aboutsummaryrefslogtreecommitdiffstats
path: root/mps/code
diff options
context:
space:
mode:
Diffstat (limited to 'mps/code')
-rw-r--r--mps/code/eventsql.c72
1 files changed, 57 insertions, 15 deletions
diff --git a/mps/code/eventsql.c b/mps/code/eventsql.c
index 9b069ac65e6..1e995bb0f67 100644
--- a/mps/code/eventsql.c
+++ b/mps/code/eventsql.c
@@ -1,6 +1,6 @@
1/* eventsql.c: event log to SQLite importer. 1/* eventsql.c: event log to SQLite importer.
2 * 2 *
3 * $Id* 3 * $Id$
4 * 4 *
5 * Copyright (c) 2012 Ravenbrook Limited. See end of file for license. 5 * Copyright (c) 2012 Ravenbrook Limited. See end of file for license.
6 * 6 *
@@ -34,12 +34,12 @@
34 * same event header files as those used to compile the MPS and 34 * same event header files as those used to compile the MPS and
35 * eventcnv which generated and processed the telemetry output. 35 * eventcnv which generated and processed the telemetry output.
36 * 36 *
37 * The program also creates three other tables: two 'glue' tables 37 * The program also creates several other tables: three 'glue' tables
38 * containing event metadata - event_kind (one row per kind) and 38 * containing event metadata - event_kind (one row per kind),
39 * event_type (one row per type), again derived from eventdef.h - and 39 * event_type (one row per type), and event_param (one row per
40 * the event_log table which has one row per log file imported (the 40 * parameter), all derived from eventdef.h - and the event_log table
41 * log_serial column in the event tables is a primary key to this 41 * which has one row per log file imported (the log_serial column in
42 * event_log table). 42 * the event tables is a primary key to this event_log table).
43 * 43 *
44 * No tables are created if they already exist, unless the -r 44 * No tables are created if they already exist, unless the -r
45 * (rebuild) switch is given. 45 * (rebuild) switch is given.
@@ -332,7 +332,7 @@ static sqlite3_stmt *prepareStatement(sqlite3 *db,
332 &statement, 332 &statement,
333 NULL); 333 NULL);
334 if (res != SQLITE_OK) 334 if (res != SQLITE_OK)
335 sqlite_error(res, db, "statementpreparation failed: %s", sql); 335 sqlite_error(res, db, "statement preparation failed: %s", sql);
336 return statement; 336 return statement;
337} 337}
338 338
@@ -342,7 +342,7 @@ static void finalizeStatement(sqlite3 *db,
342 int res; 342 int res;
343 res = sqlite3_finalize(statement); 343 res = sqlite3_finalize(statement);
344 if (res != SQLITE_OK) 344 if (res != SQLITE_OK)
345 sqlite_error(res, db, "event_type finalize failed"); 345 sqlite_error(res, db, "statement finalize failed");
346} 346}
347 347
348static void runStatement(sqlite3 *db, 348static void runStatement(sqlite3 *db,
@@ -366,7 +366,12 @@ static void runStatement(sqlite3 *db,
366 * from SQL which is then attached to all event rows from that log. 366 * from SQL which is then attached to all event rows from that log.
367 * We use this to record overall SQL activity, to deter mistaken 367 * We use this to record overall SQL activity, to deter mistaken
368 * attempts to add the same log file twice, and to allow events from 368 * attempts to add the same log file twice, and to allow events from
369 * several different log files to share the same SQL file. */ 369 * several different log files to share the same SQL file.
370 *
371 * When reading events from stdin, we can't so easily avoid the
372 * duplication (unless we, e.g., take a hash of the event set); we
373 * assume that the user is smart enough not to do that.
374 */
370 375
371static unsigned long logSerial = 0; 376static unsigned long logSerial = 0;
372 377
@@ -498,6 +503,12 @@ const char *createStatements[] = {
498 " kind INTEGER," 503 " kind INTEGER,"
499 " FOREIGN KEY (kind) REFERENCES event_kind(enum));", 504 " FOREIGN KEY (kind) REFERENCES event_kind(enum));",
500 505
506 "CREATE TABLE IF NOT EXISTS event_param (type INTEGER,"
507 " param_index INTEGER,"
508 " sort TEXT,"
509 " ident TEXT,"
510 " FOREIGN KEY (type) REFERENCES event_type(code));",
511
501 "CREATE TABLE IF NOT EXISTS event_log (name TEXT," 512 "CREATE TABLE IF NOT EXISTS event_log (name TEXT,"
502 " size INTEGER," 513 " size INTEGER,"
503 " modtime INTEGER," 514 " modtime INTEGER,"
@@ -522,6 +533,7 @@ static void makeTables(sqlite3 *db)
522const char *glueTables[] = { 533const char *glueTables[] = {
523 "event_kind", 534 "event_kind",
524 "event_type", 535 "event_type",
536 "event_param",
525}; 537};
526 538
527static void dropGlueTables(sqlite3 *db) 539static void dropGlueTables(sqlite3 *db)
@@ -544,7 +556,8 @@ static void dropGlueTables(sqlite3 *db)
544 } 556 }
545} 557}
546 558
547/* Populate the metadata "glue" tables event_kind and event_type. */ 559/* Populate the metadata "glue" tables event_kind, event_type, and
560 * event_param. */
548 561
549#define EVENT_KIND_DO_INSERT(X, name, description) \ 562#define EVENT_KIND_DO_INSERT(X, name, description) \
550 res = sqlite3_bind_text(statement, 1, #name, -1, SQLITE_STATIC); \ 563 res = sqlite3_bind_text(statement, 1, #name, -1, SQLITE_STATIC); \
@@ -588,6 +601,31 @@ static void dropGlueTables(sqlite3 *db)
588 if (res != SQLITE_OK) \ 601 if (res != SQLITE_OK) \
589 sqlite_error(res, db, "Couldn't reset event_type insert statement."); 602 sqlite_error(res, db, "Couldn't reset event_type insert statement.");
590 603
604#define EVENT_PARAM_DO_INSERT(code, index, sort, ident) \
605 res = sqlite3_bind_int(statement, 1, code); \
606 if (res != SQLITE_OK) \
607 sqlite_error(res, db, "event_param bind of code %d failed.", code); \
608 res = sqlite3_bind_int(statement, 2, index); \
609 if (res != SQLITE_OK) \
610 sqlite_error(res, db, "event_param bind of index %d failed.", index); \
611 res = sqlite3_bind_text(statement, 3, #sort, -1, SQLITE_STATIC); \
612 if (res != SQLITE_OK) \
613 sqlite_error(res, db, "event_type bind of sort \"" #sort "\" failed."); \
614 res = sqlite3_bind_text(statement, 4, #ident, -1, SQLITE_STATIC); \
615 if (res != SQLITE_OK) \
616 sqlite_error(res, db, "event_type bind of ident \"" #ident "\" failed."); \
617 res = sqlite3_step(statement); \
618 if (res != SQLITE_DONE) \
619 sqlite_error(res, db, "event_param insert of ident \"" #ident "\" for code %d failed.", code); \
620 if (sqlite3_changes(db) != 0) \
621 log(LOG_SOMETIMES, "Insert of event_param row for code %d, ident \"" #ident "\" affected %d rows.", code, sqlite3_changes(db)); \
622 res = sqlite3_reset(statement); \
623 if (res != SQLITE_OK) \
624 sqlite_error(res, db, "Couldn't reset event_param insert statement.");
625
626#define EVENT_TYPE_INSERT_PARAMS(X, name, code, always, kind) \
627 EVENT_##name##_PARAMS(EVENT_PARAM_DO_INSERT, code)
628
591static void fillGlueTables(sqlite3 *db) 629static void fillGlueTables(sqlite3 *db)
592{ 630{
593 int i; 631 int i;
@@ -609,6 +647,13 @@ static void fillGlueTables(sqlite3 *db)
609 EVENT_LIST(EVENT_TYPE_DO_INSERT, X); 647 EVENT_LIST(EVENT_TYPE_DO_INSERT, X);
610 648
611 finalizeStatement(db, statement); 649 finalizeStatement(db, statement);
650
651 statement = prepareStatement(db,
652 "INSERT OR IGNORE INTO event_param (type, param_index, sort, ident)"
653 "VALUES (?, ?, ?, ?)");
654 EVENT_LIST(EVENT_TYPE_INSERT_PARAMS, X);
655
656 finalizeStatement(db, statement);
612} 657}
613 658
614/* Populate the actual event tables. */ 659/* Populate the actual event tables. */
@@ -862,10 +907,7 @@ int main(int argc, char *argv[])
862 fillGlueTables(db); 907 fillGlueTables(db);
863 count = writeEventsToSQL(db); 908 count = writeEventsToSQL(db);
864 log(LOG_ALWAYS, "Imported %llu events from %s to %s, serial %lu.", 909 log(LOG_ALWAYS, "Imported %llu events from %s to %s, serial %lu.",
865 (unsigned long)count, 910 count, logFileName, databaseName, logSerial);
866 logFileName,
867 databaseName,
868 logSerial);
869 911
870 if (runTests) { 912 if (runTests) {
871 /* TODO: more unit tests in here */ 913 /* TODO: more unit tests in here */