aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog.txt3
-rw-r--r--pseudo_db.c162
-rw-r--r--pseudo_db.h3
-rw-r--r--pseudolog.c20
4 files changed, 111 insertions, 77 deletions
diff --git a/ChangeLog.txt b/ChangeLog.txt
index 5ec17c9..09f3a33 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -1,3 +1,6 @@
+2010-04-30:
+ * (seebs) rework pdb_history
+
2010-04-27:
* (seebs) fix -P in pseudolog
* (seebs) document PSEUDO_DEBUG_FILE
diff --git a/pseudo_db.c b/pseudo_db.c
index e4047fa..3839581 100644
--- a/pseudo_db.c
+++ b/pseudo_db.c
@@ -886,11 +886,10 @@ frag(buffer *b, char *fmt, ...) {
return rc;
}
-log_history
-pdb_history(pseudo_query_t *traits, unsigned long fields, int unique, int do_delete) {
- log_history h = NULL;
+sqlite3_stmt *
+pdb_query(char *stmt_type, pseudo_query_t *traits, unsigned long fields, int unique, int want_results) {
pseudo_query_t *trait;
- sqlite3_stmt *select;
+ sqlite3_stmt *stmt;
int done_any = 0;
int field = 0;
char *order_by = "id";
@@ -899,32 +898,35 @@ pdb_history(pseudo_query_t *traits, unsigned long fields, int unique, int do_del
pseudo_query_field_t f;
static buffer *sql;
+ if (!log_db && get_db(&log_db)) {
+ pseudo_diag("database error.\n");
+ return NULL;
+ }
+
+ if (!stmt_type) {
+ pseudo_diag("can't prepare a statement without a type.\n");
+ }
+
if (!sql) {
sql = malloc(sizeof *sql);
if (!sql) {
pseudo_diag("can't allocate SQL buffer.\n");
- return 0;
+ return NULL;
}
sql->buflen = 512;
sql->data = malloc(sql->buflen);
if (!sql->data) {
pseudo_diag("can't allocate SQL text buffer.\n");
free(sql);
- return 0;
+ sql = 0;
+ return NULL;
}
}
sql->tail = sql->data;
- if (do_delete)
- frag(sql, "DELETE ");
- else
- frag(sql, "SELECT ");
+ /* should be DELETE or SELECT */
+ frag(sql, "%s ", stmt_type);
- if (!log_db && get_db(&log_db)) {
- pseudo_diag("database error.\n");
- return 0;
- }
-
- if (!do_delete) {
+ if (want_results) {
if (unique)
frag(sql, "DISTINCT ");
@@ -952,9 +954,9 @@ pdb_history(pseudo_query_t *traits, unsigned long fields, int unique, int do_del
}
}
switch (trait->field) {
- case PSQF_PROGRAM: /* FALLTHROUGH */
- case PSQF_TEXT: /* FALLTHROUGH */
- case PSQF_TAG: /* FALLTHROUGH */
+ case PSQF_PROGRAM:
+ case PSQF_TEXT:
+ case PSQF_TAG:
case PSQF_PATH:
switch (trait->type) {
case PSQT_LIKE:
@@ -962,7 +964,7 @@ pdb_history(pseudo_query_t *traits, unsigned long fields, int unique, int do_del
pseudo_query_field_name(trait->field),
pseudo_query_type_sql(trait->type));
break;
- case PSQT_NOTLIKE: /* FALLTHROUGH */
+ case PSQT_NOTLIKE:
case PSQT_SQLPAT:
frag(sql, "%s %s ?",
pseudo_query_field_name(trait->field),
@@ -977,8 +979,8 @@ pdb_history(pseudo_query_t *traits, unsigned long fields, int unique, int do_del
break;
case PSQF_PERM:
switch (trait->type) {
- case PSQT_LIKE: /* FALLTHROUGH */
- case PSQT_NOTLIKE: /* FALLTHROUGH */
+ case PSQT_LIKE:
+ case PSQT_NOTLIKE:
case PSQT_SQLPAT:
pseudo_diag("Error: Can't use a LIKE match on non-text fields.\n");
return 0;
@@ -994,8 +996,8 @@ pdb_history(pseudo_query_t *traits, unsigned long fields, int unique, int do_del
break;
case PSQF_FTYPE:
switch (trait->type) {
- case PSQT_LIKE: /* FALLTHROUGH */
- case PSQT_NOTLIKE: /* FALLTHROUGH */
+ case PSQT_LIKE:
+ case PSQT_NOTLIKE:
case PSQT_SQLPAT:
pseudo_diag("Error: Can't use a LIKE match on non-text fields.\n");
return 0;
@@ -1015,7 +1017,7 @@ pdb_history(pseudo_query_t *traits, unsigned long fields, int unique, int do_del
case PSQT_LESS:
order_dir = "DESC";
break;
- case PSQT_EXACT: /* FALLTHROUGH */
+ case PSQT_EXACT:
/* this was already the default */
break;
case PSQT_GREATER:
@@ -1029,8 +1031,8 @@ pdb_history(pseudo_query_t *traits, unsigned long fields, int unique, int do_del
break;
default:
switch (trait->type) {
- case PSQT_LIKE: /* FALLTHROUGH */
- case PSQT_NOTLIKE: /* FALLTHROUGH */
+ case PSQT_LIKE:
+ case PSQT_NOTLIKE:
case PSQT_SQLPAT:
pseudo_diag("Error: Can't use a LIKE match on non-text fields.\n");
return 0;
@@ -1044,15 +1046,15 @@ pdb_history(pseudo_query_t *traits, unsigned long fields, int unique, int do_del
break;
}
}
- if (!do_delete)
+ if (want_results)
frag(sql, "ORDER BY %s %s;", order_by, order_dir);
pseudo_debug(1, "created SQL: <%s>\n", sql->data);
/* second, prepare it */
- rc = sqlite3_prepare_v2(log_db, sql->data, strlen(sql->data), &select, NULL);
+ rc = sqlite3_prepare_v2(log_db, sql->data, strlen(sql->data), &stmt, NULL);
if (rc) {
- dberr(log_db, "couldn't prepare %s statement", do_delete ? "DELETE" : "SELECT");
- return 0;
+ dberr(log_db, "couldn't prepare %s statement", stmt_type);
+ return NULL;
}
/* third, bind the fields */
@@ -1062,60 +1064,84 @@ pdb_history(pseudo_query_t *traits, unsigned long fields, int unique, int do_del
case PSQF_ORDER:
/* this just creates a hunk of SQL above */
break;
- case PSQF_PROGRAM: /* FALLTHROUGH */
- case PSQF_PATH: /* FALLTHROUGH */
- case PSQF_TAG: /* FALLTHROUGH */
+ case PSQF_PROGRAM:
+ case PSQF_PATH:
+ case PSQF_TAG:
case PSQF_TEXT:
- sqlite3_bind_text(select, field++,
+ sqlite3_bind_text(stmt, field++,
trait->data.svalue, -1, SQLITE_STATIC);
break;
- case PSQF_ACCESS: /* FALLTHROUGH */
- case PSQF_CLIENT: /* FALLTHROUGH */
- case PSQF_DEV: /* FALLTHROUGH */
- case PSQF_FD: /* FALLTHROUGH */
- case PSQF_FTYPE: /* FALLTHROUGH */
- case PSQF_INODE: /* FALLTHROUGH */
- case PSQF_GID: /* FALLTHROUGH */
- case PSQF_PERM: /* FALLTHROUGH */
- case PSQF_MODE: /* FALLTHROUGH */
- case PSQF_OP: /* FALLTHROUGH */
- case PSQF_RESULT: /* FALLTHROUGH */
- case PSQF_SEVERITY: /* FALLTHROUGH */
- case PSQF_STAMP: /* FALLTHROUGH */
- case PSQF_TYPE: /* FALLTHROUGH */
- case PSQF_UID: /* FALLTHROUGH */
- sqlite3_bind_int(select, field++, trait->data.ivalue);
+ case PSQF_ACCESS:
+ case PSQF_CLIENT:
+ case PSQF_DEV:
+ case PSQF_FD:
+ case PSQF_FTYPE:
+ case PSQF_INODE:
+ case PSQF_GID:
+ case PSQF_PERM:
+ case PSQF_MODE:
+ case PSQF_OP:
+ case PSQF_RESULT:
+ case PSQF_SEVERITY:
+ case PSQF_STAMP:
+ case PSQF_TYPE:
+ case PSQF_UID:
+ sqlite3_bind_int(stmt, field++, trait->data.ivalue);
break;
default:
pseudo_diag("Inexplicably invalid field type %d\n", trait->field);
- sqlite3_finalize(select);
- return 0;
+ sqlite3_finalize(stmt);
+ return NULL;
}
}
+ return stmt;
+}
+
+int
+pdb_delete(pseudo_query_t *traits, unsigned long fields) {
+ sqlite3_stmt *stmt;
- if (do_delete) {
- /* no need to return it, so... */
- int rc = sqlite3_step(select);
+ stmt = pdb_query("DELETE", traits, fields, 0, 0);
+
+ /* no need to return it, so... */
+ if (stmt) {
+ int rc = sqlite3_step(stmt);
if (rc != SQLITE_DONE) {
dberr(log_db, "deletion failed");
+ return -1;
} else {
pseudo_diag("Deleted records, vacuuming log database (may take a while).\n");
+ /* we can't do anything about it if this fails... */
sqlite3_exec(log_db, "VACUUM;", NULL, NULL, NULL);
}
- sqlite3_finalize(select);
- return 0;
+ sqlite3_finalize(stmt);
+ return 0;
}
+ return -1;
+}
- /* fourth, return the statement, now ready to be stepped through */
- h = malloc(sizeof(*h));
- if (h) {
- h->rc = 0;
- h->fields = fields;
- h->stmt = select;
+log_history
+pdb_history(pseudo_query_t *traits, unsigned long fields, int unique) {
+ log_history h = NULL;
+ sqlite3_stmt *stmt;
+
+ stmt = pdb_query("SELECT", traits, fields, unique, 1);
+
+ if (stmt) {
+ /* fourth, return the statement, now ready to be stepped through */
+ h = malloc(sizeof(*h));
+ if (h) {
+ h->rc = 0;
+ h->fields = fields;
+ h->stmt = stmt;
+ } else {
+ pseudo_diag("failed to allocate memory for log_history\n");
+ sqlite3_finalize(stmt);
+ }
+ return h;
} else {
- pseudo_diag("failed to allocate memory for log_history\n");
+ return NULL;
}
- return h;
}
log_entry *
@@ -1208,8 +1234,8 @@ pdb_history_entry(log_history h) {
case PSQF_UID:
l->uid = sqlite3_column_int64(h->stmt, column++);
break;
- case PSQF_ORDER: /* FALLTHROUGH */
- case PSQF_FTYPE: /* FALLTHROUGH */
+ case PSQF_ORDER:
+ case PSQF_FTYPE:
case PSQF_PERM:
pseudo_diag("field %s should not be in the fields list.\n",
pseudo_query_field_name(f));
diff --git a/pseudo_db.h b/pseudo_db.h
index f8f5e3c..77ff5b5 100644
--- a/pseudo_db.h
+++ b/pseudo_db.h
@@ -76,7 +76,8 @@ extern pdb_file_list pdb_files(void);
extern pseudo_msg_t *pdb_file(pdb_file_list);
extern void pdb_files_done(pdb_file_list);
-extern log_history pdb_history(pseudo_query_t *traits, unsigned long fields, int unique, int delete);
+extern int pdb_delete(pseudo_query_t *traits, unsigned long fields);
+extern log_history pdb_history(pseudo_query_t *traits, unsigned long fields, int unique);
extern log_entry *pdb_history_entry(log_history h);
extern void pdb_history_free(log_history h);
extern void log_entry_free(log_entry *);
diff --git a/pseudolog.c b/pseudolog.c
index 707a71f..1316b9d 100644
--- a/pseudolog.c
+++ b/pseudolog.c
@@ -628,16 +628,20 @@ main(int argc, char **argv) {
pseudo_diag("couldn't parse format string (%s).\n", format);
return EXIT_FAILURE;
}
- history = pdb_history(traits, fields, opt_U, opt_D);
- if (history) {
- log_entry *e;
- while ((e = pdb_history_entry(history)) != NULL) {
- display(e, format);
- log_entry_free(e);
+ if (opt_D) {
+ if (pdb_delete(traits, fields)) {
+ pseudo_diag("errors occurred trying to delete entries.\n");
}
- pdb_history_free(history);
} else {
- if (!opt_D) {
+ history = pdb_history(traits, fields, opt_U);
+ if (history) {
+ log_entry *e;
+ while ((e = pdb_history_entry(history)) != NULL) {
+ display(e, format);
+ log_entry_free(e);
+ }
+ pdb_history_free(history);
+ } else {
pseudo_diag("could not retrieve history.\n");
return EXIT_FAILURE;
}