diff options
Diffstat (limited to 'mps/code')
| -rw-r--r-- | mps/code/eventsql.c | 72 |
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 | ||
| 348 | static void runStatement(sqlite3 *db, | 348 | static 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 | ||
| 371 | static unsigned long logSerial = 0; | 376 | static 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) | |||
| 522 | const char *glueTables[] = { | 533 | const char *glueTables[] = { |
| 523 | "event_kind", | 534 | "event_kind", |
| 524 | "event_type", | 535 | "event_type", |
| 536 | "event_param", | ||
| 525 | }; | 537 | }; |
| 526 | 538 | ||
| 527 | static void dropGlueTables(sqlite3 *db) | 539 | static 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 | |||
| 591 | static void fillGlueTables(sqlite3 *db) | 629 | static 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 */ |