]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/cats/sql.c
Fix get_basename() -- rewrite
[bacula/bacula] / bacula / src / cats / sql.c
index 4efc0e813d46e69d10d237782c59eb2bb75b6b8c..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;
@@ -443,28 +456,159 @@ list_dashes(B_DB *mdb, DB_LIST_HANDLER *send, void *ctx)
    send(ctx, "\n");
 }
 
+/* Small handler to print the last line of a list xxx command */
+static void last_line_handler(void *vctx, const char *str)
+{
+   LIST_CTX *ctx = (LIST_CTX *)vctx;
+   bstrncat(ctx->line, str, sizeof(ctx->line));
+}
+
+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;
+   DB_LIST_HANDLER *send = pctx->send;
+   e_list_type type = pctx->type;
+   B_DB *mdb = pctx->mdb;
+   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", 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 */
+         }
+      }
+
+      pctx->num_rows++;
+
+      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);
+
+      /* Keep the result to display the same line at the end of the table */
+      list_dashes(mdb, last_line_handler, pctx);
+      send(ctx, pctx->line);
+
+      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);
+
+   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");
+   return 0;
+
+vertical_list:
+
+   Dmsg1(800, "list_result starts vertical list at %d fields\n", num_fields);
+
+   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 0;
+}
+
 /*
  * If full_list is set, we list vertically, otherwise, we
- * list on one line horizontally.
+ *  list on one line horizontally.
+ * Return number of rows
  */
-void
-list_result(JCR *jcr, B_DB *mdb, DB_LIST_HANDLER *send, void *ctx, e_list_type type)
+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;
+      return sql_num_rows(mdb);
    }
 
-   Dmsg1(800, "list_result starts looking at %d fields\n", sql_num_fields(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 < 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) {
@@ -494,11 +638,11 @@ list_result(JCR *jcr, B_DB *mdb, DB_LIST_HANDLER *send, void *ctx, e_list_type t
       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);
    list_dashes(mdb, send, ctx);
    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) {
@@ -511,11 +655,11 @@ list_result(JCR *jcr, B_DB *mdb, DB_LIST_HANDLER *send, void *ctx, e_list_type t
    send(ctx, "\n");
    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);
    while ((row = sql_fetch_row(mdb)) != NULL) {
       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;
@@ -534,14 +678,14 @@ list_result(JCR *jcr, B_DB *mdb, DB_LIST_HANDLER *send, void *ctx, e_list_type t
       send(ctx, "\n");
    }
    list_dashes(mdb, send, ctx);
-   return;
+   return sql_num_rows(mdb);
 
 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);
    while ((row = sql_fetch_row(mdb)) != NULL) {
       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;
@@ -558,7 +702,7 @@ vertical_list:
       }
       send(ctx, "\n");
    }
-   return;
+   return sql_num_rows(mdb);
 }
 
 /*