]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/cats/postgresql.c
Add second COALESCE to sql_find -- thanks to JML
[bacula/bacula] / bacula / src / cats / postgresql.c
index c502330fc6304227f036cb3ec93f8aa4435de990..91b4493743c9973da88369173b8f5bb850b504cd 100644 (file)
@@ -9,7 +9,7 @@
  */
 
 /*
-   Copyright (C) 2000-2003 Kern Sibbald and John Walker
+   Copyright (C) 2000-2004 Kern Sibbald and John Walker
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -95,7 +95,7 @@ db_init_database(JCR *jcr, char *db_name, char *db_user, char *db_password,
    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 */
+   mdb->cmd               = get_pool_memory(PM_EMSG); /* get command buffer */
    mdb->cached_path    = get_pool_memory(PM_FNAME);
    mdb->cached_path_id = 0;
    mdb->ref_count      = 1;
@@ -109,7 +109,9 @@ db_init_database(JCR *jcr, char *db_name, char *db_user, char *db_password,
 
 /*
  * Now actually open the database.  This can generate errors,
- * which are returned in the errmsg
+ *   which are returned in the errmsg
+ *
+ * DO NOT close the database or free(mdb) here !!!!
  */
 int
 db_open_database(JCR *jcr, B_DB *mdb)
@@ -160,14 +162,13 @@ db_open_database(JCR *jcr, B_DB *mdb)
       Mmsg2(&mdb->errmsg, _("Unable to connect to PostgreSQL server.\n"
             "Database=%s User=%s\n"
             "It is probably not running or your password is incorrect.\n"),
-           mdb->db_name, mdb->db_user);
+            mdb->db_name, mdb->db_user);
       V(mutex);
       return 0;
    }
 
    if (!check_tables_version(jcr, mdb)) {
       V(mutex);
-      db_close_database(jcr, mdb);
       return 0;
    }
 
@@ -179,6 +180,9 @@ db_open_database(JCR *jcr, B_DB *mdb)
 void
 db_close_database(JCR *jcr, B_DB *mdb)
 {
+   if (!mdb) {
+      return;
+   }
    P(mutex);
    mdb->ref_count--;
    if (mdb->ref_count == 0) {
@@ -269,10 +273,10 @@ int db_sql_query(B_DB *mdb, char *query, DB_RESULT_HANDLER *result_handler, void
 
             Dmsg0(50, "db_sql_query sql_fetch_row worked\n");
            if (result_handler(ctx, num_fields, row))
-                  break;
+              break;
         }
 
-        sql_free_result(mdb);
+       sql_free_result(mdb);
       }
    }
    db_unlock(mdb);
@@ -328,29 +332,57 @@ POSTGRESQL_ROW my_postgresql_fetch_row(B_DB *mdb)
        return row;
 }
 
-POSTGRESQL_FIELD * my_postgresql_fetch_field(B_DB *mdb) 
-{
-       mdb->field.name       = PQfname    (mdb->result, mdb->field_number);
-
-       // I am not sure this returns the max width of the result set
-       mdb->field.max_length = PQfsize    (mdb->result, mdb->field_number);
-
-       // I am not sure this returns what we can use
-       mdb->field.type       = PQftype    (mdb->result, mdb->field_number);
-
-//     if (mdb->num_rows > 0) {
-//              Dmsg1(50, "asking for information on field '%d' type='%d' and IsNull=%d\n",
-//             mdb->field.flags  = PQgetisnull(mdb->result, mdb->row_number, mdb->field_number);
-//     }
-       mdb->field.flags = 0;
-
-        Dmsg4(50, "my_postgresql_fetch_field finds field '%s' has length='%d' type='%d' and IsNull=%d\n", 
-               mdb->field.name, mdb->field.max_length, mdb->field.type, mdb->field.flags);
+int my_postgresql_max_length(B_DB *mdb, int field_num) {
+       //
+       // for a given column, find the max length
+       //
+       int     max_length;
+       int i;
+       int     this_length;
+
+       max_length = 0;
+       for (i = 0; i < mdb->num_rows; i++) {
+               if (PQgetisnull(mdb->result, i, field_num)) {
+                        this_length = 4;        // "NULL"
+               } else {
+                       this_length = strlen(PQgetvalue(mdb->result, i, field_num));
+               }
+                               
+               if (max_length < this_length) {
+                       max_length = this_length;
+               }
+       }
 
-       // increment this for the next time around
-       mdb->field_number++;
+       return max_length;
+}
 
-       return &mdb->field;
+POSTGRESQL_FIELD * my_postgresql_fetch_field(B_DB *mdb) 
+{
+       int     i;
+
+        Dmsg0(50, "my_postgresql_fetch_field starts\n");
+       if (mdb->fields == NULL) {
+                Dmsg1(50, "allocating space for %d fields\n", mdb->num_fields);
+               mdb->fields = (POSTGRESQL_FIELD *)
+                                malloc(sizeof(POSTGRESQL_FIELD) * mdb->num_fields);
+
+               for (i = 0; i < mdb->num_fields; i++) {
+                        Dmsg1(50, "filling field %d\n", i);
+                       mdb->fields[i].name           = PQfname(mdb->result, i);
+                       mdb->fields[i].max_length = my_postgresql_max_length(mdb, i);
+                       mdb->fields[i].type       = PQftype(mdb->result, i);
+                       mdb->fields[i].flags      = 0;
+
+                        Dmsg4(50, "my_postgresql_fetch_field finds field '%s' has length='%d' type='%d' and IsNull=%d\n", 
+                          mdb->fields[i].name, mdb->fields[i].max_length, mdb->fields[i].type,
+                          mdb->fields[i].flags);
+               } // end for
+       } // end if
+
+       // increment field number for the next time around
+
+        Dmsg0(50, "my_postgresql_fetch_field finishes\n");
+       return &mdb->fields[mdb->field_number++];
 }
 
 void my_postgresql_data_seek(B_DB *mdb, int row) 
@@ -361,7 +393,7 @@ void my_postgresql_data_seek(B_DB *mdb, int row)
 }
 
 void my_postgresql_field_seek(B_DB *mdb, int field)
- {
+{
        mdb->field_number = field;
 }
 
@@ -407,6 +439,11 @@ void my_postgresql_free_result (B_DB *mdb)
                free(mdb->row);
                mdb->row = NULL;
        }
+
+       if (mdb->fields) {
+               free(mdb->fields);
+               mdb->fields = NULL;
+       }
 }
 
 int my_postgresql_currval(B_DB *mdb, char *table_name) 
@@ -429,7 +466,6 @@ int my_postgresql_currval(B_DB *mdb, char *table_name)
 
        char      sequence[NAMEDATALEN-1];
        char      query   [NAMEDATALEN+50];
-//     POOLMEM  *query;
        PGresult *result;
        int       id = 0;
 
@@ -459,7 +495,6 @@ int my_postgresql_currval(B_DB *mdb, char *table_name)
                 Mmsg1(&mdb->errmsg, _("error fetching currval: %s\n"), PQerrorMessage(mdb->db));
        }
 
-//     free_pool_memory(query);
        PQclear(result);
 
        return id;