]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/cats/postgresql.c
bvfs: Restore should be ok with MySQL
[bacula/bacula] / bacula / src / cats / postgresql.c
index 9407978d67ce1e751857298f0b5d5601511fd4ff..959baf75ed239ab91f2c73307b47754834db3f9e 100644 (file)
@@ -6,7 +6,7 @@
    The main author of Bacula is Kern Sibbald, with contributions from
    many others, a complete list can be found in the file AUTHORS.
    This program is Free Software; you can redistribute it and/or
-   modify it under the terms of version two of the GNU General Public
+   modify it under the terms of version three of the GNU Affero General Public
    License as published by the Free Software Foundation and included
    in the file LICENSE.
 
@@ -15,7 +15,7 @@
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    General Public License for more details.
 
-   You should have received a copy of the GNU General Public License
+   You should have received a copy of the GNU Affero General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
@@ -117,7 +117,6 @@ db_init_database(JCR *jcr, const char *db_name, const char *db_user, const char
       mdb->db_socket   = bstrdup(db_socket);
    }
    mdb->db_port        = db_port;
-   mdb->have_insert_id = TRUE;
    mdb->errmsg         = get_pool_memory(PM_EMSG); /* get error message buffer */
    *mdb->errmsg        = 0;
    mdb->cmd            = get_pool_memory(PM_EMSG); /* get command buffer */
@@ -127,7 +126,7 @@ db_init_database(JCR *jcr, const char *db_name, const char *db_user, const char
    mdb->fname          = get_pool_memory(PM_FNAME);
    mdb->path           = get_pool_memory(PM_FNAME);
    mdb->esc_name       = get_pool_memory(PM_FNAME);
-   mdb->esc_path      = get_pool_memory(PM_FNAME);
+   mdb->esc_path       = get_pool_memory(PM_FNAME);
    mdb->allow_transactions = mult_db_connections;
    db_list->append(mdb);                   /* put db in list */
    V(mutex);
@@ -291,6 +290,9 @@ db_close_database(JCR *jcr, B_DB *mdb)
       if (mdb->db_socket) {
          free(mdb->db_socket);
       }
+      if (mdb->esc_obj) {
+         PQfreemem(mdb->esc_obj);
+      }
       free(mdb);
       if (db_list->size() == 0) {
          delete db_list;
@@ -328,6 +330,61 @@ int db_next_index(JCR *jcr, B_DB *mdb, char *table, char *index)
    return 1;
 }
 
+/*
+ * Escape binary so that PostgreSQL is happy
+ *
+ */
+char *
+db_escape_object(JCR *jcr, B_DB *mdb, char *old, int len)
+{
+   size_t new_len;
+   if (mdb->esc_obj) {
+      PQfreemem(mdb->esc_obj);
+   }
+
+   mdb->esc_obj = PQescapeByteaConn(mdb->db, (unsigned const char *)old,
+                                    len, &new_len);
+
+   if (!mdb->esc_obj) {
+      Jmsg(jcr, M_FATAL, 0, _("PQescapeByteaConn returned NULL.\n"));
+   }
+
+   return (char *)mdb->esc_obj;
+}
+
+/*
+ * Unescape binary object so that PostgreSQL is happy
+ *
+ */
+void
+db_unescape_object(JCR *jcr, B_DB *mdb, 
+                   char *from, int32_t expected_len,
+                   POOLMEM **dest, int32_t *dest_len)
+{
+   size_t new_len;
+   unsigned char *obj;
+
+   if (!from) {
+      *dest[0] = 0;
+      *dest_len = 0;
+      return;
+   }
+
+   obj = PQunescapeBytea((unsigned const char *)from, &new_len);
+
+   if (!obj) {
+      Jmsg(jcr, M_FATAL, 0, _("PQunescapeByteaConn returned NULL.\n"));
+   }
+
+   *dest_len = new_len;
+   *dest = check_pool_memory_size(*dest, new_len+1);
+   memcpy(*dest, obj, new_len);
+   (*dest)[new_len]=0;
+   
+   PQfreemem(obj);
+
+   Dmsg1(010, "obj size: %d\n", *dest_len);
+}
 
 /*
  * Escape strings so that PostgreSQL is happy
@@ -593,7 +650,7 @@ void my_postgresql_free_result(B_DB *mdb)
    db_unlock(mdb);
 }
 
-int my_postgresql_currval(B_DB *mdb, const char *table_name)
+static uint64_t my_postgresql_currval(B_DB *mdb, const char *table_name)
 {
    // Obtain the current value of the sequence that
    // provides the serial value for primary key of the table.
@@ -614,7 +671,7 @@ int my_postgresql_currval(B_DB *mdb, const char *table_name)
    char      sequence[NAMEDATALEN-1];
    char      query   [NAMEDATALEN+50];
    PGresult *result;
-   int       id = 0;
+   uint64_t  id = 0;
 
    if (strcasecmp(table_name, "basefiles") == 0) {
       bstrncpy(sequence, "basefiles_baseid", sizeof(sequence));
@@ -645,7 +702,7 @@ int my_postgresql_currval(B_DB *mdb, const char *table_name)
 
    if (PQresultStatus(result) == PGRES_TUPLES_OK) {
       Dmsg0(500, "getting value");
-      id = atoi(PQgetvalue(result, 0, 0));
+      id = str_to_uint64(PQgetvalue(result, 0, 0));
       Dmsg2(500, "got value '%s' which became %d\n", PQgetvalue(result, 0, 0), id);
    } else {
       Dmsg1(50, "Result status failed: %s\n", query);
@@ -654,10 +711,29 @@ int my_postgresql_currval(B_DB *mdb, const char *table_name)
 
 bail_out:
    PQclear(result);
-
+   
    return id;
 }
 
+uint64_t my_postgresql_insert_autokey_record(B_DB *mdb, const char *query, const char *table_name)
+{
+   /*
+    * First execute the insert query and then retrieve the currval.
+    */
+   if (my_postgresql_query(mdb, query)) {
+      return 0;
+   }
+
+   mdb->num_rows = sql_affected_rows(mdb);
+   if (mdb->num_rows != 1) {
+      return 0;
+   }
+
+   mdb->changes++;
+
+   return my_postgresql_currval(mdb, table_name);
+}
+
 #ifdef HAVE_BATCH_FILE_INSERT
 
 int my_postgresql_batch_start(JCR *jcr, B_DB *mdb)