]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/cats/dbi.c
7cbfc1868f509fbc18e87026a560a2c0fdd07713
[bacula/bacula] / bacula / src / cats / dbi.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2003-2008 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from
7    many others, a complete list can be found in the file AUTHORS.
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version two of the GNU General Public
10    License as published by the Free Software Foundation and included
11    in the file LICENSE.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    Bacula® is a registered trademark of Kern Sibbald.
24    The licensor of Bacula is the Free Software Foundation Europe
25    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26    Switzerland, email:ftf@fsfeurope.org.
27 */
28 /*
29  * Bacula Catalog Database routines specific to DBI
30  *   These are DBI specific routines
31  *
32  *    João Henrique Freitas, December 2007
33  *    based upon work done by Dan Langille, December 2003 and
34  *    by Kern Sibbald, March 2000
35  *
36  *    Version $Id$
37  */
38
39
40 /* The following is necessary so that we do not include
41  * the dummy external definition of DB.
42  */
43 #define __SQL_C                       /* indicate that this is sql.c */
44
45 #include "bacula.h"
46 #include "cats.h"
47
48 #ifdef HAVE_DBI
49
50 /* -----------------------------------------------------------------------
51  *
52  *   DBI dependent defines and subroutines
53  *
54  * -----------------------------------------------------------------------
55  */
56
57 /* List of open databases */
58 static BQUEUE db_list = {&db_list, &db_list};
59
60 /* Control allocated fields by my_dbi_getvalue */
61 static BQUEUE dbi_getvalue_list = {&dbi_getvalue_list, &dbi_getvalue_list};
62
63 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
64
65 /*
66  * Retrieve database type
67  */
68 const char *
69 db_get_type(void)
70 {
71    return "DBI";
72 }
73
74 /*
75  * Initialize database data structure. In principal this should
76  * never have errors, or it is really fatal.
77  */
78 B_DB *
79 db_init_database(JCR *jcr, const char *db_name, const char *db_user, const char *db_password,
80                  const char *db_address, int db_port, const char *db_socket,
81                  int mult_db_connections)
82 {
83    B_DB *mdb;
84    char db_driver[10];
85    char db_driverdir[256];
86
87    /* Constraint the db_driver */
88    if(db_type  == -1) {
89       Jmsg(jcr, M_FATAL, 0, _("A dbi driver for DBI must be supplied.\n"));
90       return NULL;
91    }
92
93    /* Do the correct selection of driver.
94     * Can be one of the varius supported by libdbi
95     */
96    switch (db_type) {
97    case SQL_TYPE_MYSQL:
98       bstrncpy(db_driver,"mysql", sizeof(db_driver));
99       break;
100    case SQL_TYPE_POSTGRESQL:
101       bstrncpy(db_driver,"pgsql", sizeof(db_driver));
102       break;
103    case SQL_TYPE_SQLITE:
104       bstrncpy(db_driver,"sqlite", sizeof(db_driver));
105       break;
106    case SQL_TYPE_SQLITE3:
107       bstrncpy(db_driver,"sqlite3", sizeof(db_driver));
108       break;
109    }
110
111    /* Set db_driverdir whereis is the libdbi drivers */
112    bstrncpy(db_driverdir, DBI_DRIVER_DIR, 255);
113
114    if (!db_user) {
115       Jmsg(jcr, M_FATAL, 0, _("A user name for DBI must be supplied.\n"));
116       return NULL;
117    }
118    P(mutex);                          /* lock DB queue */
119    if (!mult_db_connections) {
120       /* Look to see if DB already open */
121       for (mdb=NULL; (mdb=(B_DB *)qnext(&db_list, &mdb->bq)); ) {
122          if (bstrcmp(mdb->db_name, db_name) &&
123              bstrcmp(mdb->db_address, db_address) &&
124              bstrcmp(mdb->db_driver, db_driver) &&
125              mdb->db_port == db_port) {
126             Dmsg4(100, "DB REopen %d %s %s erro: %d\n", mdb->ref_count, db_driver, db_name,
127                   dbi_conn_error(mdb->db, NULL));
128             mdb->ref_count++;
129             V(mutex);
130             return mdb;                  /* already open */
131          }
132       }
133    }
134    Dmsg0(100, "db_open first time\n");
135    mdb = (B_DB *)malloc(sizeof(B_DB));
136    memset(mdb, 0, sizeof(B_DB));
137    mdb->db_name = bstrdup(db_name);
138    mdb->db_user = bstrdup(db_user);
139    if (db_password) {
140       mdb->db_password = bstrdup(db_password);
141    }
142    if (db_address) {
143       mdb->db_address  = bstrdup(db_address);
144    }
145    if (db_socket) {
146       mdb->db_socket   = bstrdup(db_socket);
147    }
148    if (db_driverdir) {
149       mdb->db_driverdir = bstrdup(db_driverdir);
150    }
151    if (db_driver) {
152       mdb->db_driver    = bstrdup(db_driver);
153    }
154    mdb->db_type        = db_type;
155    mdb->db_port        = db_port;
156    mdb->have_insert_id = TRUE;
157    mdb->errmsg         = get_pool_memory(PM_EMSG); /* get error message buffer */
158    *mdb->errmsg        = 0;
159    mdb->cmd            = get_pool_memory(PM_EMSG); /* get command buffer */
160    mdb->cached_path    = get_pool_memory(PM_FNAME);
161    mdb->cached_path_id = 0;
162    mdb->ref_count      = 1;
163    mdb->fname          = get_pool_memory(PM_FNAME);
164    mdb->path           = get_pool_memory(PM_FNAME);
165    mdb->esc_name       = get_pool_memory(PM_FNAME);
166    mdb->esc_path      = get_pool_memory(PM_FNAME);
167    mdb->allow_transactions = mult_db_connections;
168    qinsert(&db_list, &mdb->bq);            /* put db in list */
169    V(mutex);
170    return mdb;
171 }
172
173 /*
174  * Now actually open the database.  This can generate errors,
175  *   which are returned in the errmsg
176  *
177  * DO NOT close the database or free(mdb) here  !!!!
178  */
179 int
180 db_open_database(JCR *jcr, B_DB *mdb)
181 {
182    int errstat;
183    int dbstat;
184    uint8_t len;
185    const char *errmsg;
186    char buf[10], *port;
187    int numdrivers;
188    char *db_name = NULL;
189    char *db_dir = NULL;
190
191    P(mutex);
192    if (mdb->connected) {
193       V(mutex);
194       return 1;
195    }
196    mdb->connected = false;
197
198    if ((errstat=rwl_init(&mdb->lock)) != 0) {
199       berrno be;
200       Mmsg1(&mdb->errmsg, _("Unable to initialize DB lock. ERR=%s\n"),
201             be.bstrerror(errstat));
202       V(mutex);
203       return 0;
204    }
205
206    if (mdb->db_port) {
207       bsnprintf(buf, sizeof(buf), "%d", mdb->db_port);
208       port = buf;
209    } else {
210       port = NULL;
211    }
212
213    numdrivers = dbi_initialize_r(mdb->db_driverdir, &(mdb->instance));
214    if (numdrivers < 0) {
215       Mmsg2(&mdb->errmsg, _("Unable to locate the DBD drivers to DBI interface in: \n"
216                                "db_driverdir=%s. It is probaly not found any drivers\n"),
217                                mdb->db_driverdir,numdrivers);
218       V(mutex);
219       return 0;
220    }
221    mdb->db = (void **)dbi_conn_new_r(mdb->db_driver, mdb->instance);
222    /* Can be many types of databases */
223    switch (mdb->db_type) {
224    case SQL_TYPE_MYSQL:
225       dbi_conn_set_option(mdb->db, "host", mdb->db_address); /* default = localhost */
226       dbi_conn_set_option(mdb->db, "port", port);            /* default port */
227       dbi_conn_set_option(mdb->db, "username", mdb->db_user);     /* login name */
228       dbi_conn_set_option(mdb->db, "password", mdb->db_password); /* password */
229       dbi_conn_set_option(mdb->db, "dbname", mdb->db_name);       /* database name */
230       break;
231    case SQL_TYPE_POSTGRESQL:
232       dbi_conn_set_option(mdb->db, "host", mdb->db_address);
233       dbi_conn_set_option(mdb->db, "port", port);
234       dbi_conn_set_option(mdb->db, "username", mdb->db_user);
235       dbi_conn_set_option(mdb->db, "password", mdb->db_password);
236       dbi_conn_set_option(mdb->db, "dbname", mdb->db_name);
237       break;
238    case SQL_TYPE_SQLITE:
239       len = strlen(working_directory) + 5;
240       db_dir = (char *)malloc(len);
241       strcpy(db_dir, working_directory);
242       strcat(db_dir, "/");
243       len = strlen(mdb->db_name) + 5;
244       db_name = (char *)malloc(len);
245       strcpy(db_name, mdb->db_name);
246       strcat(db_name, ".db");
247       dbi_conn_set_option(mdb->db, "sqlite_dbdir", db_dir);
248       dbi_conn_set_option(mdb->db, "dbname", db_name);
249       break;
250    case SQL_TYPE_SQLITE3:
251       len = strlen(working_directory) + 5;
252       db_dir = (char *)malloc(len);
253       strcpy(db_dir, working_directory);
254       strcat(db_dir, "/");
255       len = strlen(mdb->db_name) + 5;
256       db_name = (char *)malloc(len);
257       strcpy(db_name, mdb->db_name);
258       strcat(db_name, ".db");
259       dbi_conn_set_option(mdb->db, "sqlite3_dbdir", db_dir);
260       dbi_conn_set_option(mdb->db, "dbname", db_name);
261       Dmsg2(500, "SQLITE: %s %s\n", db_dir, db_name);
262       break;
263    }
264
265    /* If connection fails, try at 5 sec intervals for 30 seconds. */
266    for (int retry=0; retry < 6; retry++) {
267
268       dbstat = dbi_conn_connect(mdb->db);
269       if ( dbstat == 0) {
270          break;
271       }
272
273       dbi_conn_error(mdb->db, &errmsg);
274       Dmsg1(50, "dbi error: %s\n", errmsg);
275
276       bmicrosleep(5, 0);
277
278    }
279
280    if ( dbstat != 0 ) {
281       Mmsg3(&mdb->errmsg, _("Unable to connect to DBI interface.\n"
282                        "Type=%s Database=%s User=%s\n"
283                        "It is probably not running or your password is incorrect.\n"),
284                         mdb->db_driver, mdb->db_name, mdb->db_user);
285       V(mutex);
286       return 0;
287    }
288
289    Dmsg0(50, "dbi_real_connect done\n");
290    Dmsg3(50, "db_user=%s db_name=%s db_password=%s\n",
291                     mdb->db_user, mdb->db_name,
292                     mdb->db_password==NULL?"(NULL)":mdb->db_password);
293
294    mdb->connected = true;
295
296    if (!check_tables_version(jcr, mdb)) {
297       V(mutex);
298       return 0;
299    }
300
301    switch (mdb->db_type) {
302    case SQL_TYPE_MYSQL:
303       /* Set connection timeout to 8 days specialy for batch mode */
304       sql_query(mdb, "SET wait_timeout=691200");
305       sql_query(mdb, "SET interactive_timeout=691200");
306       break;
307    case SQL_TYPE_POSTGRESQL:
308       /* tell PostgreSQL we are using standard conforming strings
309          and avoid warnings such as:
310          WARNING:  nonstandard use of \\ in a string literal
311       */
312       sql_query(mdb, "SET datestyle TO 'ISO, YMD'");
313       sql_query(mdb, "set standard_conforming_strings=on");
314       break;
315    }
316
317    if(db_dir) {
318       free(db_dir);
319    }
320    if(db_name) {
321       free(db_name);
322    }
323
324    V(mutex);
325    return 1;
326 }
327
328 void
329 db_close_database(JCR *jcr, B_DB *mdb)
330 {
331    if (!mdb) {
332       return;
333    }
334    db_end_transaction(jcr, mdb);
335    P(mutex);
336    sql_free_result(mdb);
337    mdb->ref_count--;
338    if (mdb->ref_count == 0) {
339       qdchain(&mdb->bq);
340       if (mdb->connected && mdb->db) {
341          //sql_close(mdb);
342          dbi_shutdown_r(mdb->instance);
343          mdb->db = NULL;
344          mdb->instance = NULL;
345       }
346       rwl_destroy(&mdb->lock);
347       free_pool_memory(mdb->errmsg);
348       free_pool_memory(mdb->cmd);
349       free_pool_memory(mdb->cached_path);
350       free_pool_memory(mdb->fname);
351       free_pool_memory(mdb->path);
352       free_pool_memory(mdb->esc_name);
353       free_pool_memory(mdb->esc_path);
354       if (mdb->db_name) {
355          free(mdb->db_name);
356       }
357       if (mdb->db_user) {
358          free(mdb->db_user);
359       }
360       if (mdb->db_password) {
361          free(mdb->db_password);
362       }
363       if (mdb->db_address) {
364          free(mdb->db_address);
365       }
366       if (mdb->db_socket) {
367          free(mdb->db_socket);
368       }
369       if (mdb->db_driverdir) {
370          free(mdb->db_driverdir);
371       }
372       if (mdb->db_driver) {
373           free(mdb->db_driver);
374       }
375       free(mdb);
376    }
377    V(mutex);
378 }
379
380 void db_thread_cleanup()
381 { }
382
383 /*
384  * Return the next unique index (auto-increment) for
385  * the given table.  Return NULL on error.
386  *
387  */
388 int db_next_index(JCR *jcr, B_DB *mdb, char *table, char *index)
389 {
390    strcpy(index, "NULL");
391    return 1;
392 }
393
394
395 /*
396  * Escape strings so that DBI is happy
397  *
398  *   NOTE! len is the length of the old string. Your new
399  *         string must be long enough (max 2*old+1) to hold
400  *         the escaped output.
401  *
402  * dbi_conn_quote_string_copy receives a pointer to pointer.
403  * We need copy the value of pointer to snew because libdbi change the
404  * pointer
405  */
406 void
407 db_escape_string(JCR *jcr, B_DB *mdb, char *snew, char *old, int len)
408 {
409    char *inew;
410    char *pnew;
411
412    if (len == 0) {
413       snew[0] = 0;
414    } else {
415       /* correct the size of old basead in len
416        * and copy new string to inew
417        */
418       inew = (char *)malloc(sizeof(char) * len + 1);
419       bstrncpy(inew,old,len + 1);
420       /* escape the correct size of old */
421       dbi_conn_escape_string_copy(mdb->db, inew, &pnew);
422       free(inew);
423       /* copy the escaped string to snew */
424       bstrncpy(snew, pnew, 2 * len + 1);
425    }
426
427    Dmsg2(500, "dbi_conn_escape_string_copy %p %s\n",snew,snew);
428
429 }
430
431 /*
432  * Submit a general SQL command (cmd), and for each row returned,
433  *  the sqlite_handler is called with the ctx.
434  */
435 bool db_sql_query(B_DB *mdb, const char *query, DB_RESULT_HANDLER *result_handler, void *ctx)
436 {
437    SQL_ROW row;
438
439    Dmsg0(500, "db_sql_query started\n");
440
441    db_lock(mdb);
442    if (sql_query(mdb, query) != 0) {
443       Mmsg(mdb->errmsg, _("Query failed: %s: ERR=%s\n"), query, sql_strerror(mdb));
444       db_unlock(mdb);
445       Dmsg0(500, "db_sql_query failed\n");
446       return false;
447    }
448    Dmsg0(500, "db_sql_query succeeded. checking handler\n");
449
450    if (result_handler != NULL) {
451       Dmsg0(500, "db_sql_query invoking handler\n");
452       if ((mdb->result = sql_store_result(mdb)) != NULL) {
453          int num_fields = sql_num_fields(mdb);
454
455          Dmsg0(500, "db_sql_query sql_store_result suceeded\n");
456          while ((row = sql_fetch_row(mdb)) != NULL) {
457
458             Dmsg0(500, "db_sql_query sql_fetch_row worked\n");
459             if (result_handler(ctx, num_fields, row))
460                break;
461          }
462
463         sql_free_result(mdb);
464       }
465    }
466    db_unlock(mdb);
467
468    Dmsg0(500, "db_sql_query finished\n");
469
470    return true;
471 }
472
473
474
475 DBI_ROW my_dbi_fetch_row(B_DB *mdb)
476 {
477    int j;
478    DBI_ROW row = NULL; // by default, return NULL
479
480    Dmsg0(500, "my_dbi_fetch_row start\n");
481    if ((!mdb->row || mdb->row_size < mdb->num_fields) && mdb->num_rows > 0) {
482       int num_fields = mdb->num_fields;
483       Dmsg1(500, "we have need space of %d bytes\n", sizeof(char *) * mdb->num_fields);
484
485       if (mdb->row) {
486          Dmsg0(500, "my_dbi_fetch_row freeing space\n");
487          Dmsg2(500, "my_dbi_free_row row: '%p' num_fields: '%d'\n", mdb->row, mdb->num_fields);
488          if (mdb->num_rows != 0) {
489             for(j = 0; j < mdb->num_fields; j++) {
490                Dmsg2(500, "my_dbi_free_row row '%p' '%d'\n", mdb->row[j], j);
491                   if(mdb->row[j]) {
492                      free(mdb->row[j]);
493                   }
494             }
495          }
496          free(mdb->row);
497       }
498       //num_fields += 20;                  /* add a bit extra */
499       mdb->row = (DBI_ROW)malloc(sizeof(char *) * num_fields);
500       mdb->row_size = num_fields;
501
502       // now reset the row_number now that we have the space allocated
503       mdb->row_number = 1;
504    }
505
506    // if still within the result set
507    if (mdb->row_number <= mdb->num_rows && mdb->row_number != DBI_ERROR_BADPTR) {
508       Dmsg2(500, "my_dbi_fetch_row row number '%d' is acceptable (1..%d)\n", mdb->row_number, mdb->num_rows);
509       // get each value from this row
510       for (j = 0; j < mdb->num_fields; j++) {
511          mdb->row[j] = my_dbi_getvalue(mdb->result, mdb->row_number, j);
512          // allocate space to queue row
513          mdb->field_get = (DBI_FIELD_GET *)malloc(sizeof(DBI_FIELD_GET));
514          // store the pointer in queue
515          mdb->field_get->value = mdb->row[j];
516          Dmsg4(500, "my_dbi_fetch_row row[%d] field: '%p' in queue: '%p' has value: '%s'\n",
517                j, mdb->row[j], mdb->field_get->value, mdb->row[j]);
518          // insert in queue to future free
519          qinsert(&dbi_getvalue_list, &mdb->field_get->bq);
520       }
521       // increment the row number for the next call
522       mdb->row_number++;
523
524       row = mdb->row;
525    } else {
526       Dmsg2(500, "my_dbi_fetch_row row number '%d' is NOT acceptable (1..%d)\n", mdb->row_number, mdb->num_rows);
527    }
528
529    Dmsg1(500, "my_dbi_fetch_row finishes returning %p\n", row);
530
531    return row;
532 }
533
534 int my_dbi_max_length(B_DB *mdb, int field_num) {
535    //
536    // for a given column, find the max length
537    //
538    int max_length;
539    int i;
540    int this_length;
541    char *cbuf = NULL;
542
543    max_length = 0;
544    for (i = 0; i < mdb->num_rows; i++) {
545       if (my_dbi_getisnull(mdb->result, i, field_num)) {
546           this_length = 4;        // "NULL"
547       } else {
548          cbuf = my_dbi_getvalue(mdb->result, i, field_num);
549          this_length = cstrlen(cbuf);
550          // cbuf is always free
551          free(cbuf);
552       }
553
554       if (max_length < this_length) {
555           max_length = this_length;
556       }
557    }
558
559    return max_length;
560 }
561
562 DBI_FIELD * my_dbi_fetch_field(B_DB *mdb)
563 {
564    int     i;
565    int     dbi_index;
566
567    Dmsg0(500, "my_dbi_fetch_field starts\n");
568
569    if (!mdb->fields || mdb->fields_size < mdb->num_fields) {
570       if (mdb->fields) {
571          free(mdb->fields);
572       }
573       Dmsg1(500, "allocating space for %d fields\n", mdb->num_fields);
574       mdb->fields = (DBI_FIELD *)malloc(sizeof(DBI_FIELD) * mdb->num_fields);
575       mdb->fields_size = mdb->num_fields;
576
577       for (i = 0; i < mdb->num_fields; i++) {
578          // num_fileds is starting at 1, increment i by 1
579          dbi_index = i + 1;
580          Dmsg1(500, "filling field %d\n", i);
581          mdb->fields[i].name       = (char *)dbi_result_get_field_name(mdb->result, dbi_index);
582          mdb->fields[i].max_length = my_dbi_max_length(mdb, i);
583          mdb->fields[i].type       = dbi_result_get_field_type_idx(mdb->result, dbi_index);
584          mdb->fields[i].flags      = dbi_result_get_field_attribs_idx(mdb->result, dbi_index);
585
586          Dmsg4(500, "my_dbi_fetch_field finds field '%s' has length='%d' type='%d' and IsNull=%d\n",
587             mdb->fields[i].name, mdb->fields[i].max_length, mdb->fields[i].type,
588             mdb->fields[i].flags);
589       } // end for
590    } // end if
591
592    // increment field number for the next time around
593
594    Dmsg0(500, "my_dbi_fetch_field finishes\n");
595    return &mdb->fields[mdb->field_number++];
596 }
597
598 void my_dbi_data_seek(B_DB *mdb, int row)
599 {
600    // set the row number to be returned on the next call
601    // to my_dbi_fetch_row
602    mdb->row_number = row;
603 }
604
605 void my_dbi_field_seek(B_DB *mdb, int field)
606 {
607    mdb->field_number = field;
608 }
609
610 /*
611  * Note, if this routine returns 1 (failure), Bacula expects
612  *  that no result has been stored.
613  *
614  *  Returns:  0  on success
615  *            1  on failure
616  *
617  */
618 int my_dbi_query(B_DB *mdb, const char *query)
619 {
620    const char *errmsg;
621    Dmsg1(500, "my_dbi_query started %s\n", query);
622    // We are starting a new query.  reset everything.
623    mdb->num_rows     = -1;
624    mdb->row_number   = -1;
625    mdb->field_number = -1;
626
627    if (mdb->result) {
628       dbi_result_free(mdb->result);  /* hmm, someone forgot to free?? */
629       mdb->result = NULL;
630    }
631
632    mdb->result = (void **)dbi_conn_query(mdb->db, query);
633
634    if (!mdb->result) {
635       Dmsg2(50, "Query failed: %s %p\n", query, mdb->result);
636       goto bail_out;
637    }
638
639    mdb->status = (dbi_error_flag) dbi_conn_error(mdb->db, &errmsg);
640
641    if (mdb->status == DBI_ERROR_NONE) {
642       Dmsg1(500, "we have a result\n", query);
643
644       // how many fields in the set?
645       // num_fields starting at 1
646       mdb->num_fields = dbi_result_get_numfields(mdb->result);
647       Dmsg1(500, "we have %d fields\n", mdb->num_fields);
648       // if no result num_rows is 0
649       mdb->num_rows = dbi_result_get_numrows(mdb->result);
650       Dmsg1(500, "we have %d rows\n", mdb->num_rows);
651
652       mdb->status = (dbi_error_flag) 0;                  /* succeed */
653    } else {
654       Dmsg1(50, "Result status failed: %s\n", query);
655       goto bail_out;
656    }
657
658    Dmsg0(500, "my_dbi_query finishing\n");
659    return mdb->status;
660
661 bail_out:
662    mdb->status = (dbi_error_flag) dbi_conn_error(mdb->db,&errmsg);
663    //dbi_conn_error(mdb->db, &errmsg);
664    Dmsg4(500, "my_dbi_query we failed dbi error: "
665                    "'%s' '%p' '%d' flag '%d''\n", errmsg, mdb->result, mdb->result, mdb->status);
666    dbi_result_free(mdb->result);
667    mdb->result = NULL;
668    mdb->status = (dbi_error_flag) 1;                   /* failed */
669    return mdb->status;
670 }
671
672 void my_dbi_free_result(B_DB *mdb)
673 {
674
675    DBI_FIELD_GET *f;
676    db_lock(mdb);
677    if (mdb->result) {
678       Dmsg1(500, "my_dbi_free_result result '%p'\n", mdb->result);
679       dbi_result_free(mdb->result);
680    }
681
682    mdb->result = NULL;
683
684    if (mdb->row) {
685       free(mdb->row);
686    }
687
688    /* now is time to free all value return by my_dbi_get_value
689     * this is necessary because libdbi don't free memory return by yours results
690     * and Bacula has some routine wich call more than once time my_dbi_fetch_row
691     *
692     * Using a queue to store all pointer allocate is a good way to free all things
693     * when necessary
694     */
695    while((f=(DBI_FIELD_GET *)qremove(&dbi_getvalue_list))) {
696       Dmsg2(500, "my_dbi_free_result field value: '%p' in queue: '%p'\n", f->value, f);
697       free(f->value);
698       free(f);
699    }
700
701    mdb->row = NULL;
702
703    if (mdb->fields) {
704       free(mdb->fields);
705       mdb->fields = NULL;
706    }
707    db_unlock(mdb);
708    Dmsg0(500, "my_dbi_free_result finish\n");
709
710 }
711
712 const char *my_dbi_strerror(B_DB *mdb)
713 {
714    const char *errmsg;
715
716    dbi_conn_error(mdb->db, &errmsg);
717
718    return errmsg;
719 }
720
721 #ifdef HAVE_BATCH_FILE_INSERT
722
723 /*
724  * This can be a bit strang but is the one way to do
725  *
726  * Returns 1 if OK
727  *         0 if failed
728  */
729 int my_dbi_batch_start(JCR *jcr, B_DB *mdb)
730 {
731    char *query = "COPY batch FROM STDIN";
732
733    Dmsg0(500, "my_dbi_batch_start started\n");
734
735    switch (mdb->db_type) {
736    case SQL_TYPE_MYSQL:
737       db_lock(mdb);
738       if (my_dbi_query(mdb,
739                               "CREATE TEMPORARY TABLE batch ("
740                                   "FileIndex integer,"
741                                   "JobId integer,"
742                                   "Path blob,"
743                                   "Name blob,"
744                                   "LStat tinyblob,"
745                                   "MD5 tinyblob)") == 1)
746       {
747          Dmsg0(500, "my_dbi_batch_start failed\n");
748          return 1;
749       }
750       db_unlock(mdb);
751       Dmsg0(500, "my_dbi_batch_start finishing\n");
752       return 1;
753       break;
754    case SQL_TYPE_POSTGRESQL:
755
756       if (my_dbi_query(mdb, "CREATE TEMPORARY TABLE batch ("
757                                   "fileindex int,"
758                                   "jobid int,"
759                                   "path varchar,"
760                                   "name varchar,"
761                                   "lstat varchar,"
762                                   "md5 varchar)") == 1)
763       {
764          Dmsg0(500, "my_dbi_batch_start failed\n");
765          return 1;
766       }
767
768       // We are starting a new query.  reset everything.
769       mdb->num_rows     = -1;
770       mdb->row_number   = -1;
771       mdb->field_number = -1;
772
773       my_dbi_free_result(mdb);
774
775       for (int i=0; i < 10; i++) {
776          my_dbi_query(mdb, query);
777          if (mdb->result) {
778             break;
779          }
780          bmicrosleep(5, 0);
781       }
782       if (!mdb->result) {
783          Dmsg1(50, "Query failed: %s\n", query);
784          goto bail_out;
785       }
786
787       mdb->status = (dbi_error_flag)dbi_conn_error(mdb->db, NULL);
788       //mdb->status = DBI_ERROR_NONE;
789
790       if (mdb->status == DBI_ERROR_NONE) {
791          // how many fields in the set?
792          mdb->num_fields = dbi_result_get_numfields(mdb->result);
793          mdb->num_rows   = dbi_result_get_numrows(mdb->result);
794          mdb->status = (dbi_error_flag) 1;
795       } else {
796          Dmsg1(50, "Result status failed: %s\n", query);
797          goto bail_out;
798       }
799
800       Dmsg0(500, "my_postgresql_batch_start finishing\n");
801
802       return mdb->status;
803       break;
804    case SQL_TYPE_SQLITE:
805       db_lock(mdb);
806       if (my_dbi_query(mdb, "CREATE TEMPORARY TABLE batch ("
807                                   "FileIndex integer,"
808                                   "JobId integer,"
809                                   "Path blob,"
810                                   "Name blob,"
811                                   "LStat tinyblob,"
812                                   "MD5 tinyblob)") == 1)
813       {
814          Dmsg0(500, "my_dbi_batch_start failed\n");
815          goto bail_out;
816       }
817       db_unlock(mdb);
818       Dmsg0(500, "my_dbi_batch_start finishing\n");
819       return 1;
820       break;
821    case SQL_TYPE_SQLITE3:
822       db_lock(mdb);
823       if (my_dbi_query(mdb, "CREATE TEMPORARY TABLE batch ("
824                                   "FileIndex integer,"
825                                   "JobId integer,"
826                                   "Path blob,"
827                                   "Name blob,"
828                                   "LStat tinyblob,"
829                                   "MD5 tinyblob)") == 1)
830       {
831          Dmsg0(500, "my_dbi_batch_start failed\n");
832          goto bail_out;
833       }
834       db_unlock(mdb);
835       Dmsg0(500, "my_dbi_batch_start finishing\n");
836       return 1;
837       break;
838    }
839
840 bail_out:
841    Mmsg1(&mdb->errmsg, _("error starting batch mode: %s"), my_dbi_strerror(mdb));
842    mdb->status = (dbi_error_flag) 0;
843    my_dbi_free_result(mdb);
844    mdb->result = NULL;
845    return mdb->status;
846 }
847
848 /* set error to something to abort operation */
849 int my_dbi_batch_end(JCR *jcr, B_DB *mdb, const char *error)
850 {
851    int res = 0;
852    int count = 30;
853    int (*custom_function)(void*, const char*) = NULL;
854    dbi_conn_t *myconn = (dbi_conn_t *)(mdb->db);
855
856    Dmsg0(500, "my_dbi_batch_end started\n");
857
858    if (!mdb) {                  /* no files ? */
859       return 0;
860    }
861
862    switch (mdb->db_type) {
863    case SQL_TYPE_MYSQL:
864       if(mdb) {
865          mdb->status = (dbi_error_flag) 0;
866       }
867       break;
868    case SQL_TYPE_POSTGRESQL:
869       custom_function = (custom_function_end_t)dbi_driver_specific_function(dbi_conn_get_driver(mdb->db), "PQputCopyEnd");
870
871
872       do {
873          res = (*custom_function)(myconn->connection, error);
874       } while (res == 0 && --count > 0);
875
876       if (res == 1) {
877          Dmsg0(500, "ok\n");
878          mdb->status = (dbi_error_flag) 1;
879       }
880
881       if (res <= 0) {
882          Dmsg0(500, "we failed\n");
883          mdb->status = (dbi_error_flag) 0;
884          //Mmsg1(&mdb->errmsg, _("error ending batch mode: %s"), PQerrorMessage(mdb->db));
885        }
886       break;
887    case SQL_TYPE_SQLITE:
888       if(mdb) {
889          mdb->status = (dbi_error_flag) 0;
890       }
891       break;
892    case SQL_TYPE_SQLITE3:
893       if(mdb) {
894          mdb->status = (dbi_error_flag) 0;
895       }
896       break;
897    }
898
899    Dmsg0(500, "my_dbi_batch_end finishing\n");
900
901    return true;
902 }
903
904 /*
905  * This function is big and use a big switch.
906  * In near future is better split in small functions
907  * and refactory.
908  *
909  */
910 int my_dbi_batch_insert(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
911 {
912    int res;
913    int count=30;
914    dbi_conn_t *myconn = (dbi_conn_t *)(mdb->db);
915    int (*custom_function)(void*, const char*, int) = NULL;
916    char* (*custom_function_error)(void*) = NULL;
917    size_t len;
918    char *digest;
919    char ed1[50];
920
921    Dmsg0(500, "my_dbi_batch_insert started \n");
922
923    mdb->esc_name = check_pool_memory_size(mdb->esc_name, mdb->fnl*2+1);
924    mdb->esc_path = check_pool_memory_size(mdb->esc_path, mdb->pnl*2+1);
925
926    if (ar->Digest == NULL || ar->Digest[0] == 0) {
927       digest = "0";
928    } else {
929       digest = ar->Digest;
930    }
931
932    switch (mdb->db_type) {
933    case SQL_TYPE_MYSQL:
934       db_escape_string(jcr, mdb, mdb->esc_name, mdb->fname, mdb->fnl);
935       db_escape_string(jcr, mdb, mdb->esc_path, mdb->path, mdb->pnl);
936       len = Mmsg(mdb->cmd, "INSERT INTO batch VALUES (%u,%s,'%s','%s','%s','%s')",
937                       ar->FileIndex, edit_int64(ar->JobId,ed1), mdb->esc_path,
938                       mdb->esc_name, ar->attr, digest);
939
940       if (my_dbi_query(mdb,mdb->cmd) == 1)
941       {
942          Dmsg0(500, "my_dbi_batch_insert failed\n");
943          goto bail_out;
944       }
945
946       Dmsg0(500, "my_dbi_batch_insert finishing\n");
947
948       return 1;
949       break;
950    case SQL_TYPE_POSTGRESQL:
951       my_postgresql_copy_escape(mdb->esc_name, mdb->fname, mdb->fnl);
952       my_postgresql_copy_escape(mdb->esc_path, mdb->path, mdb->pnl);
953       len = Mmsg(mdb->cmd, "%u\t%s\t%s\t%s\t%s\t%s\n",
954                      ar->FileIndex, edit_int64(ar->JobId, ed1), mdb->esc_path,
955                      mdb->esc_name, ar->attr, digest);
956
957       /* libdbi don't support CopyData and we need call a postgresql
958        * specific function to do this work
959        */
960       Dmsg2(500, "my_dbi_batch_insert :\n %s \ncmd_size: %d",mdb->cmd, len);
961       if ((custom_function = (custom_function_insert_t)dbi_driver_specific_function(dbi_conn_get_driver(mdb->db),
962             "PQputCopyData")) != NULL) {
963          do {
964             res = (*custom_function)(myconn->connection, mdb->cmd, len);
965          } while (res == 0 && --count > 0);
966
967          if (res == 1) {
968             Dmsg0(500, "ok\n");
969             mdb->changes++;
970             mdb->status = (dbi_error_flag) 1;
971          }
972
973          if (res <= 0) {
974             Dmsg0(500, "my_dbi_batch_insert failed\n");
975             goto bail_out;
976          }
977
978          Dmsg0(500, "my_dbi_batch_insert finishing\n");
979          return mdb->status;
980       } else {
981          // ensure to detect a PQerror
982          custom_function_error = (custom_function_error_t)dbi_driver_specific_function(dbi_conn_get_driver(mdb->db), "PQerrorMessage");
983          Dmsg1(500, "my_dbi_batch_insert failed\n PQerrorMessage: %s", (*custom_function_error)(myconn->connection));
984          goto bail_out;
985       }
986       break;
987    case SQL_TYPE_SQLITE:
988       db_escape_string(jcr, mdb, mdb->esc_name, mdb->fname, mdb->fnl);
989       db_escape_string(jcr, mdb, mdb->esc_path, mdb->path, mdb->pnl);
990       len = Mmsg(mdb->cmd, "INSERT INTO batch VALUES (%u,%s,'%s','%s','%s','%s')",
991                       ar->FileIndex, edit_int64(ar->JobId,ed1), mdb->esc_path,
992                       mdb->esc_name, ar->attr, digest);
993       if (my_dbi_query(mdb,mdb->cmd) == 1)
994       {
995          Dmsg0(500, "my_dbi_batch_insert failed\n");
996          goto bail_out;
997       }
998
999       Dmsg0(500, "my_dbi_batch_insert finishing\n");
1000
1001       return 1;
1002       break;
1003    case SQL_TYPE_SQLITE3:
1004       db_escape_string(jcr, mdb, mdb->esc_name, mdb->fname, mdb->fnl);
1005       db_escape_string(jcr, mdb, mdb->esc_path, mdb->path, mdb->pnl);
1006       len = Mmsg(mdb->cmd, "INSERT INTO batch VALUES (%u,%s,'%s','%s','%s','%s')",
1007                       ar->FileIndex, edit_int64(ar->JobId,ed1), mdb->esc_path,
1008                       mdb->esc_name, ar->attr, digest);
1009       if (my_dbi_query(mdb,mdb->cmd) == 1)
1010       {
1011          Dmsg0(500, "my_dbi_batch_insert failed\n");
1012          goto bail_out;
1013       }
1014
1015       Dmsg0(500, "my_dbi_batch_insert finishing\n");
1016
1017       return 1;
1018       break;
1019    }
1020
1021 bail_out:
1022   Mmsg1(&mdb->errmsg, _("error inserting batch mode: %s"), my_dbi_strerror(mdb));
1023   mdb->status = (dbi_error_flag) 0;
1024   my_dbi_free_result(mdb);
1025   return mdb->status;
1026 }
1027
1028 /*
1029  * Escape strings so that PostgreSQL is happy on COPY
1030  *
1031  *   NOTE! len is the length of the old string. Your new
1032  *         string must be long enough (max 2*old+1) to hold
1033  *         the escaped output.
1034  */
1035 char *my_postgresql_copy_escape(char *dest, char *src, size_t len)
1036 {
1037    /* we have to escape \t, \n, \r, \ */
1038    char c = '\0' ;
1039
1040    while (len > 0 && *src) {
1041       switch (*src) {
1042       case '\n':
1043          c = 'n';
1044          break;
1045       case '\\':
1046          c = '\\';
1047          break;
1048       case '\t':
1049          c = 't';
1050          break;
1051       case '\r':
1052          c = 'r';
1053          break;
1054       default:
1055          c = '\0' ;
1056       }
1057
1058       if (c) {
1059          *dest = '\\';
1060          dest++;
1061          *dest = c;
1062       } else {
1063          *dest = *src;
1064       }
1065
1066       len--;
1067       src++;
1068       dest++;
1069    }
1070
1071    *dest = '\0';
1072    return dest;
1073 }
1074
1075 #endif /* HAVE_BATCH_FILE_INSERT */
1076
1077 /* my_dbi_getisnull
1078  * like PQgetisnull
1079  * int PQgetisnull(const PGresult *res,
1080  *              int row_number,
1081  *               int column_number);
1082  *
1083  *  use dbi_result_seek_row to search in result set
1084  */
1085 int my_dbi_getisnull(dbi_result *result, int row_number, int column_number) {
1086    int i;
1087
1088    if(row_number == 0) {
1089       row_number++;
1090    }
1091
1092    column_number++;
1093
1094    if(dbi_result_seek_row(result, row_number)) {
1095
1096       i = dbi_result_field_is_null_idx(result,column_number);
1097
1098       return i;
1099    } else {
1100
1101       return 0;
1102    }
1103
1104 }
1105 /* my_dbi_getvalue
1106  * like PQgetvalue;
1107  * char *PQgetvalue(const PGresult *res,
1108  *                int row_number,
1109  *                int column_number);
1110  *
1111  * use dbi_result_seek_row to search in result set
1112  * use example to return only strings
1113  */
1114 char *my_dbi_getvalue(dbi_result *result, int row_number, unsigned int column_number) {
1115
1116    char *buf = NULL;
1117    const char *errmsg;
1118    const char *field_name;
1119    unsigned short dbitype;
1120    size_t field_length;
1121    int64_t num;
1122
1123    /* correct the index for dbi interface
1124     * dbi index begins 1
1125     * I prefer do not change others functions
1126     */
1127    Dmsg3(600, "my_dbi_getvalue pre-starting result '%p' row number '%d' column number '%d'\n",
1128                                 result, row_number, column_number);
1129
1130    column_number++;
1131
1132    if(row_number == 0) {
1133      row_number++;
1134    }
1135
1136    Dmsg3(600, "my_dbi_getvalue starting result '%p' row number '%d' column number '%d'\n",
1137                         result, row_number, column_number);
1138
1139    if(dbi_result_seek_row(result, row_number)) {
1140
1141       field_name = dbi_result_get_field_name(result, column_number);
1142       field_length = dbi_result_get_field_length(result, field_name);
1143       dbitype = dbi_result_get_field_type_idx(result,column_number);
1144
1145       Dmsg3(500, "my_dbi_getvalue start: type: '%d' "
1146             "field_length bytes: '%d' fieldname: '%s'\n",
1147             dbitype, field_length, field_name);
1148
1149       if(field_length) {
1150          //buf = (char *)malloc(sizeof(char *) * field_length + 1);
1151          buf = (char *)malloc(field_length + 1);
1152       } else {
1153          /* if numbers */
1154          buf = (char *)malloc(sizeof(char *) * 50);
1155       }
1156
1157       switch (dbitype) {
1158       case DBI_TYPE_INTEGER:
1159          num = dbi_result_get_longlong(result, field_name);
1160          edit_int64(num, buf);
1161          field_length = strlen(buf);
1162          break;
1163       case DBI_TYPE_STRING:
1164          if(field_length) {
1165             field_length = bsnprintf(buf, field_length + 1, "%s",
1166             dbi_result_get_string(result, field_name));
1167          } else {
1168             buf[0] = 0;
1169          }
1170          break;
1171       case DBI_TYPE_BINARY:
1172          /* dbi_result_get_binary return a NULL pointer if value is empty
1173          * following, change this to what Bacula espected
1174          */
1175          if(field_length) {
1176             field_length = bsnprintf(buf, field_length + 1, "%s",
1177                   dbi_result_get_binary(result, field_name));
1178          } else {
1179             buf[0] = 0;
1180          }
1181          break;
1182       case DBI_TYPE_DATETIME:
1183          time_t last;
1184          struct tm tm;
1185
1186          last = dbi_result_get_datetime(result, field_name);
1187
1188          if(last == -1) {
1189                 field_length = bsnprintf(buf, 20, "0000-00-00 00:00:00");
1190          } else {
1191             (void)localtime_r(&last, &tm);
1192             field_length = bsnprintf(buf, 20, "%04d-%02d-%02d %02d:%02d:%02d",
1193                   (tm.tm_year + 1900), (tm.tm_mon + 1), tm.tm_mday,
1194                   tm.tm_hour, tm.tm_min, tm.tm_sec);
1195          }
1196          break;
1197       }
1198
1199    } else {
1200       dbi_conn_error(dbi_result_get_conn(result), &errmsg);
1201       Dmsg1(500, "my_dbi_getvalue error: %s\n", errmsg);
1202    }
1203
1204    Dmsg3(500, "my_dbi_getvalue finish buffer: '%p' num bytes: '%d' data: '%s'\n",
1205       buf, field_length, buf);
1206
1207    // don't worry about this buf
1208    return buf;
1209 }
1210
1211 int my_dbi_sql_insert_id(B_DB *mdb, char *table_name)
1212 {
1213    /*
1214     Obtain the current value of the sequence that
1215     provides the serial value for primary key of the table.
1216
1217     currval is local to our session.  It is not affected by
1218     other transactions.
1219
1220     Determine the name of the sequence.
1221     PostgreSQL automatically creates a sequence using
1222     <table>_<column>_seq.
1223     At the time of writing, all tables used this format for
1224     for their primary key: <table>id
1225     Except for basefiles which has a primary key on baseid.
1226     Therefore, we need to special case that one table.
1227
1228     everything else can use the PostgreSQL formula.
1229    */
1230
1231    char      sequence[30];
1232    uint64_t    id = 0;
1233
1234    if (mdb->db_type == SQL_TYPE_POSTGRESQL) {
1235
1236       if (strcasecmp(table_name, "basefiles") == 0) {
1237          bstrncpy(sequence, "basefiles_baseid", sizeof(sequence));
1238       } else {
1239          bstrncpy(sequence, table_name, sizeof(sequence));
1240          bstrncat(sequence, "_",        sizeof(sequence));
1241          bstrncat(sequence, table_name, sizeof(sequence));
1242          bstrncat(sequence, "id",       sizeof(sequence));
1243       }
1244
1245       bstrncat(sequence, "_seq", sizeof(sequence));
1246       id = dbi_conn_sequence_last(mdb->db, NT_(sequence));
1247    } else {
1248       id = dbi_conn_sequence_last(mdb->db, NT_(table_name));
1249    }
1250
1251    return id;
1252 }
1253
1254 #ifdef HAVE_BATCH_FILE_INSERT
1255 const char *my_dbi_batch_lock_path_query[4] = {
1256    /* Mysql */
1257    "LOCK TABLES Path write, batch write, Path as p write",
1258    /* Postgresql */
1259    "BEGIN; LOCK TABLE Path IN SHARE ROW EXCLUSIVE MODE",
1260    /* SQLite */
1261    "BEGIN",
1262    /* SQLite3 */
1263    "BEGIN"};
1264
1265 const char *my_dbi_batch_lock_filename_query[4] = {
1266    /* Mysql */
1267    "LOCK TABLES Filename write, batch write, Filename as f write",
1268    /* Postgresql */
1269    "BEGIN; LOCK TABLE Filename IN SHARE ROW EXCLUSIVE MODE",
1270    /* SQLite */
1271    "BEGIN",
1272    /* SQLite3 */
1273    "BEGIN"};
1274
1275 const char *my_dbi_batch_unlock_tables_query[4] = {
1276    /* Mysql */
1277    "UNLOCK TABLES",
1278    /* Postgresql */
1279    "COMMIT",
1280    /* SQLite */
1281    "COMMIT",
1282    /* SQLite3 */
1283    "COMMIT"};
1284
1285 const char *my_dbi_match[4] = {
1286    /* Mysql */
1287    "MATCH",
1288    /* Postgresql */
1289    "~",
1290    /* SQLite */
1291    "MATCH",
1292    /* SQLite3 */
1293    "MATCH"
1294 };
1295
1296 const char *my_dbi_batch_fill_path_query[4] = {
1297    /* Mysql */
1298    "INSERT INTO Path (Path) "
1299    "SELECT a.Path FROM "
1300    "(SELECT DISTINCT Path FROM batch) AS a WHERE NOT EXISTS "
1301    "(SELECT Path FROM Path AS p WHERE p.Path = a.Path)",
1302    /* Postgresql */
1303    "INSERT INTO Path (Path) "
1304    "SELECT a.Path FROM "
1305    "(SELECT DISTINCT Path FROM batch) AS a "
1306    "WHERE NOT EXISTS (SELECT Path FROM Path WHERE Path = a.Path) ",
1307    /* SQLite */
1308    "INSERT INTO Path (Path)"
1309    " SELECT DISTINCT Path FROM batch"
1310    " EXCEPT SELECT Path FROM Path",
1311    /* SQLite3 */
1312    "INSERT INTO Path (Path)"
1313    " SELECT DISTINCT Path FROM batch"
1314    " EXCEPT SELECT Path FROM Path"};
1315
1316 const char *my_dbi_batch_fill_filename_query[4] = {
1317    /* Mysql */
1318    "INSERT INTO Filename (Name) "
1319    "SELECT a.Name FROM "
1320    "(SELECT DISTINCT Name FROM batch) AS a WHERE NOT EXISTS "
1321    "(SELECT Name FROM Filename AS f WHERE f.Name = a.Name)",
1322    /* Postgresql */
1323    "INSERT INTO Filename (Name) "
1324    "SELECT a.Name FROM "
1325    "(SELECT DISTINCT Name FROM batch) as a "
1326    "WHERE NOT EXISTS "
1327    "(SELECT Name FROM Filename WHERE Name = a.Name)",
1328    /* SQLite */
1329    "INSERT INTO Filename (Name)"
1330    " SELECT DISTINCT Name FROM batch "
1331    " EXCEPT SELECT Name FROM Filename",
1332    /* SQLite3 */
1333    "INSERT INTO Filename (Name)"
1334    " SELECT DISTINCT Name FROM batch "
1335    " EXCEPT SELECT Name FROM Filename"};
1336
1337 #endif /* HAVE_BATCH_FILE_INSERT */
1338
1339 #endif /* HAVE_DBI */