]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/cats/sql_create.c
Backport from Bacula Enterprise
[bacula/bacula] / bacula / src / cats / sql_create.c
index 74d7603e90ad10fca466319562af3cd75b9be276..9a84a49c334dc7cb01b35ab6280df86f5af053cd 100644 (file)
@@ -1,17 +1,21 @@
 /*
-   Bacula® - The Network Backup Solution
+   Bacula(R) - The Network Backup Solution
 
+   Copyright (C) 2000-2015 Kern Sibbald
    Copyright (C) 2000-2014 Free Software Foundation Europe e.V.
 
-   The main author of Bacula is Kern Sibbald, with contributions from many
-   others, a complete list can be found in the file AUTHORS.
+   The original author of Bacula is Kern Sibbald, with contributions
+   from many others, a complete list can be found in the file AUTHORS.
 
    You may use this file and others of this release according to the
    license defined in the LICENSE file, which includes the Affero General
    Public License, v3.0 ("AGPLv3") and some additional permissions and
    terms pursuant to its AGPLv3 Section 7.
 
-   Bacula® is a registered trademark of Kern Sibbald.
+   This notice must be preserved when any source code is 
+   conveyed and/or propagated.
+
+   Bacula(R) is a registered trademark of Kern Sibbald.
 */
 /*
  * Bacula Catalog Database Create record interface routines
  *
  */
 
-#include "bacula.h"
+#include  "bacula.h"
 
 static const int dbglevel = 100;
 
 #if HAVE_SQLITE3 || HAVE_MYSQL || HAVE_POSTGRESQL
-
-#include "cats.h"
-#include "bdb_priv.h"
-#include "sql_glue.h"
+#include  "cats.h"
 
 /* -----------------------------------------------------------------------
  *
@@ -37,16 +39,11 @@ static const int dbglevel = 100;
  * -----------------------------------------------------------------------
  */
 
-/* Forward referenced subroutines */
-static int db_create_file_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar);
-static int db_create_filename_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar);
-
 /** Create a new record for the Job
  *  Returns: false on failure
  *          true  on success
  */
-bool
-db_create_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
+bool BDB::bdb_create_job_record(JCR *jcr, JOB_DBR *jr)
 {
    POOL_MEM buf;
    char dt[MAX_TIME_LENGTH];
@@ -59,7 +56,7 @@ db_create_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
    char esc_job[MAX_ESCAPE_NAME_LENGTH];
    char esc_name[MAX_ESCAPE_NAME_LENGTH];
 
-   db_lock(mdb);
+   bdb_lock();
 
    stime = jr->SchedTime;
    ASSERT(stime != 0);
@@ -70,13 +67,13 @@ db_create_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
 
    len = strlen(jcr->comment);  /* TODO: use jr instead of jcr to get comment */
    buf.check_size(len*2+1);
-   mdb->db_escape_string(jcr, buf.c_str(), jcr->comment, len);
+   bdb_escape_string(jcr, buf.c_str(), jcr->comment, len);
 
-   mdb->db_escape_string(jcr, esc_job, jr->Job, strlen(jr->Job));
-   mdb->db_escape_string(jcr, esc_name, jr->Name, strlen(jr->Name));
+   bdb_escape_string(jcr, esc_job, jr->Job, strlen(jr->Job));
+   bdb_escape_string(jcr, esc_name, jr->Name, strlen(jr->Name));
 
    /* Must create it */
-   Mmsg(mdb->cmd,
+   Mmsg(cmd,
 "INSERT INTO Job (Job,Name,Type,Level,JobStatus,SchedTime,JobTDate,"
                  "ClientId,Comment) "
 "VALUES ('%s','%s','%c','%c','%c','%s',%s,%s,'%s')",
@@ -84,15 +81,14 @@ db_create_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
            (char)(jr->JobStatus), dt, edit_uint64(JobTDate, ed1),
            edit_int64(jr->ClientId, ed2), buf.c_str());
 
-   jr->JobId = sql_insert_autokey_record(mdb, mdb->cmd, NT_("Job"));
-   if (jr->JobId == 0) {
-      Mmsg2(&mdb->errmsg, _("Create DB Job record %s failed. ERR=%s\n"),
-            mdb->cmd, sql_strerror(mdb));
+   if ((jr->JobId = sql_insert_autokey_record(cmd, NT_("Job"))) == 0) {
+      Mmsg2(&errmsg, _("Create DB Job record %s failed. ERR=%s\n"),
+            cmd, sql_strerror());
       ok = false;
    } else {
       ok = true;
    }
-   db_unlock(mdb);
+   bdb_unlock();
    return ok;
 }
 
@@ -101,25 +97,24 @@ db_create_job_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr)
  *  Returns: false on failure
  *          true  on success
  */
-bool
-db_create_jobmedia_record(JCR *jcr, B_DB *mdb, JOBMEDIA_DBR *jm)
+bool BDB::bdb_create_jobmedia_record(JCR *jcr, JOBMEDIA_DBR *jm)
 {
    bool ok = true;
    int count;
    char ed1[50], ed2[50];
 
-   db_lock(mdb);
+   bdb_lock();
 
    /* Now get count for VolIndex */
-   Mmsg(mdb->cmd, "SELECT count(*) from JobMedia WHERE JobId=%s",
+   Mmsg(cmd, "SELECT count(*) from JobMedia WHERE JobId=%s",
         edit_int64(jm->JobId, ed1));
-   count = get_sql_record_max(jcr, mdb);
+   count = get_sql_record_max(jcr, this);
    if (count < 0) {
       count = 0;
    }
    count++;
 
-   Mmsg(mdb->cmd,
+   Mmsg(cmd,
         "INSERT INTO JobMedia (JobId,MediaId,FirstIndex,LastIndex,"
         "StartFile,EndFile,StartBlock,EndBlock,VolIndex) "
         "VALUES (%s,%s,%u,%u,%u,%u,%u,%u,%u)",
@@ -128,23 +123,23 @@ db_create_jobmedia_record(JCR *jcr, B_DB *mdb, JOBMEDIA_DBR *jm)
         jm->FirstIndex, jm->LastIndex,
         jm->StartFile, jm->EndFile, jm->StartBlock, jm->EndBlock,count);
 
-   Dmsg0(300, mdb->cmd);
-   if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
-      Mmsg2(&mdb->errmsg, _("Create JobMedia record %s failed: ERR=%s\n"), mdb->cmd,
-         sql_strerror(mdb));
+   Dmsg0(300, cmd);
+   if (!InsertDB(jcr, cmd)) {
+      Mmsg2(&errmsg, _("Create JobMedia record %s failed: ERR=%s\n"), cmd,
+         sql_strerror());
       ok = false;
    } else {
       /* Worked, now update the Media record with the EndFile and EndBlock */
-      Mmsg(mdb->cmd,
+      Mmsg(cmd,
            "UPDATE Media SET EndFile=%u, EndBlock=%u WHERE MediaId=%u",
            jm->EndFile, jm->EndBlock, jm->MediaId);
-      if (!UPDATE_DB(jcr, mdb, mdb->cmd)) {
-         Mmsg2(&mdb->errmsg, _("Update Media record %s failed: ERR=%s\n"), mdb->cmd,
-              sql_strerror(mdb));
+      if (!UpdateDB(jcr, cmd)) {
+         Mmsg2(&errmsg, _("Update Media record %s failed: ERR=%s\n"), cmd,
+              sql_strerror());
          ok = false;
       }
    }
-   db_unlock(mdb);
+   bdb_unlock();
    Dmsg0(300, "Return from JobMedia\n");
    return ok;
 }
@@ -153,37 +148,33 @@ db_create_jobmedia_record(JCR *jcr, B_DB *mdb, JOBMEDIA_DBR *jm)
  *  Returns: false on failure
  *          true  on success
  */
-bool
-db_create_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
+bool BDB::bdb_create_pool_record(JCR *jcr, POOL_DBR *pr)
 {
    bool stat;
    char ed1[30], ed2[30], ed3[50], ed4[50], ed5[50];
    char esc_name[MAX_ESCAPE_NAME_LENGTH];
    char esc_lf[MAX_ESCAPE_NAME_LENGTH];
 
-   int num_rows;
-
-
    Dmsg0(200, "In create pool\n");
-   db_lock(mdb);
-   mdb->db_escape_string(jcr, esc_name, pr->Name, strlen(pr->Name));
-   mdb->db_escape_string(jcr, esc_lf, pr->LabelFormat, strlen(pr->LabelFormat));
-   Mmsg(mdb->cmd, "SELECT PoolId,Name FROM Pool WHERE Name='%s'", esc_name);
-   Dmsg1(200, "selectpool: %s\n", mdb->cmd);
-
-   if (QUERY_DB(jcr, mdb, mdb->cmd)) {
-      num_rows = sql_num_rows(mdb);
-      if (num_rows > 0) {
-         Mmsg1(&mdb->errmsg, _("pool record %s already exists\n"), pr->Name);
-         sql_free_result(mdb);
-         db_unlock(mdb);
+   bdb_lock();
+   bdb_escape_string(jcr, esc_name, pr->Name, strlen(pr->Name));
+   bdb_escape_string(jcr, esc_lf, pr->LabelFormat, strlen(pr->LabelFormat));
+   Mmsg(cmd, "SELECT PoolId,Name FROM Pool WHERE Name='%s'", esc_name);
+   Dmsg1(200, "selectpool: %s\n", cmd);
+
+   if (QueryDB(jcr, cmd)) {
+      if (sql_num_rows() > 0) { 
+         Mmsg1(&errmsg, _("pool record %s already exists\n"), pr->Name);
+         sql_free_result();
+         bdb_unlock();
+         Dmsg1(200, "%s", errmsg); /* pool already exists */
          return false;
       }
-      sql_free_result(mdb);
+      sql_free_result();
    }
 
    /* Must create it */
-   Mmsg(mdb->cmd,
+   Mmsg(cmd,
 "INSERT INTO Pool (Name,NumVols,MaxVols,UseOnce,UseCatalog,"
 "AcceptAnyVolume,AutoPrune,Recycle,VolRetention,VolUseDuration,"
 "MaxVolJobs,MaxVolFiles,MaxVolBytes,PoolType,LabelType,LabelFormat,"
@@ -203,17 +194,15 @@ db_create_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
                   edit_int64(pr->ScratchPoolId,ed5),
                   pr->ActionOnPurge
       );
-   Dmsg1(200, "Create Pool: %s\n", mdb->cmd);
-   pr->PoolId = sql_insert_autokey_record(mdb, mdb->cmd, NT_("Pool"));
-   if (pr->PoolId == 0) {
-      Mmsg2(&mdb->errmsg, _("Create db Pool record %s failed: ERR=%s\n"),
-            mdb->cmd, sql_strerror(mdb));
+   Dmsg1(200, "Create Pool: %s\n", cmd);
+   if ((pr->PoolId = sql_insert_autokey_record(cmd, NT_("Pool"))) == 0) {
+      Mmsg2(&errmsg, _("Create db Pool record %s failed: ERR=%s\n"),
+            cmd, sql_strerror());
       stat = false;
    } else {
       stat = true;
    }
-   db_unlock(mdb);
-   Dmsg0(500, "Create Pool: done\n");
+   bdb_unlock();
    return stat;
 }
 
@@ -222,47 +211,43 @@ db_create_pool_record(JCR *jcr, B_DB *mdb, POOL_DBR *pr)
  * Returns: false on failure
  *          true  on success
  */
-bool
-db_create_device_record(JCR *jcr, B_DB *mdb, DEVICE_DBR *dr)
+bool BDB::bdb_create_device_record(JCR *jcr, DEVICE_DBR *dr)
 {
    bool ok;
    char ed1[30], ed2[30];
    char esc[MAX_ESCAPE_NAME_LENGTH];
-   int num_rows;
 
    Dmsg0(200, "In create Device\n");
-   db_lock(mdb);
-   mdb->db_escape_string(jcr, esc, dr->Name, strlen(dr->Name));
-   Mmsg(mdb->cmd, "SELECT DeviceId,Name FROM Device WHERE Name='%s'", esc);
-   Dmsg1(200, "selectdevice: %s\n", mdb->cmd);
-
-   if (QUERY_DB(jcr, mdb, mdb->cmd)) {
-      num_rows = sql_num_rows(mdb);
-      if (num_rows > 0) {
-         Mmsg1(&mdb->errmsg, _("Device record %s already exists\n"), dr->Name);
-         sql_free_result(mdb);
-         db_unlock(mdb);
+   bdb_lock();
+   bdb_escape_string(jcr, esc, dr->Name, strlen(dr->Name));
+   Mmsg(cmd, "SELECT DeviceId,Name FROM Device WHERE Name='%s'", esc);
+   Dmsg1(200, "selectdevice: %s\n", cmd);
+
+   if (QueryDB(jcr, cmd)) {
+      if (sql_num_rows() > 0) { 
+         Mmsg1(&errmsg, _("Device record %s already exists\n"), dr->Name);
+         sql_free_result();
+         bdb_unlock();
          return false;
       }
-      sql_free_result(mdb);
+      sql_free_result();
    }
 
    /* Must create it */
-   Mmsg(mdb->cmd,
+   Mmsg(cmd,
 "INSERT INTO Device (Name,MediaTypeId,StorageId) VALUES ('%s',%s,%s)",
                   esc,
                   edit_uint64(dr->MediaTypeId, ed1),
                   edit_int64(dr->StorageId, ed2));
-   Dmsg1(200, "Create Device: %s\n", mdb->cmd);
-   dr->DeviceId = sql_insert_autokey_record(mdb, mdb->cmd, NT_("Device"));
-   if (dr->DeviceId == 0) {
-      Mmsg2(&mdb->errmsg, _("Create db Device record %s failed: ERR=%s\n"),
-            mdb->cmd, sql_strerror(mdb));
+   Dmsg1(200, "Create Device: %s\n", cmd);
+   if ((dr->DeviceId = sql_insert_autokey_record(cmd, NT_("Device"))) == 0) {
+      Mmsg2(&errmsg, _("Create db Device record %s failed: ERR=%s\n"),
+            cmd, sql_strerror());
       ok = false;
    } else {
       ok = true;
    }
-   db_unlock(mdb);
+   bdb_unlock();
    return ok;
 }
 
@@ -273,59 +258,56 @@ db_create_device_record(JCR *jcr, B_DB *mdb, DEVICE_DBR *dr)
  * Returns: false on failure
  *          true  on success with id in sr->StorageId
  */
-bool db_create_storage_record(JCR *jcr, B_DB *mdb, STORAGE_DBR *sr)
+bool BDB::bdb_create_storage_record(JCR *jcr, STORAGE_DBR *sr)
 {
    SQL_ROW row;
    bool ok;
-   int num_rows;
    char esc[MAX_ESCAPE_NAME_LENGTH];
 
-   db_lock(mdb);
-   mdb->db_escape_string(jcr, esc, sr->Name, strlen(sr->Name));
-   Mmsg(mdb->cmd, "SELECT StorageId,AutoChanger FROM Storage WHERE Name='%s'",esc);
+   bdb_lock();
+   bdb_escape_string(jcr, esc, sr->Name, strlen(sr->Name));
+   Mmsg(cmd, "SELECT StorageId,AutoChanger FROM Storage WHERE Name='%s'",esc);
 
    sr->StorageId = 0;
    sr->created = false;
    /* Check if it already exists */
-   if (QUERY_DB(jcr, mdb, mdb->cmd)) {
-      num_rows = sql_num_rows(mdb);
+   if (QueryDB(jcr, cmd)) {
       /* If more than one, report error, but return first row */
-      if (num_rows > 1) {
-         Mmsg1(&mdb->errmsg, _("More than one Storage record!: %d\n"), num_rows);
-         Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+      if (sql_num_rows() > 1) { 
+         Mmsg1(&errmsg, _("More than one Storage record!: %d\n"), sql_num_rows());
+         Jmsg(jcr, M_ERROR, 0, "%s", errmsg);
       }
-      if (num_rows >= 1) {
-         if ((row = sql_fetch_row(mdb)) == NULL) {
-            Mmsg1(&mdb->errmsg, _("error fetching Storage row: %s\n"), sql_strerror(mdb));
-            Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
-            sql_free_result(mdb);
-            db_unlock(mdb);
+      if (sql_num_rows() >= 1) { 
+         if ((row = sql_fetch_row()) == NULL) {
+            Mmsg1(&errmsg, _("error fetching Storage row: %s\n"), sql_strerror());
+            Jmsg(jcr, M_ERROR, 0, "%s", errmsg);
+            sql_free_result();
+            bdb_unlock();
             return false;
          }
          sr->StorageId = str_to_int64(row[0]);
          sr->AutoChanger = atoi(row[1]);   /* bool */
-         sql_free_result(mdb);
-         db_unlock(mdb);
+         sql_free_result();
+         bdb_unlock();
          return true;
       }
-      sql_free_result(mdb);
+      sql_free_result();
    }
 
    /* Must create it */
-   Mmsg(mdb->cmd, "INSERT INTO Storage (Name,AutoChanger)"
+   Mmsg(cmd, "INSERT INTO Storage (Name,AutoChanger)"
         " VALUES ('%s',%d)", esc, sr->AutoChanger);
 
-   sr->StorageId = sql_insert_autokey_record(mdb, mdb->cmd, NT_("Storage"));
-   if (sr->StorageId == 0) {
-      Mmsg2(&mdb->errmsg, _("Create DB Storage record %s failed. ERR=%s\n"),
-            mdb->cmd, sql_strerror(mdb));
-      Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+   if ((sr->StorageId = sql_insert_autokey_record(cmd, NT_("Storage"))) == 0) {
+      Mmsg2(&errmsg, _("Create DB Storage record %s failed. ERR=%s\n"),
+            cmd, sql_strerror());
+      Jmsg(jcr, M_ERROR, 0, "%s", errmsg);
       ok = false;
    } else {
       sr->created = true;
       ok = true;
    }
-   db_unlock(mdb);
+   bdb_unlock();
    return ok;
 }
 
@@ -335,46 +317,42 @@ bool db_create_storage_record(JCR *jcr, B_DB *mdb, STORAGE_DBR *sr)
  * Returns: false on failure
  *          true  on success
  */
-bool
-db_create_mediatype_record(JCR *jcr, B_DB *mdb, MEDIATYPE_DBR *mr)
+bool BDB::bdb_create_mediatype_record(JCR *jcr, MEDIATYPE_DBR *mr)
 {
    bool stat;
-   int num_rows;
    char esc[MAX_ESCAPE_NAME_LENGTH];
 
    Dmsg0(200, "In create mediatype\n");
-   db_lock(mdb);
-   mdb->db_escape_string(jcr, esc, mr->MediaType, strlen(mr->MediaType));
-   Mmsg(mdb->cmd, "SELECT MediaTypeId,MediaType FROM MediaType WHERE MediaType='%s'", esc);
-   Dmsg1(200, "selectmediatype: %s\n", mdb->cmd);
-
-   if (QUERY_DB(jcr, mdb, mdb->cmd)) {
-      num_rows = sql_num_rows(mdb);
-      if (num_rows > 0) {
-         Mmsg1(&mdb->errmsg, _("mediatype record %s already exists\n"), mr->MediaType);
-         sql_free_result(mdb);
-         db_unlock(mdb);
+   bdb_lock();
+   bdb_escape_string(jcr, esc, mr->MediaType, strlen(mr->MediaType));
+   Mmsg(cmd, "SELECT MediaTypeId,MediaType FROM MediaType WHERE MediaType='%s'", esc);
+   Dmsg1(200, "selectmediatype: %s\n", cmd);
+
+   if (QueryDB(jcr, cmd)) {
+      if (sql_num_rows() > 0) { 
+         Mmsg1(&errmsg, _("mediatype record %s already exists\n"), mr->MediaType);
+         sql_free_result();
+         bdb_unlock();
          return false;
       }
-      sql_free_result(mdb);
+      sql_free_result();
    }
 
    /* Must create it */
-   Mmsg(mdb->cmd,
+   Mmsg(cmd,
 "INSERT INTO MediaType (MediaType,ReadOnly) "
 "VALUES ('%s',%d)",
                   mr->MediaType,
                   mr->ReadOnly);
-   Dmsg1(200, "Create mediatype: %s\n", mdb->cmd);
-   mr->MediaTypeId = sql_insert_autokey_record(mdb, mdb->cmd, NT_("MediaType"));
-   if (mr->MediaTypeId == 0) {
-      Mmsg2(&mdb->errmsg, _("Create db mediatype record %s failed: ERR=%s\n"),
-            mdb->cmd, sql_strerror(mdb));
+   Dmsg1(200, "Create mediatype: %s\n", cmd);
+   if ((mr->MediaTypeId = sql_insert_autokey_record(cmd, NT_("MediaType"))) == 0) {
+      Mmsg2(&errmsg, _("Create db mediatype record %s failed: ERR=%s\n"),
+            cmd, sql_strerror());
       stat = false;
    } else {
       stat = true;
    }
-   db_unlock(mdb);
+   bdb_unlock();
    return stat;
 }
 
@@ -385,40 +363,37 @@ db_create_mediatype_record(JCR *jcr, B_DB *mdb, MEDIATYPE_DBR *mr)
  * Returns: 0 on failure
  *          1 on success
  */
-int
-db_create_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
+int BDB::bdb_create_media_record(JCR *jcr, MEDIA_DBR *mr)
 {
    int stat;
    char ed1[50], ed2[50], ed3[50], ed4[50], ed5[50], ed6[50], ed7[50], ed8[50];
    char ed9[50], ed10[50], ed11[50], ed12[50];
    struct tm tm;
-   int num_rows;
    char esc_name[MAX_ESCAPE_NAME_LENGTH];
    char esc_mtype[MAX_ESCAPE_NAME_LENGTH];
    char esc_status[MAX_ESCAPE_NAME_LENGTH];
 
 
-   db_lock(mdb);
-   mdb->db_escape_string(jcr, esc_name, mr->VolumeName, strlen(mr->VolumeName));
-   mdb->db_escape_string(jcr, esc_mtype, mr->MediaType, strlen(mr->MediaType));
-   mdb->db_escape_string(jcr, esc_status, mr->VolStatus, strlen(mr->VolStatus));
+   bdb_lock();
+   bdb_escape_string(jcr, esc_name, mr->VolumeName, strlen(mr->VolumeName));
+   bdb_escape_string(jcr, esc_mtype, mr->MediaType, strlen(mr->MediaType));
+   bdb_escape_string(jcr, esc_status, mr->VolStatus, strlen(mr->VolStatus));
 
-   Mmsg(mdb->cmd, "SELECT MediaId FROM Media WHERE VolumeName='%s'", esc_name);
-   Dmsg1(500, "selectpool: %s\n", mdb->cmd);
+   Mmsg(cmd, "SELECT MediaId FROM Media WHERE VolumeName='%s'", esc_name);
+   Dmsg1(500, "selectpool: %s\n", cmd);
 
-   if (QUERY_DB(jcr, mdb, mdb->cmd)) {
-      num_rows = sql_num_rows(mdb);
-      if (num_rows > 0) {
-         Mmsg1(&mdb->errmsg, _("Volume \"%s\" already exists.\n"), mr->VolumeName);
-         sql_free_result(mdb);
-         db_unlock(mdb);
+   if (QueryDB(jcr, cmd)) {
+      if (sql_num_rows() > 0) { 
+         Mmsg1(&errmsg, _("Volume \"%s\" already exists.\n"), mr->VolumeName);
+         sql_free_result();
+         bdb_unlock();
          return 0;
       }
-      sql_free_result(mdb);
+      sql_free_result();
    }
 
    /* Must create it */
-   Mmsg(mdb->cmd,
+   Mmsg(cmd,
 "INSERT INTO Media (VolumeName,MediaType,MediaTypeId,PoolId,MaxVolBytes,"
 "VolCapacityBytes,Recycle,VolRetention,VolUseDuration,MaxVolJobs,MaxVolFiles,"
 "VolStatus,Slot,VolBytes,InChanger,VolReadTime,VolWriteTime,VolParts,"
@@ -441,7 +416,7 @@ db_create_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
           mr->InChanger,
           edit_int64(mr->VolReadTime, ed6),
           edit_int64(mr->VolWriteTime, ed7),
-          mr->VolParts,
+          mr->VolType,   /* formerly VolParts */
           mr->LabelType,
           edit_int64(mr->StorageId, ed8),
           edit_int64(mr->DeviceId, ed9),
@@ -452,11 +427,10 @@ db_create_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
           );
 
 
-   Dmsg1(500, "Create Volume: %s\n", mdb->cmd);
-   mr->MediaId = sql_insert_autokey_record(mdb, mdb->cmd, NT_("Media"));
-   if (mr->MediaId == 0) {
-      Mmsg2(&mdb->errmsg, _("Create DB Media record %s failed. ERR=%s\n"),
-            mdb->cmd, sql_strerror(mdb));
+   Dmsg1(500, "Create Volume: %s\n", cmd);
+   if ((mr->MediaId = sql_insert_autokey_record(cmd, NT_("Media"))) == 0) {
+      Mmsg2(&errmsg, _("Create DB Media record %s failed. ERR=%s\n"),
+            cmd, sql_strerror());
       stat = 0;
    } else {
       stat = 1;
@@ -467,18 +441,18 @@ db_create_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
          }
          (void)localtime_r(&mr->LabelDate, &tm);
          strftime(dt, sizeof(dt), "%Y-%m-%d %H:%M:%S", &tm);
-         Mmsg(mdb->cmd, "UPDATE Media SET LabelDate='%s' "
+         Mmsg(cmd, "UPDATE Media SET LabelDate='%s' "
               "WHERE MediaId=%d", dt, mr->MediaId);
-         stat = UPDATE_DB(jcr, mdb, mdb->cmd);
+         stat = UpdateDB(jcr, cmd);
       }
       /*
        * Make sure that if InChanger is non-zero any other identical slot
        *   has InChanger zero.
        */
-      db_make_inchanger_unique(jcr, mdb, mr);
+      db_make_inchanger_unique(jcr, this, mr);
    }
 
-   db_unlock(mdb);
+   bdb_unlock();
    return stat;
 }
 
@@ -487,34 +461,32 @@ db_create_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
  * Returns: 0 on failure
  *          1 on success with id in cr->ClientId
  */
-int db_create_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr)
+int BDB::bdb_create_client_record(JCR *jcr, CLIENT_DBR *cr)
 {
    SQL_ROW row;
    int stat;
    char ed1[50], ed2[50];
-   int num_rows;
    char esc_name[MAX_ESCAPE_NAME_LENGTH];
    char esc_uname[MAX_ESCAPE_NAME_LENGTH];
 
-   db_lock(mdb);
-   mdb->db_escape_string(jcr, esc_name, cr->Name, strlen(cr->Name));
-   mdb->db_escape_string(jcr, esc_uname, cr->Uname, strlen(cr->Uname));
-   Mmsg(mdb->cmd, "SELECT ClientId,Uname FROM Client WHERE Name='%s'",esc_name);
+   bdb_lock();
+   bdb_escape_string(jcr, esc_name, cr->Name, strlen(cr->Name));
+   bdb_escape_string(jcr, esc_uname, cr->Uname, strlen(cr->Uname));
+   Mmsg(cmd, "SELECT ClientId,Uname FROM Client WHERE Name='%s'",esc_name);
 
    cr->ClientId = 0;
-   if (QUERY_DB(jcr, mdb, mdb->cmd)) {
-      num_rows = sql_num_rows(mdb);
+   if (QueryDB(jcr, cmd)) {
       /* If more than one, report error, but return first row */
-      if (num_rows > 1) {
-         Mmsg1(&mdb->errmsg, _("More than one Client!: %d\n"), num_rows);
-         Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+      if (sql_num_rows() > 1) { 
+         Mmsg1(&errmsg, _("More than one Client!: %d\n"), sql_num_rows());
+         Jmsg(jcr, M_ERROR, 0, "%s", errmsg);
       }
-      if (num_rows >= 1) {
-         if ((row = sql_fetch_row(mdb)) == NULL) {
-            Mmsg1(&mdb->errmsg, _("error fetching Client row: %s\n"), sql_strerror(mdb));
-            Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
-            sql_free_result(mdb);
-            db_unlock(mdb);
+      if (sql_num_rows() >= 1) { 
+         if ((row = sql_fetch_row()) == NULL) {
+            Mmsg1(&errmsg, _("error fetching Client row: %s\n"), sql_strerror());
+            Jmsg(jcr, M_ERROR, 0, "%s", errmsg);
+            sql_free_result();
+            bdb_unlock();
             return 0;
          }
          cr->ClientId = str_to_int64(row[0]);
@@ -523,67 +495,64 @@ int db_create_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr)
          } else {
             cr->Uname[0] = 0;         /* no name */
          }
-         sql_free_result(mdb);
-         db_unlock(mdb);
+         sql_free_result();
+         bdb_unlock();
          return 1;
       }
-      sql_free_result(mdb);
+      sql_free_result();
    }
 
    /* Must create it */
-   Mmsg(mdb->cmd, "INSERT INTO Client (Name,Uname,AutoPrune,"
+   Mmsg(cmd, "INSERT INTO Client (Name,Uname,AutoPrune,"
 "FileRetention,JobRetention) VALUES "
 "('%s','%s',%d,%s,%s)", esc_name, esc_uname, cr->AutoPrune,
       edit_uint64(cr->FileRetention, ed1),
       edit_uint64(cr->JobRetention, ed2));
 
-   cr->ClientId = sql_insert_autokey_record(mdb, mdb->cmd, NT_("Client"));
-   if (cr->ClientId == 0) {
-      Mmsg2(&mdb->errmsg, _("Create DB Client record %s failed. ERR=%s\n"),
-            mdb->cmd, sql_strerror(mdb));
-      Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+   if ((cr->ClientId = sql_insert_autokey_record(cmd, NT_("Client"))) == 0) {
+      Mmsg2(&errmsg, _("Create DB Client record %s failed. ERR=%s\n"),
+            cmd, sql_strerror());
+      Jmsg(jcr, M_ERROR, 0, "%s", errmsg);
       stat = 0;
    } else {
       stat = 1;
    }
-   db_unlock(mdb);
+   bdb_unlock();
    return stat;
 }
 
 
 /** Create a Unique record for the Path -- no duplicates */
-int db_create_path_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
+int BDB::bdb_create_path_record(JCR *jcr, ATTR_DBR *ar)
 {
    SQL_ROW row;
    int stat;
-   int num_rows;
 
-   mdb->errmsg[0] = 0;
-   mdb->esc_name = check_pool_memory_size(mdb->esc_name, 2*mdb->pnl+2);
-   db_escape_string(jcr, mdb, mdb->esc_name, mdb->path, mdb->pnl);
+   errmsg[0] = 0;
+   esc_name = check_pool_memory_size(esc_name, 2*pnl+2);
+   bdb_escape_string(jcr, esc_name, path, pnl);
 
-   if (mdb->cached_path_id != 0 && mdb->cached_path_len == mdb->pnl &&
-       strcmp(mdb->cached_path, mdb->path) == 0) {
-      ar->PathId = mdb->cached_path_id;
+   if (cached_path_id != 0 && cached_path_len == pnl &&
+       strcmp(cached_path, path) == 0) {
+      ar->PathId = cached_path_id;
       return 1;
    }
 
-   Mmsg(mdb->cmd, "SELECT PathId FROM Path WHERE Path='%s'", mdb->esc_name);
+   Mmsg(cmd, "SELECT PathId FROM Path WHERE Path='%s'", esc_name);
 
-   if (QUERY_DB(jcr, mdb, mdb->cmd)) {
-      num_rows = sql_num_rows(mdb);
-      if (num_rows > 1) {
+   if (QueryDB(jcr, cmd)) {
+      if (sql_num_rows() > 1) { 
          char ed1[30];
-         Mmsg2(&mdb->errmsg, _("More than one Path!: %s for path: %s\n"),
-            edit_uint64(num_rows, ed1), mdb->path);
-         Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg);
+         Mmsg2(&errmsg, _("More than one Path!: %s for path: %s\n"),
+            edit_uint64(sql_num_rows(), ed1), path);
+         Jmsg(jcr, M_WARNING, 0, "%s", errmsg);
       }
       /* Even if there are multiple paths, take the first one */
-      if (num_rows >= 1) {
-         if ((row = sql_fetch_row(mdb)) == NULL) {
-            Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
-            Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
-            sql_free_result(mdb);
+      if (sql_num_rows() >= 1) { 
+         if ((row = sql_fetch_row()) == NULL) {
+            Mmsg1(&errmsg, _("error fetching row: %s\n"), sql_strerror());
+            Jmsg(jcr, M_ERROR, 0, "%s", errmsg);
+            sql_free_result();
             ar->PathId = 0;
             ASSERT2(ar->PathId,
                     "Your Path table is broken. "
@@ -591,26 +560,25 @@ int db_create_path_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
             return 0;
          }
          ar->PathId = str_to_int64(row[0]);
-         sql_free_result(mdb);
+         sql_free_result();
          /* Cache path */
-         if (ar->PathId != mdb->cached_path_id) {
-            mdb->cached_path_id = ar->PathId;
-            mdb->cached_path_len = mdb->pnl;
-            pm_strcpy(mdb->cached_path, mdb->path);
+         if (ar->PathId != cached_path_id) {
+            cached_path_id = ar->PathId;
+            cached_path_len = pnl;
+            pm_strcpy(cached_path, path);
          }
          ASSERT(ar->PathId);
          return 1;
       }
-      sql_free_result(mdb);
+      sql_free_result();
    }
 
-   Mmsg(mdb->cmd, "INSERT INTO Path (Path) VALUES ('%s')", mdb->esc_name);
+   Mmsg(cmd, "INSERT INTO Path (Path) VALUES ('%s')", esc_name);
 
-   ar->PathId = sql_insert_autokey_record(mdb, mdb->cmd, NT_("Path"));
-   if (ar->PathId == 0) {
-      Mmsg2(&mdb->errmsg, _("Create db Path record %s failed. ERR=%s\n"),
-         mdb->cmd, sql_strerror(mdb));
-      Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg);
+   if ((ar->PathId = sql_insert_autokey_record(cmd, NT_("Path"))) == 0) {
+      Mmsg2(&errmsg, _("Create db Path record %s failed. ERR=%s\n"),
+         cmd, sql_strerror());
+      Jmsg(jcr, M_FATAL, 0, "%s", errmsg);
       ar->PathId = 0;
       stat = 0;
    } else {
@@ -618,10 +586,10 @@ int db_create_path_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
    }
 
    /* Cache path */
-   if (stat && ar->PathId != mdb->cached_path_id) {
-      mdb->cached_path_id = ar->PathId;
-      mdb->cached_path_len = mdb->pnl;
-      pm_strcpy(mdb->cached_path, mdb->path);
+   if (stat && ar->PathId != cached_path_id) {
+      cached_path_id = ar->PathId;
+      cached_path_len = pnl;
+      pm_strcpy(cached_path, path);
    }
    return stat;
 }
@@ -631,36 +599,36 @@ int db_create_path_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
  * Returns: 0 on failure
  *          1 on success with counter filled in
  */
-int db_create_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr)
+int BDB::bdb_create_counter_record(JCR *jcr, COUNTER_DBR *cr)
 {
    char esc[MAX_ESCAPE_NAME_LENGTH];
    COUNTER_DBR mcr;
    int stat;
 
-   db_lock(mdb);
+   bdb_lock();
    memset(&mcr, 0, sizeof(mcr));
    bstrncpy(mcr.Counter, cr->Counter, sizeof(mcr.Counter));
-   if (db_get_counter_record(jcr, mdb, &mcr)) {
+   if (bdb_get_counter_record(jcr, &mcr)) {
       memcpy(cr, &mcr, sizeof(COUNTER_DBR));
-      db_unlock(mdb);
+      bdb_unlock();
       return 1;
    }
-   mdb->db_escape_string(jcr, esc, cr->Counter, strlen(cr->Counter));
+   bdb_escape_string(jcr, esc, cr->Counter, strlen(cr->Counter));
 
    /* Must create it */
-   Mmsg(mdb->cmd, insert_counter_values[db_get_type_index(mdb)],
+   Mmsg(cmd, insert_counter_values[bdb_get_type_index()],
         esc, cr->MinValue, cr->MaxValue, cr->CurrentValue,
         cr->WrapCounter);
 
-   if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
-      Mmsg2(&mdb->errmsg, _("Create DB Counters record %s failed. ERR=%s\n"),
-            mdb->cmd, sql_strerror(mdb));
-      Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+   if (!InsertDB(jcr, cmd)) {
+      Mmsg2(&errmsg, _("Create DB Counters record %s failed. ERR=%s\n"),
+            cmd, sql_strerror());
+      Jmsg(jcr, M_ERROR, 0, "%s", errmsg);
       stat = 0;
    } else {
       stat = 1;
    }
-   db_unlock(mdb);
+   bdb_unlock();
    return stat;
 }
 
@@ -670,36 +638,34 @@ int db_create_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr)
  *  Returns: 0 on failure
  *           1 on success with FileSetId in record
  */
-bool db_create_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
+bool BDB::bdb_create_fileset_record(JCR *jcr, FILESET_DBR *fsr)
 {
    SQL_ROW row;
    bool stat;
    struct tm tm;
-   int num_rows;
    char esc_fs[MAX_ESCAPE_NAME_LENGTH];
    char esc_md5[MAX_ESCAPE_NAME_LENGTH];
 
    /* TODO: Escape FileSet and MD5 */
-   db_lock(mdb);
+   bdb_lock();
    fsr->created = false;
-   mdb->db_escape_string(jcr, esc_fs, fsr->FileSet, strlen(fsr->FileSet));
-   mdb->db_escape_string(jcr, esc_md5, fsr->MD5, strlen(fsr->MD5));
-   Mmsg(mdb->cmd, "SELECT FileSetId,CreateTime FROM FileSet WHERE "
+   bdb_escape_string(jcr, esc_fs, fsr->FileSet, strlen(fsr->FileSet));
+   bdb_escape_string(jcr, esc_md5, fsr->MD5, strlen(fsr->MD5));
+   Mmsg(cmd, "SELECT FileSetId,CreateTime FROM FileSet WHERE "
                   "FileSet='%s' AND MD5='%s'", esc_fs, esc_md5);
 
    fsr->FileSetId = 0;
-   if (QUERY_DB(jcr, mdb, mdb->cmd)) {
-      num_rows = sql_num_rows(mdb);
-      if (num_rows > 1) {
-         Mmsg1(&mdb->errmsg, _("More than one FileSet!: %d\n"), num_rows);
-         Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+   if (QueryDB(jcr, cmd)) {
+      if (sql_num_rows() > 1) { 
+         Mmsg1(&errmsg, _("More than one FileSet!: %d\n"), sql_num_rows());
+         Jmsg(jcr, M_ERROR, 0, "%s", errmsg);
       }
-      if (num_rows >= 1) {
-         if ((row = sql_fetch_row(mdb)) == NULL) {
-            Mmsg1(&mdb->errmsg, _("error fetching FileSet row: ERR=%s\n"), sql_strerror(mdb));
-            Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
-            sql_free_result(mdb);
-            db_unlock(mdb);
+      if (sql_num_rows() >= 1) { 
+         if ((row = sql_fetch_row()) == NULL) {
+            Mmsg1(&errmsg, _("error fetching FileSet row: ERR=%s\n"), sql_strerror());
+            Jmsg(jcr, M_ERROR, 0, "%s", errmsg);
+            sql_free_result();
+            bdb_unlock();
             return false;
          }
          fsr->FileSetId = str_to_int64(row[0]);
@@ -708,11 +674,11 @@ bool db_create_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
          } else {
             bstrncpy(fsr->cCreateTime, row[1], sizeof(fsr->cCreateTime));
          }
-         sql_free_result(mdb);
-         db_unlock(mdb);
+         sql_free_result();
+         bdb_unlock();
          return true;
       }
-      sql_free_result(mdb);
+      sql_free_result();
    }
 
    if (fsr->CreateTime == 0 && fsr->cCreateTime[0] == 0) {
@@ -722,21 +688,20 @@ bool db_create_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
    strftime(fsr->cCreateTime, sizeof(fsr->cCreateTime), "%Y-%m-%d %H:%M:%S", &tm);
 
    /* Must create it */
-      Mmsg(mdb->cmd, "INSERT INTO FileSet (FileSet,MD5,CreateTime) "
+      Mmsg(cmd, "INSERT INTO FileSet (FileSet,MD5,CreateTime) "
 "VALUES ('%s','%s','%s')", esc_fs, esc_md5, fsr->cCreateTime);
 
-   fsr->FileSetId = sql_insert_autokey_record(mdb, mdb->cmd, NT_("FileSet"));
-   if (fsr->FileSetId == 0) {
-      Mmsg2(&mdb->errmsg, _("Create DB FileSet record %s failed. ERR=%s\n"),
-            mdb->cmd, sql_strerror(mdb));
-      Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+   if ((fsr->FileSetId = sql_insert_autokey_record(cmd, NT_("FileSet"))) == 0) {
+      Mmsg2(&errmsg, _("Create DB FileSet record %s failed. ERR=%s\n"),
+            cmd, sql_strerror());
+      Jmsg(jcr, M_ERROR, 0, "%s", errmsg);
       stat = false;
    } else {
       fsr->created = true;
       stat = true;
    }
 
-   db_unlock(mdb);
+   bdb_unlock();
    return stat;
 }
 
@@ -763,39 +728,39 @@ bool db_create_fileset_record(JCR *jcr, B_DB *mdb, FILESET_DBR *fsr)
 /* For maintenance, we can put batch mode in hold */
 static bool batch_mode_enabled = true;
 
-void db_disable_batch_insert(bool enabled)
+void bdb_disable_batch_insert(bool enabled)
 {
    batch_mode_enabled = enabled;
 }
 
-/**
- * All sql_batch_* functions are used to do bulk batch insert in File/Filename/Path
- *  tables.
+/*
+ * All sql_batch_xx functions are used to do bulk batch 
+ *  insert in File/Filename/Path tables.
  *
  *  To sum up :
  *   - bulk load a temp table
- *   - insert missing filenames into filename with a single query (lock filenames
+ *   - insert missing filenames into filename with a single query (lock filenames 
  *   - table before that to avoid possible duplicate inserts with concurrent update)
  *   - insert missing paths into path with another single query
  *   - then insert the join between the temp, filename and path tables into file.
  */
 
 /*
- * Returns true if OK
- *         false if failed
+ *  Returns true if OK
+ *          false if failed
  */
-bool db_write_batch_file_records(JCR *jcr)
+bool bdb_write_batch_file_records(JCR *jcr)
 {
-   bool retval = false;
+   bool retval = false; 
    int JobStatus = jcr->JobStatus;
 
    if (!jcr->batch_started) {         /* no files to backup ? */
-      Dmsg0(50,"db_create_file_record : no files\n");
+      Dmsg0(50,"db_write_batch_file_records: no files\n");
       return true;
    }
 
    if (job_canceled(jcr)) {
-      goto bail_out;
+      goto bail_out; 
    }
 
    jcr->JobStatus = JS_AttrInserting;
@@ -806,37 +771,35 @@ bool db_write_batch_file_records(JCR *jcr)
       bmicrosleep(10, 0);
 
       if (job_canceled(jcr)) {
-         goto bail_out;
+         goto bail_out; 
       }
    }
 
-   Dmsg1(50,"db_create_file_record changes=%u\n",jcr->db_batch->changes);
+   Dmsg1(50,"db_write_batch_file_records changes=%u\n",jcr->db_batch->changes);
 
-   if (!sql_batch_end(jcr, jcr->db_batch, NULL)) {
+   if (!jcr->db_batch->sql_batch_end(jcr, NULL)) {
       Jmsg1(jcr, M_FATAL, 0, "Batch end %s\n", jcr->db_batch->errmsg);
-      goto bail_out;
+      goto bail_out; 
    }
    if (job_canceled(jcr)) {
-      goto bail_out;
+      goto bail_out; 
    }
 
-   /*
-    * We have to lock tables
-    */
-   if (!db_sql_query(jcr->db_batch, batch_lock_path_query[db_get_type_index(jcr->db_batch)], NULL, NULL)) {
+   /* We have to lock tables */
+   if (!jcr->db_batch->bdb_sql_query(batch_lock_path_query[jcr->db_batch->bdb_get_type_index()], NULL, NULL)) {
       Jmsg1(jcr, M_FATAL, 0, "Lock Path table %s\n", jcr->db_batch->errmsg);
-      goto bail_out;
+      goto bail_out; 
    }
 
-   if (!db_sql_query(jcr->db_batch, batch_fill_path_query[db_get_type_index(jcr->db_batch)], NULL, NULL)) {
+   if (!jcr->db_batch->bdb_sql_query(batch_fill_path_query[jcr->db_batch->bdb_get_type_index()], NULL, NULL)) {
       Jmsg1(jcr, M_FATAL, 0, "Fill Path table %s\n",jcr->db_batch->errmsg);
-      db_sql_query(jcr->db_batch, batch_unlock_tables_query[db_get_type_index(jcr->db_batch)], NULL, NULL);
-      goto bail_out;
+      jcr->db_batch->bdb_sql_query(batch_unlock_tables_query[jcr->db_batch->bdb_get_type_index()], NULL, NULL);
+      goto bail_out; 
    }
 
-   if (!db_sql_query(jcr->db_batch, batch_unlock_tables_query[db_get_type_index(jcr->db_batch)], NULL, NULL)) {
+   if (!jcr->db_batch->bdb_sql_query(batch_unlock_tables_query[jcr->db_batch->bdb_get_type_index()], NULL, NULL)) {
       Jmsg1(jcr, M_FATAL, 0, "Unlock Path table %s\n", jcr->db_batch->errmsg);
-      goto bail_out;
+      goto bail_out; 
    }
 
    /*
@@ -846,7 +809,7 @@ bool db_write_batch_file_records(JCR *jcr)
       Jmsg1(jcr, M_FATAL, 0, "Lock Filename table %s\n", jcr->db_batch->errmsg);
       goto bail_out;
    }
-
+   
    if (!db_sql_query(jcr->db_batch, batch_fill_filename_query[db_get_type_index(jcr->db_batch)], NULL, NULL)) {
       Jmsg1(jcr,M_FATAL,0,"Fill Filename table %s\n",jcr->db_batch->errmsg);
       db_sql_query(jcr->db_batch, batch_unlock_tables_query[db_get_type_index(jcr->db_batch)], NULL, NULL);
@@ -857,8 +820,8 @@ bool db_write_batch_file_records(JCR *jcr)
       Jmsg1(jcr, M_FATAL, 0, "Unlock Filename table %s\n", jcr->db_batch->errmsg);
       goto bail_out;
    }
-
-   if (!db_sql_query(jcr->db_batch,
+   
+   if (!db_sql_query(jcr->db_batch, 
 "INSERT INTO File (FileIndex, JobId, PathId, FilenameId, LStat, MD5, DeltaSeq) "
     "SELECT batch.FileIndex, batch.JobId, Path.PathId, "
            "Filename.FilenameId,batch.LStat, batch.MD5, batch.DeltaSeq "
@@ -868,21 +831,21 @@ bool db_write_batch_file_records(JCR *jcr)
                      NULL, NULL))
    {
       Jmsg1(jcr, M_FATAL, 0, "Fill File table %s\n", jcr->db_batch->errmsg);
-      goto bail_out;
+      goto bail_out; 
    }
 
-   jcr->JobStatus = JobStatus;         /* reset entry status */
-   retval = true;
-
-bail_out:
-   db_sql_query(jcr->db_batch, "DROP TABLE batch", NULL,NULL);
+   jcr->JobStatus = JobStatus;    /* reset entry status */
+   retval = true; 
+bail_out: 
+   jcr->db_batch->bdb_sql_query("DROP TABLE batch", NULL,NULL);
    jcr->batch_started = false;
 
-   return retval;
+   return retval; 
 }
 
 /**
- * Create File record in B_DB
+ * Create File record in BDB
  *
  *  In order to reduce database size, we store the File attributes,
  *  the FileName, and the Path separately.  In principle, there
@@ -892,29 +855,28 @@ bail_out:
  *
  *  Note: all routines that call this expect to be able to call
  *    db_strerror(mdb) to get the error message, so the error message
- *    MUST be edited into mdb->errmsg before returning an error status.
+ *    MUST be edited into errmsg before returning an error status.
  */
-bool db_create_batch_file_attributes_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
+bool BDB::bdb_create_batch_file_attributes_record(JCR *jcr, ATTR_DBR *ar)
 {
    ASSERT(ar->FileType != FT_BASE);
-
    Dmsg1(dbglevel, "Fname=%s\n", ar->fname);
    Dmsg0(dbglevel, "put_file_into_catalog\n");
 
    if (jcr->batch_started && jcr->db_batch->changes > 500000) {
-      db_write_batch_file_records(jcr);
+      bdb_write_batch_file_records(jcr);
       jcr->db_batch->changes = 0;
    }
 
    /* Open the dedicated connexion */
    if (!jcr->batch_started) {
-      if (!db_open_batch_connexion(jcr, mdb)) {
+      if (!bdb_open_batch_connexion(jcr)) {
          return false;     /* error already printed */
       }
-      if (!sql_batch_start(jcr, jcr->db_batch)) {
-         Mmsg1(&mdb->errmsg,
+      if (!jcr->db_batch->sql_batch_start(jcr)) {
+         Mmsg1(&errmsg, 
               "Can't start batch mode: ERR=%s", db_strerror(jcr->db_batch));
-         Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg);
+         Jmsg(jcr, M_FATAL, 0, "%s", errmsg);
          return false;
       }
       jcr->batch_started = true;
@@ -922,11 +884,11 @@ bool db_create_batch_file_attributes_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
 
    split_path_and_file(jcr, jcr->db_batch, ar->fname);
 
-   return sql_batch_insert(jcr, jcr->db_batch, ar);
+   return jcr->db_batch->sql_batch_insert(jcr, ar);
 }
 
 /**
- * Create File record in B_DB
+ * Create File record in BDB
  *
  *  In order to reduce database size, we store the File attributes,
  *  the FileName, and the Path separately.  In principle, there
@@ -934,44 +896,44 @@ bool db_create_batch_file_attributes_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
  *  how many times it occurs.  This is this subroutine, we separate
  *  the file and the path and create three database records.
  */
-bool db_create_file_attributes_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
+bool BDB::bdb_create_file_attributes_record(JCR *jcr, ATTR_DBR *ar)
 {
-   db_lock(mdb);
+   bdb_lock();
    Dmsg1(dbglevel, "Fname=%s\n", ar->fname);
    Dmsg0(dbglevel, "put_file_into_catalog\n");
 
-   split_path_and_file(jcr, mdb, ar->fname);
+   split_path_and_file(jcr, this, ar->fname);
 
-   if (!db_create_filename_record(jcr, mdb, ar)) {
+   if (!bdb_create_filename_record(jcr, ar)) {
       goto bail_out;
    }
-   Dmsg1(dbglevel, "db_create_filename_record: %s\n", mdb->esc_name);
+   Dmsg1(dbglevel, "bdb_create_filename_record: %s\n", esc_name);
 
 
-   if (!db_create_path_record(jcr, mdb, ar)) {
+   if (!bdb_create_path_record(jcr, ar)) {
       goto bail_out;
    }
-   Dmsg1(dbglevel, "db_create_path_record: %s\n", mdb->esc_name);
+   Dmsg1(dbglevel, "bdb_create_path_record: %s\n", esc_name);
 
    /* Now create master File record */
-   if (!db_create_file_record(jcr, mdb, ar)) {
-      goto bail_out;
+   if (!bdb_create_file_record(jcr, ar)) {
+      goto bail_out; 
    }
    Dmsg0(dbglevel, "db_create_file_record OK\n");
 
-   Dmsg3(dbglevel, "CreateAttributes Path=%s File=%s FilenameId=%d\n", mdb->path, mdb->fname, ar->FilenameId);
-   db_unlock(mdb);
+   Dmsg3(dbglevel, "CreateAttributes Path=%s File=%s FilenameId=%d\n", path, fname, ar->FilenameId);
+   bdb_unlock();
    return true;
 
-bail_out:
-   db_unlock(mdb);
+bail_out: 
+   bdb_unlock();
    return false;
 }
 /**
  * This is the master File entry containing the attributes.
  *  The filename and path records have already been created.
  */
-static int db_create_file_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
+int BDB::bdb_create_file_record(JCR *jcr, ATTR_DBR *ar)
 {
    int stat;
    static const char *no_digest = "0";
@@ -988,17 +950,16 @@ static int db_create_file_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
    }
 
    /* Must create it */
-   Mmsg(mdb->cmd,
+   Mmsg(cmd,
         "INSERT INTO File (FileIndex,JobId,PathId,FilenameId,"
         "LStat,MD5,DeltaSeq) VALUES (%u,%u,%u,%u,'%s','%s',%u)",
         ar->FileIndex, ar->JobId, ar->PathId, ar->FilenameId,
         ar->attr, digest, ar->DeltaSeq);
 
-   ar->FileId = sql_insert_autokey_record(mdb, mdb->cmd, NT_("File"));
-   if (ar->FileId == 0) {
-      Mmsg2(&mdb->errmsg, _("Create db File record %s failed. ERR=%s"),
-         mdb->cmd, sql_strerror(mdb));
-      Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg);
+   if ((ar->FileId = sql_insert_autokey_record(cmd, NT_("File"))) == 0) {
+      Mmsg2(&errmsg, _("Create db File record %s failed. ERR=%s"),
+         cmd, sql_strerror());
+      Jmsg(jcr, M_FATAL, 0, "%s", errmsg);
       stat = 0;
    } else {
       stat = 1;
@@ -1007,82 +968,82 @@ static int db_create_file_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
 }
 
 /** Create a Unique record for the filename -- no duplicates */
-static int db_create_filename_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
+int BDB::bdb_create_filename_record(JCR *jcr, ATTR_DBR *ar)
 {
    SQL_ROW row;
    int num_rows;
 
-   mdb->errmsg[0] = 0;
-   mdb->esc_name = check_pool_memory_size(mdb->esc_name, 2*mdb->fnl+2);
-   db_escape_string(jcr, mdb, mdb->esc_name, mdb->fname, mdb->fnl);
-
-   Mmsg(mdb->cmd, "SELECT FilenameId FROM Filename WHERE Name='%s'", mdb->esc_name);
+   errmsg[0] = 0;
+   esc_name = check_pool_memory_size(esc_name, 2*fnl+2);
+   bdb_escape_string(jcr, esc_name, fname, fnl);
+   
+   Mmsg(cmd, "SELECT FilenameId FROM Filename WHERE Name='%s'", esc_name);
 
-   if (QUERY_DB(jcr, mdb, mdb->cmd)) {
-      num_rows = sql_num_rows(mdb);
+   if (QueryDB(jcr, cmd)) {
+      num_rows = sql_num_rows();
       if (num_rows > 1) {
          char ed1[30];
-         Mmsg2(&mdb->errmsg, _("More than one Filename! %s for file: %s\n"),
-            edit_uint64(num_rows, ed1), mdb->fname);
-         Jmsg(jcr, M_WARNING, 0, "%s", mdb->errmsg);
+         Mmsg2(&errmsg, _("More than one Filename! %s for file: %s\n"),
+            edit_uint64(num_rows, ed1), fname);
+         Jmsg(jcr, M_WARNING, 0, "%s", errmsg);
       }
       if (num_rows >= 1) {
-         if ((row = sql_fetch_row(mdb)) == NULL) {
-            Mmsg2(&mdb->errmsg, _("Error fetching row for file=%s: ERR=%s\n"),
-                mdb->fname, sql_strerror(mdb));
-            Jmsg(jcr, M_ERROR, 0, "%s", mdb->errmsg);
+         if ((row = sql_fetch_row()) == NULL) {
+            Mmsg2(&errmsg, _("Error fetching row for file=%s: ERR=%s\n"),
+                fname, sql_strerror());
+            Jmsg(jcr, M_ERROR, 0, "%s", errmsg);
             ar->FilenameId = 0;
          } else {
             ar->FilenameId = str_to_int64(row[0]);
          }
-         sql_free_result(mdb);
+         sql_free_result();
          return ar->FilenameId > 0;
       }
-      sql_free_result(mdb);
+      sql_free_result();
    }
 
-   Mmsg(mdb->cmd, "INSERT INTO Filename (Name) VALUES ('%s')", mdb->esc_name);
+   Mmsg(cmd, "INSERT INTO Filename (Name) VALUES ('%s')", esc_name);
 
-   ar->FilenameId = sql_insert_autokey_record(mdb, mdb->cmd, NT_("Filename"));
+   ar->FilenameId = sql_insert_autokey_record(cmd, NT_("Filename"));
    if (ar->FilenameId == 0) {
-      Mmsg2(&mdb->errmsg, _("Create db Filename record %s failed. ERR=%s\n"),
-            mdb->cmd, sql_strerror(mdb));
-      Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg);
+      Mmsg2(&errmsg, _("Create db Filename record %s failed. ERR=%s\n"),
+            cmd, sql_strerror());
+      Jmsg(jcr, M_FATAL, 0, "%s", errmsg);
    }
    return ar->FilenameId > 0;
 }
 
-/**
+/* 
  * Create file attributes record, or base file attributes record
  */
-bool db_create_attributes_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
+bool BDB::bdb_create_attributes_record(JCR *jcr, ATTR_DBR *ar)
 {
    bool ret;
 
-   mdb->errmsg[0] = 0;
+   errmsg[0] = 0;
    /*
     * Make sure we have an acceptable attributes record.
     */
    if (!(ar->Stream == STREAM_UNIX_ATTRIBUTES ||
          ar->Stream == STREAM_UNIX_ATTRIBUTES_EX)) {
-      Mmsg1(&mdb->errmsg, _("Attempt to put non-attributes into catalog. Stream=%d\n"),
+      Mmsg1(&errmsg, _("Attempt to put non-attributes into catalog. Stream=%d\n"),
          ar->Stream);
-      Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg);
+      Jmsg(jcr, M_FATAL, 0, "%s", errmsg);
       return false;
    }
 
    if (ar->FileType != FT_BASE) {
-      if (mdb->batch_insert_available()) {
-         ret = db_create_batch_file_attributes_record(jcr, mdb, ar);
+      if (batch_insert_available()) {
+         ret = bdb_create_batch_file_attributes_record(jcr, ar);
          /* Error message already printed */
-      } else {
-         ret = db_create_file_attributes_record(jcr, mdb, ar);
-      }
+      } else { 
+         ret = bdb_create_file_attributes_record(jcr, ar);
+      } 
    } else if (jcr->HasBase) {
-      ret = db_create_base_file_attributes_record(jcr, mdb, ar);
+      ret = bdb_create_base_file_attributes_record(jcr, ar);
    } else {
-      Mmsg0(&mdb->errmsg, _("Cannot Copy/Migrate job using BaseJob.\n"));
-      Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg);
+      Mmsg0(&errmsg, _("Cannot Copy/Migrate job using BaseJob.\n"));
+      Jmsg(jcr, M_FATAL, 0, "%s", errmsg);
       ret = true;               /* in copy/migration what do we do ? */
    }
 
@@ -1090,29 +1051,30 @@ bool db_create_attributes_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
 }
 
 /**
- * Create Base File record in B_DB
+ * Create Base File record in BDB
  *
  */
-bool db_create_base_file_attributes_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
+bool BDB::bdb_create_base_file_attributes_record(JCR *jcr, ATTR_DBR *ar)
 {
    bool ret;
+
    Dmsg1(dbglevel, "create_base_file Fname=%s\n", ar->fname);
    Dmsg0(dbglevel, "put_base_file_into_catalog\n");
 
-   db_lock(mdb);
-   split_path_and_file(jcr, mdb, ar->fname);
+   bdb_lock();
+   split_path_and_file(jcr, this, ar->fname);
 
-   mdb->esc_name = check_pool_memory_size(mdb->esc_name, mdb->fnl*2+1);
-   db_escape_string(jcr, mdb, mdb->esc_name, mdb->fname, mdb->fnl);
+   esc_name = check_pool_memory_size(esc_name, fnl*2+1);
+   bdb_escape_string(jcr, esc_name, fname, fnl);
 
-   mdb->esc_path = check_pool_memory_size(mdb->esc_path, mdb->pnl*2+1);
-   db_escape_string(jcr, mdb, mdb->esc_path, mdb->path, mdb->pnl);
+   esc_path = check_pool_memory_size(esc_path, pnl*2+1);
+   bdb_escape_string(jcr, esc_path, path, pnl);
 
-   Mmsg(mdb->cmd, "INSERT INTO basefile%lld (Path, Name) VALUES ('%s','%s')",
-        (uint64_t)jcr->JobId, mdb->esc_path, mdb->esc_name);
+   Mmsg(cmd, "INSERT INTO basefile%lld (Path, Name) VALUES ('%s','%s')",
+        (uint64_t)jcr->JobId, esc_path, esc_name);
 
-   ret = INSERT_DB(jcr, mdb, mdb->cmd);
-   db_unlock(mdb);
+   ret = InsertDB(jcr, cmd);
+   bdb_unlock();
 
    return ret;
 }
@@ -1120,28 +1082,28 @@ bool db_create_base_file_attributes_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
 /**
  * Cleanup the base file temporary tables
  */
-static void db_cleanup_base_file(JCR *jcr, B_DB *mdb)
+static void db_cleanup_base_file(JCR *jcr, BDB *mdb)
 {
    POOL_MEM buf(PM_MESSAGE);
    Mmsg(buf, "DROP TABLE new_basefile%lld", (uint64_t) jcr->JobId);
-   db_sql_query(mdb, buf.c_str(), NULL, NULL);
+   mdb->bdb_sql_query(buf.c_str(), NULL, NULL);
 
    Mmsg(buf, "DROP TABLE basefile%lld", (uint64_t) jcr->JobId);
-   db_sql_query(mdb, buf.c_str(), NULL, NULL);
+   mdb->bdb_sql_query(buf.c_str(), NULL, NULL);
 }
 
 /**
  * Put all base file seen in the backup to the BaseFile table
  * and cleanup temporary tables
  */
-bool db_commit_base_file_attributes_record(JCR *jcr, B_DB *mdb)
+bool BDB::bdb_commit_base_file_attributes_record(JCR *jcr)
 {
    bool ret;
    char ed1[50];
 
-   db_lock(mdb);
+   bdb_lock();
 
-   Mmsg(mdb->cmd,
+   Mmsg(cmd,
   "INSERT INTO BaseFiles (BaseJobId, JobId, FileId, FileIndex) "
    "SELECT B.JobId AS BaseJobId, %s AS JobId, "
           "B.FileId, B.FileIndex "
@@ -1150,18 +1112,18 @@ bool db_commit_base_file_attributes_record(JCR *jcr, B_DB *mdb)
       "AND A.Name = B.Name "
     "ORDER BY B.FileId",
         edit_uint64(jcr->JobId, ed1), ed1, ed1);
-   ret = db_sql_query(mdb, mdb->cmd, NULL, NULL);
+   ret = bdb_sql_query(cmd, NULL, NULL);
    /*
     * Display error now, because the subsequent cleanup destroys the
     *  error message from the above query.
     */
    if (!ret) {
-      Jmsg1(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
+      Jmsg1(jcr, M_FATAL, 0, "%s", jcr->db->bdb_strerror());
    }
-   jcr->nb_base_files_used = sql_affected_rows(mdb);
-   db_cleanup_base_file(jcr, mdb);
+   jcr->nb_base_files_used = sql_affected_rows();
+   db_cleanup_base_file(jcr, this);
 
-   db_unlock(mdb);
+   bdb_unlock();
    return ret;
 }
 
@@ -1172,77 +1134,148 @@ bool db_commit_base_file_attributes_record(JCR *jcr, B_DB *mdb)
  * 3) Put the result in a temporary table for the end of job
  *
  */
-bool db_create_base_file_list(JCR *jcr, B_DB *mdb, char *jobids)
+bool BDB::bdb_create_base_file_list(JCR *jcr, char *jobids)
 {
    POOL_MEM buf;
-   bool ret=false;
+   bool ret = false;
 
-   db_lock(mdb);
+   bdb_lock();
 
    if (!*jobids) {
-      Mmsg(mdb->errmsg, _("ERR=JobIds are empty\n"));
-      goto bail_out;
+      Mmsg(errmsg, _("ERR=JobIds are empty\n"));
+      goto bail_out; 
    }
 
-   Mmsg(mdb->cmd, create_temp_basefile[db_get_type_index(mdb)], (uint64_t) jcr->JobId);
-   if (!db_sql_query(mdb, mdb->cmd, NULL, NULL)) {
-      goto bail_out;
+   Mmsg(cmd, create_temp_basefile[bdb_get_type_index()], (uint64_t) jcr->JobId);
+   if (!bdb_sql_query(cmd, NULL, NULL)) {
+      goto bail_out; 
    }
-   Mmsg(buf, select_recent_version[db_get_type_index(mdb)], jobids, jobids);
-   Mmsg(mdb->cmd, create_temp_new_basefile[db_get_type_index(mdb)], (uint64_t)jcr->JobId, buf.c_str());
+   Mmsg(buf, select_recent_version[bdb_get_type_index()], jobids, jobids);
+   Mmsg(cmd, create_temp_new_basefile[bdb_get_type_index()], (uint64_t)jcr->JobId, buf.c_str());
 
-   ret = db_sql_query(mdb, mdb->cmd, NULL, NULL);
-bail_out:
-   db_unlock(mdb);
+   ret = bdb_sql_query(cmd, NULL, NULL);
+bail_out: 
+   bdb_unlock();
    return ret;
 }
 
 /**
- * Create Restore Object record in B_DB
+ * Create Restore Object record in BDB
  *
  */
-bool db_create_restore_object_record(JCR *jcr, B_DB *mdb, ROBJECT_DBR *ro)
+bool BDB::bdb_create_restore_object_record(JCR *jcr, ROBJECT_DBR *ro)
 {
    bool stat;
    int plug_name_len;
    POOLMEM *esc_plug_name = get_pool_memory(PM_MESSAGE);
 
-   db_lock(mdb);
+   bdb_lock();
 
    Dmsg1(dbglevel, "Oname=%s\n", ro->object_name);
    Dmsg0(dbglevel, "put_object_into_catalog\n");
 
-   mdb->fnl = strlen(ro->object_name);
-   mdb->esc_name = check_pool_memory_size(mdb->esc_name, mdb->fnl*2+1);
-   db_escape_string(jcr, mdb, mdb->esc_name, ro->object_name, mdb->fnl);
+   fnl = strlen(ro->object_name);
+   esc_name = check_pool_memory_size(esc_name, fnl*2+1);
+   bdb_escape_string(jcr, esc_name, ro->object_name, fnl);
 
-   db_escape_object(jcr, mdb, ro->object, ro->object_len);
+   bdb_escape_object(jcr, ro->object, ro->object_len);
 
    plug_name_len = strlen(ro->plugin_name);
    esc_plug_name = check_pool_memory_size(esc_plug_name, plug_name_len*2+1);
-   db_escape_string(jcr, mdb, esc_plug_name, ro->plugin_name, plug_name_len);
+   bdb_escape_string(jcr, esc_plug_name, ro->plugin_name, plug_name_len);
 
-   Mmsg(mdb->cmd,
+   Mmsg(cmd,
         "INSERT INTO RestoreObject (ObjectName,PluginName,RestoreObject,"
         "ObjectLength,ObjectFullLength,ObjectIndex,ObjectType,"
         "ObjectCompression,FileIndex,JobId) "
         "VALUES ('%s','%s','%s',%d,%d,%d,%d,%d,%d,%u)",
-        mdb->esc_name, esc_plug_name, mdb->esc_obj,
+        esc_name, esc_plug_name, esc_obj,
         ro->object_len, ro->object_full_len, ro->object_index,
         ro->FileType, ro->object_compression, ro->FileIndex, ro->JobId);
 
-   ro->RestoreObjectId = sql_insert_autokey_record(mdb, mdb->cmd, NT_("RestoreObject"));
+   ro->RestoreObjectId = sql_insert_autokey_record(cmd, NT_("RestoreObject"));
    if (ro->RestoreObjectId == 0) {
-      Mmsg2(&mdb->errmsg, _("Create db Object record %s failed. ERR=%s"),
-         mdb->cmd, sql_strerror(mdb));
-      Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg);
+      Mmsg2(&errmsg, _("Create db Object record %s failed. ERR=%s"),
+         cmd, sql_strerror());
+      Jmsg(jcr, M_FATAL, 0, "%s", errmsg);
       stat = false;
    } else {
       stat = true;
    }
-   db_unlock(mdb);
+   bdb_unlock();
    free_pool_memory(esc_plug_name);
    return stat;
 }
 
+bool BDB::bdb_create_snapshot_record(JCR *jcr, SNAPSHOT_DBR *snap)
+{
+   bool status = false;
+   char esc_name[MAX_ESCAPE_NAME_LENGTH];
+   POOLMEM *esc_vol = get_pool_memory(PM_MESSAGE);
+   POOLMEM *esc_dev = get_pool_memory(PM_MESSAGE);
+   POOLMEM *esc_type = get_pool_memory(PM_MESSAGE);
+   POOLMEM *esc_client = get_pool_memory(PM_MESSAGE);
+   POOLMEM *esc_fs = get_pool_memory(PM_MESSAGE);
+   char esc_comment[MAX_ESCAPE_NAME_LENGTH];
+   char dt[MAX_TIME_LENGTH], ed1[50], ed2[50];
+   time_t stime;
+   struct tm tm;
+
+   bdb_lock();
+
+   esc_vol = check_pool_memory_size(esc_vol, strlen(snap->Volume) * 2 + 1);
+   bdb_escape_string(jcr, esc_vol, snap->Volume, strlen(snap->Volume));
+
+   esc_dev = check_pool_memory_size(esc_dev, strlen(snap->Device) * 2 + 1);
+   bdb_escape_string(jcr, esc_dev, snap->Device, strlen(snap->Device));
+
+   esc_type = check_pool_memory_size(esc_type, strlen(snap->Type) * 2 + 1);
+   bdb_escape_string(jcr, esc_type, snap->Type, strlen(snap->Type));
+
+   bdb_escape_string(jcr, esc_comment, snap->Comment, strlen(snap->Comment));
+
+   if (*snap->Client) {
+      bdb_escape_string(jcr, esc_name, snap->Client, strlen(snap->Client));
+      Mmsg(esc_client, "(SELECT ClientId FROM Client WHERE Name='%s')", esc_name);
+
+   } else {
+      Mmsg(esc_client, "%d", snap->ClientId);
+   }
+
+   if (*snap->FileSet) {
+      bdb_escape_string(jcr, esc_name, snap->FileSet, strlen(snap->FileSet));
+      Mmsg(esc_fs, "(SELECT FileSetId FROM FileSet WHERE FileSet='%s' ORDER BY CreateTime DESC LIMIT 1)", esc_name);
+
+   } else {
+      Mmsg(esc_fs, "%d", snap->FileSetId);
+   }
+
+   bdb_escape_string(jcr, esc_name, snap->Name, strlen(snap->Name));
+
+   stime = snap->CreateTDate;
+   (void)localtime_r(&stime, &tm);
+   strftime(dt, sizeof(dt), "%Y-%m-%d %H:%M:%S", &tm);
+
+   Mmsg(cmd, "INSERT INTO Snapshot "
+        "(Name, JobId, CreateTDate, CreateDate, ClientId, FileSetId, Volume, Device, Type, Retention, Comment) "
+ "VALUES ('%s', %s, %d, '%s', %s, %s, '%s', '%s', '%s', %s, '%s')",
+        esc_name, edit_uint64(snap->JobId, ed2), stime, dt, esc_client, esc_fs, esc_vol,
+        esc_dev, esc_type, edit_int64(snap->Retention, ed1), esc_comment);
+
+   if (bdb_sql_query(cmd, NULL, NULL)) {
+      snap->SnapshotId = sql_insert_autokey_record(cmd, NT_("Snapshot"));
+      status = true;
+   }
+
+   bdb_unlock();
+
+   free_pool_memory(esc_vol);
+   free_pool_memory(esc_dev);
+   free_pool_memory(esc_type);
+   free_pool_memory(esc_client);
+   free_pool_memory(esc_fs);
+
+   return status;
+}
+
 #endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_POSTGRESQL */