]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/cats/sql.c
Update version date
[bacula/bacula] / bacula / src / cats / sql.c
index 8c1105d2c69f0e79d6d64bbfbca7e0ca3bad6db0..2c4fa431eea984f7731af79abf59191dac2725d6 100644 (file)
@@ -99,6 +99,21 @@ int db_int64_handler(void *ctx, int num_fields, char **row)
    return 0;
 }
 
+/*
+ * Called here to retrieve a btime from the database.
+ *   The returned integer will be extended to 64 bit.
+ */
+int db_strtime_handler(void *ctx, int num_fields, char **row)
+{
+   db_int64_ctx *lctx = (db_int64_ctx *)ctx;
+
+   if (row[0]) {
+      lctx->value = str_to_utime(row[0]);
+      lctx->count++;
+   }
+   return 0;
+}
+
 /*
  * Use to build a comma separated list of values from a query. "10,20,30"
  */
@@ -106,27 +121,23 @@ int db_list_handler(void *ctx, int num_fields, char **row)
 {
    db_list_ctx *lctx = (db_list_ctx *)ctx;
    if (num_fields == 1 && row[0]) {
-      if (lctx->list[0]) {
-         pm_strcat(lctx->list, ",");
-      }
-      pm_strcat(lctx->list, row[0]);
-      lctx->count++;
+      lctx->add(row[0]);
    }
    return 0;
 }
 
 /*
- *  * specific context passed from db_check_max_connections to db_max_connections_handler.
- *   */
+ * specific context passed from db_check_max_connections to db_max_connections_handler.
+ */
 struct max_connections_context {
    B_DB *db;
    uint32_t nr_connections;
 };
 
 /*
- *  * Called here to retrieve an integer from the database
- *   */
-static int db_max_connections_handler(void *ctx, int num_fields, char **row)
+ * Called here to retrieve an integer from the database
+ */
+static inline int db_max_connections_handler(void *ctx, int num_fields, char **row)
 {
    struct max_connections_context *context;
    uint32_t index;
@@ -149,8 +160,8 @@ static int db_max_connections_handler(void *ctx, int num_fields, char **row)
 }
 
 /*
- *  * Check catalog max_connections setting
- *   */
+ * Check catalog max_connections setting
+ */
 bool db_check_max_connections(JCR *jcr, B_DB *mdb, uint32_t max_concurrent_jobs)
 {
    struct max_connections_context context;
@@ -289,7 +300,8 @@ UpdateDB(const char *file, int line, JCR *jcr, B_DB *mdb, char *cmd)
    return 1;
 }
 
-/* Utility routine for deletes
+/*
+ * Utility routine for deletes
  *
  * Returns: -1 on error
  *           n number of rows affected
@@ -339,8 +351,8 @@ int get_sql_record_max(JCR *jcr, B_DB *mdb)
 }
 
 /*
- *  * Return pre-edited error message
- *   */
+ * Return pre-edited error message
+ */
 char *db_strerror(B_DB *mdb)
 {
    return mdb->errmsg;
@@ -420,16 +432,17 @@ static int max_length(int max_length)
 /*
  * List dashes as part of header for listing SQL results in a table
  */
-void
-list_dashes(B_DB *mdb, DB_LIST_HANDLER *send, void *ctx)
+void list_dashes(B_DB *mdb, DB_LIST_HANDLER *send, void *ctx)
 {
    SQL_FIELD  *field;
    int i, j;
    int len;
+   int num_fields;
 
    sql_field_seek(mdb, 0);
    send(ctx, "+");
-   for (i = 0; i < sql_num_fields(mdb); i++) {
+   num_fields = sql_num_fields(mdb);
+   for (i = 0; i < num_fields; i++) {
       field = sql_fetch_field(mdb);
       if (!field) {
          break;
@@ -454,6 +467,7 @@ int list_result(void *vctx, int nb_col, char **row)
 {
    SQL_FIELD *field;
    int i, col_len, max_len = 0;
+   int num_fields;
    char buf[2000], ewc[30];
 
    LIST_CTX *pctx = (LIST_CTX *)vctx;
@@ -463,13 +477,14 @@ int list_result(void *vctx, int nb_col, char **row)
    void *ctx = pctx->ctx;
    JCR *jcr = pctx->jcr;
 
+   num_fields = sql_num_fields(mdb);
    if (!pctx->once) {
       pctx->once = true;
 
-      Dmsg1(800, "list_result starts looking at %d fields\n", sql_num_fields(mdb));
+      Dmsg1(800, "list_result starts looking at %d fields\n", num_fields);
       /* determine column display widths */
       sql_field_seek(mdb, 0);
-      for (i = 0; i < sql_num_fields(mdb); i++) {
+      for (i = 0; i < num_fields; i++) {
          Dmsg1(800, "list_result processing field %d\n", i);
          field = sql_fetch_field(mdb);
          if (!field) {
@@ -501,8 +516,7 @@ int list_result(void *vctx, int nb_col, char **row)
          goto vertical_list;
       }
 
-      Dmsg1(800, "list_result starts second loop looking at %d fields\n", 
-            sql_num_fields(mdb));
+      Dmsg1(800, "list_result starts second loop looking at %d fields\n", num_fields);
 
       /* Keep the result to display the same line at the end of the table */
       list_dashes(mdb, last_line_handler, pctx);
@@ -510,7 +524,7 @@ int list_result(void *vctx, int nb_col, char **row)
 
       send(ctx, "|");
       sql_field_seek(mdb, 0);
-      for (i = 0; i < sql_num_fields(mdb); i++) {
+      for (i = 0; i < num_fields; i++) {
          Dmsg1(800, "list_result looking at field %d\n", i);
          field = sql_fetch_field(mdb);
          if (!field) {
@@ -524,12 +538,11 @@ int list_result(void *vctx, int nb_col, char **row)
       list_dashes(mdb, send, ctx);      
    }
    
-   Dmsg1(800, "list_result starts third loop looking at %d fields\n", 
-         sql_num_fields(mdb));
+   Dmsg1(800, "list_result starts third loop looking at %d fields\n", num_fields);
 
    sql_field_seek(mdb, 0);
    send(ctx, "|");
-   for (i = 0; i < sql_num_fields(mdb); i++) {
+   for (i = 0; i < num_fields; i++) {
       field = sql_fetch_field(mdb);
       if (!field) {
          break;
@@ -550,10 +563,10 @@ int list_result(void *vctx, int nb_col, char **row)
 
 vertical_list:
 
-   Dmsg1(800, "list_result starts vertical list at %d fields\n", sql_num_fields(mdb));
+   Dmsg1(800, "list_result starts vertical list at %d fields\n", num_fields);
 
    sql_field_seek(mdb, 0);
-   for (i = 0; i < sql_num_fields(mdb); i++) {
+   for (i = 0; i < num_fields; i++) {
       field = sql_fetch_field(mdb);
       if (!field) {
          break;
@@ -572,6 +585,126 @@ vertical_list:
    return 0;
 }
 
+/*
+ * If full_list is set, we list vertically, otherwise, we
+ *  list on one line horizontally.
+ * Return number of rows
+ */
+int list_result(JCR *jcr, B_DB *mdb, DB_LIST_HANDLER *send, void *ctx, e_list_type type)
+{
+   SQL_FIELD *field;
+   SQL_ROW row;
+   int i, col_len, max_len = 0;
+   int num_fields;
+   char buf[2000], ewc[30];
+
+   Dmsg0(800, "list_result starts\n");
+   if (sql_num_rows(mdb) == 0) {
+      send(ctx, _("No results to list.\n"));
+      return sql_num_rows(mdb);
+   }
+
+   num_fields = sql_num_fields(mdb);
+   Dmsg1(800, "list_result starts looking at %d fields\n", num_fields);
+   /* determine column display widths */
+   sql_field_seek(mdb, 0);
+   for (i = 0; i < num_fields; i++) {
+      Dmsg1(800, "list_result processing field %d\n", i);
+      field = sql_fetch_field(mdb);
+      if (!field) {
+         break;
+      }
+      col_len = cstrlen(field->name);
+      if (type == VERT_LIST) {
+         if (col_len > max_len) {
+            max_len = col_len;
+         }
+      } else {
+         if (sql_field_is_numeric(mdb, field->type) && (int)field->max_length > 0) { /* fixup for commas */
+            field->max_length += (field->max_length - 1) / 3;
+         }  
+         if (col_len < (int)field->max_length) {
+            col_len = field->max_length;
+         }  
+         if (col_len < 4 && !sql_field_is_not_null(mdb, field->flags)) {
+            col_len = 4;                 /* 4 = length of the word "NULL" */
+         }
+         field->max_length = col_len;    /* reset column info */
+      }
+   }
+
+   Dmsg0(800, "list_result finished first loop\n");
+   if (type == VERT_LIST) {
+      goto vertical_list;
+   }
+
+   Dmsg1(800, "list_result starts second loop looking at %d fields\n", num_fields);
+   list_dashes(mdb, send, ctx);
+   send(ctx, "|");
+   sql_field_seek(mdb, 0);
+   for (i = 0; i < num_fields; i++) {
+      Dmsg1(800, "list_result looking at field %d\n", i);
+      field = sql_fetch_field(mdb);
+      if (!field) {
+         break;
+      }
+      max_len = max_length(field->max_length);
+      bsnprintf(buf, sizeof(buf), " %-*s |", max_len, field->name);
+      send(ctx, buf);
+   }
+   send(ctx, "\n");
+   list_dashes(mdb, send, ctx);
+
+   Dmsg1(800, "list_result starts third loop looking at %d fields\n", num_fields);
+   while ((row = sql_fetch_row(mdb)) != NULL) {
+      sql_field_seek(mdb, 0);
+      send(ctx, "|");
+      for (i = 0; i < num_fields; i++) {
+         field = sql_fetch_field(mdb);
+         if (!field) {
+            break;
+         }
+         max_len = max_length(field->max_length);
+         if (row[i] == NULL) {
+            bsnprintf(buf, sizeof(buf), " %-*s |", max_len, "NULL");
+         } else if (sql_field_is_numeric(mdb, field->type) && !jcr->gui && is_an_integer(row[i])) {
+            bsnprintf(buf, sizeof(buf), " %*s |", max_len,
+                      add_commas(row[i], ewc));
+         } else {
+            bsnprintf(buf, sizeof(buf), " %-*s |", max_len, row[i]);
+         }
+         send(ctx, buf);
+      }
+      send(ctx, "\n");
+   }
+   list_dashes(mdb, send, ctx);
+   return sql_num_rows(mdb);
+
+vertical_list:
+
+   Dmsg1(800, "list_result starts vertical list at %d fields\n", num_fields);
+   while ((row = sql_fetch_row(mdb)) != NULL) {
+      sql_field_seek(mdb, 0);
+      for (i = 0; i < num_fields; i++) {
+         field = sql_fetch_field(mdb);
+         if (!field) {
+            break;
+         }
+         if (row[i] == NULL) {
+            bsnprintf(buf, sizeof(buf), " %*s: %s\n", max_len, field->name, "NULL");
+         } else if (sql_field_is_numeric(mdb, field->type) && !jcr->gui && is_an_integer(row[i])) {
+            bsnprintf(buf, sizeof(buf), " %*s: %s\n", max_len, field->name,
+                add_commas(row[i], ewc));
+         } else {
+            bsnprintf(buf, sizeof(buf), " %*s: %s\n", max_len, field->name, row[i]);
+         }
+         send(ctx, buf);
+      }
+      send(ctx, "\n");
+   }
+   return sql_num_rows(mdb);
+}
+
 /* 
  * Open a new connexion to mdb catalog. This function is used
  * by batch and accurate mode.