mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-03-25 08:12:11 -07:00
Event sql interface now creates a table for each type of event.
Copied from Perforce Change: 179868 ServerID: perforce.ravenbrook.com
This commit is contained in:
parent
d148dc3d00
commit
04c5aca708
1 changed files with 170 additions and 138 deletions
|
|
@ -17,183 +17,215 @@ unsigned int verbosity = 4;
|
|||
|
||||
static void vlog(unsigned int level, const char *format, va_list args)
|
||||
{
|
||||
if (level <= verbosity) {
|
||||
fflush(stderr); /* sync */
|
||||
fprintf(stderr, "log %d: ", level);
|
||||
vfprintf(stderr, format, args);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
if (level <= verbosity) {
|
||||
fflush(stderr); /* sync */
|
||||
fprintf(stderr, "log %d: ", level);
|
||||
vfprintf(stderr, format, args);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void log(unsigned int level, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vlog(level, format, args);
|
||||
va_end(args);
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vlog(level, format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
#if 0 /* UNUSED */
|
||||
|
||||
static void error(const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
fprintf(stderr, "Fatal error: ");
|
||||
va_start(args, format);
|
||||
vlog(LOG_ALWAYS, format, args);
|
||||
va_end(args);
|
||||
exit(1);
|
||||
va_list args;
|
||||
fprintf(stderr, "Fatal error: ");
|
||||
va_start(args, format);
|
||||
vlog(LOG_ALWAYS, format, args);
|
||||
va_end(args);
|
||||
exit(1);
|
||||
}
|
||||
#endif /* UNUSED */
|
||||
|
||||
|
||||
static void sqlite_error(int res, sqlite3 *db, const char *format, ...)
|
||||
{
|
||||
log(LOG_ALWAYS, "Fatal SQL error %d", res);
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vlog(LOG_ALWAYS, format, args);
|
||||
va_end(args);
|
||||
log(LOG_ALWAYS, "SQLite message: %s\n", sqlite3_errmsg(db));
|
||||
exit(1);
|
||||
log(LOG_ALWAYS, "Fatal SQL error %d", res);
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vlog(LOG_ALWAYS, format, args);
|
||||
va_end(args);
|
||||
log(LOG_ALWAYS, "SQLite message: %s\n", sqlite3_errmsg(db));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void openDatabase(sqlite3 **dbReturn)
|
||||
{
|
||||
sqlite3 *db;
|
||||
int res;
|
||||
|
||||
const char *filename = getenv("MPS_EVENT_DATABASE");
|
||||
if(filename == NULL)
|
||||
filename = "mpsevent.db";
|
||||
log(LOG_OFTEN, "Opening %s.", filename);
|
||||
|
||||
res = sqlite3_open_v2(filename,
|
||||
&db,
|
||||
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
|
||||
NULL); /* use default sqlite_vfs object */
|
||||
|
||||
if (res != SQLITE_OK)
|
||||
sqlite_error(res, db, "Opening %s failed", filename);
|
||||
*dbReturn = db;
|
||||
return;
|
||||
sqlite3 *db;
|
||||
int res;
|
||||
|
||||
const char *filename = getenv("MPS_EVENT_DATABASE");
|
||||
if(filename == NULL)
|
||||
filename = "mpsevent.db";
|
||||
log(LOG_OFTEN, "Opening %s.", filename);
|
||||
|
||||
res = sqlite3_open_v2(filename,
|
||||
&db,
|
||||
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
|
||||
NULL); /* use default sqlite_vfs object */
|
||||
|
||||
if (res != SQLITE_OK)
|
||||
sqlite_error(res, db, "Opening %s failed", filename);
|
||||
*dbReturn = db;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Macro magic to make a CREATE TABLE statement for each event type. */
|
||||
|
||||
#define EVENT_PARAM_SQL_TYPE_A "INTEGER"
|
||||
#define EVENT_PARAM_SQL_TYPE_P "INTEGER"
|
||||
#define EVENT_PARAM_SQL_TYPE_U "INTEGER"
|
||||
#define EVENT_PARAM_SQL_TYPE_W "INTEGER"
|
||||
#define EVENT_PARAM_SQL_TYPE_D "REAL "
|
||||
#define EVENT_PARAM_SQL_TYPE_S "TEXT "
|
||||
#define EVENT_PARAM_SQL_TYPE_B "INTEGER"
|
||||
|
||||
#define EVENT_PARAM_SQL_COLUMN(X, index, sort, ident) \
|
||||
"\"" #ident "\" " EVENT_PARAM_SQL_TYPE_##sort ", "
|
||||
|
||||
#define EVENT_TABLE_CREATE(X, name, code, always, kind) \
|
||||
"CREATE TABLE IF NOT EXISTS EVENT_" #name " ( " \
|
||||
EVENT_##name##_PARAMS(EVENT_PARAM_SQL_COLUMN, X) \
|
||||
"time INTEGER ) ",
|
||||
|
||||
const char *createStatements[] = {
|
||||
"CREATE TABLE IF NOT EXISTS event_kind (name TEXT,"
|
||||
" description TEXT,"
|
||||
" enum INTEGER PRIMARY KEY)",
|
||||
"CREATE TABLE IF NOT EXISTS event_type (name TEXT,"
|
||||
" code INTEGER PRIMARY KEY,"
|
||||
" always INTEGER,"
|
||||
" kind INTEGER,"
|
||||
" FOREIGN KEY (kind) REFERENCES event_kind(enum));",
|
||||
"CREATE TABLE IF NOT EXISTS event_kind (name TEXT,"
|
||||
" description TEXT,"
|
||||
" enum INTEGER PRIMARY KEY)",
|
||||
|
||||
"CREATE TABLE IF NOT EXISTS event_type (name TEXT,"
|
||||
" code INTEGER PRIMARY KEY,"
|
||||
" always INTEGER,"
|
||||
" kind INTEGER,"
|
||||
" FOREIGN KEY (kind) REFERENCES event_kind(enum));",
|
||||
|
||||
EVENT_LIST(EVENT_TABLE_CREATE, X)
|
||||
};
|
||||
|
||||
const char *populateStatements[] = {
|
||||
};
|
||||
|
||||
#define EVENT_KIND_DO_INSERT(X, name, description) \
|
||||
res = sqlite3_bind_text(statement, 1, #name, -1, SQLITE_STATIC); \
|
||||
if (res != SQLITE_OK) \
|
||||
sqlite_error(res, db, "event_kind bind of name \"" #name "\" failed."); \
|
||||
res = sqlite3_bind_text(statement, 2, description, -1, SQLITE_STATIC); \
|
||||
if (res != SQLITE_OK) \
|
||||
sqlite_error(res, db, "event_kind bind of description \"" description "\" failed."); \
|
||||
res = sqlite3_bind_int(statement, 3, i); \
|
||||
if (res != SQLITE_OK) \
|
||||
sqlite_error(res, db, "event_kind bind of enum %d failed.", i); \
|
||||
++i; \
|
||||
res = sqlite3_step(statement); \
|
||||
if (res != SQLITE_DONE) \
|
||||
sqlite_error(res, db, "event_kind insert of name \"" #name "\" failed."); \
|
||||
if (sqlite3_changes(db) != 0)\
|
||||
log(LOG_SOMETIMES, "Insert of event_kind row for \"" #name "\" affected %d rows.", sqlite3_changes(db)); \
|
||||
res = sqlite3_reset(statement); \
|
||||
if (res != SQLITE_OK) \
|
||||
sqlite_error(res, db, "Couldn't reset event_kind insert statement.");
|
||||
res = sqlite3_bind_text(statement, 1, #name, -1, SQLITE_STATIC); \
|
||||
if (res != SQLITE_OK) \
|
||||
sqlite_error(res, db, "event_kind bind of name \"" #name "\" failed."); \
|
||||
res = sqlite3_bind_text(statement, 2, description, -1, SQLITE_STATIC); \
|
||||
if (res != SQLITE_OK) \
|
||||
sqlite_error(res, db, "event_kind bind of description \"" description "\" failed."); \
|
||||
res = sqlite3_bind_int(statement, 3, i); \
|
||||
if (res != SQLITE_OK) \
|
||||
sqlite_error(res, db, "event_kind bind of enum %d failed.", i); \
|
||||
++i; \
|
||||
res = sqlite3_step(statement); \
|
||||
if (res != SQLITE_DONE) \
|
||||
sqlite_error(res, db, "event_kind insert of name \"" #name "\" failed."); \
|
||||
if (sqlite3_changes(db) != 0) \
|
||||
log(LOG_SOMETIMES, "Insert of event_kind row for \"" #name "\" affected %d rows.", sqlite3_changes(db)); \
|
||||
res = sqlite3_reset(statement); \
|
||||
if (res != SQLITE_OK) \
|
||||
sqlite_error(res, db, "Couldn't reset event_kind insert statement.");
|
||||
|
||||
#define EVENT_TYPE_DO_INSERT(X, name, code, always, kind) \
|
||||
res = sqlite3_bind_text(statement, 1, #name, -1, SQLITE_STATIC); \
|
||||
if (res != SQLITE_OK) \
|
||||
sqlite_error(res, db, "event_type bind of name \"" #name "\" failed."); \
|
||||
res = sqlite3_bind_int(statement, 2, code); \
|
||||
if (res != SQLITE_OK) \
|
||||
sqlite_error(res, db, "event_type bind of code %d failed.", code); \
|
||||
res = sqlite3_bind_int(statement, 3, always); \
|
||||
if (res != SQLITE_OK) \
|
||||
sqlite_error(res, db, "event_type bind of always for name \"" #name "\" failed."); \
|
||||
res = sqlite3_bind_int(statement, 4, EventKind##kind); \
|
||||
if (res != SQLITE_OK) \
|
||||
sqlite_error(res, db, "event_type bind of kind for name \"" #name "\" failed."); \
|
||||
res = sqlite3_step(statement); \
|
||||
if (res != SQLITE_DONE) \
|
||||
sqlite_error(res, db, "event_type insert of name \"" #name "\" failed."); \
|
||||
if (sqlite3_changes(db) != 0) \
|
||||
log(LOG_SOMETIMES, "Insert of event_type row for \"" #name "\" affected %d rows.", sqlite3_changes(db)); \
|
||||
res = sqlite3_reset(statement); \
|
||||
if (res != SQLITE_OK) \
|
||||
sqlite_error(res, db, "Couldn't reset event_type insert statement.");
|
||||
#define EVENT_TYPE_DO_INSERT(X, name, code, always, kind) \
|
||||
res = sqlite3_bind_text(statement, 1, #name, -1, SQLITE_STATIC); \
|
||||
if (res != SQLITE_OK) \
|
||||
sqlite_error(res, db, "event_type bind of name \"" #name "\" failed."); \
|
||||
res = sqlite3_bind_int(statement, 2, code); \
|
||||
if (res != SQLITE_OK) \
|
||||
sqlite_error(res, db, "event_type bind of code %d failed.", code); \
|
||||
res = sqlite3_bind_int(statement, 3, always); \
|
||||
if (res != SQLITE_OK) \
|
||||
sqlite_error(res, db, "event_type bind of always for name \"" #name "\" failed."); \
|
||||
res = sqlite3_bind_int(statement, 4, EventKind##kind); \
|
||||
if (res != SQLITE_OK) \
|
||||
sqlite_error(res, db, "event_type bind of kind for name \"" #name "\" failed."); \
|
||||
res = sqlite3_step(statement); \
|
||||
if (res != SQLITE_DONE) \
|
||||
sqlite_error(res, db, "event_type insert of name \"" #name "\" failed."); \
|
||||
if (sqlite3_changes(db) != 0) \
|
||||
log(LOG_SOMETIMES, "Insert of event_type row for \"" #name "\" affected %d rows.", sqlite3_changes(db)); \
|
||||
res = sqlite3_reset(statement); \
|
||||
if (res != SQLITE_OK) \
|
||||
sqlite_error(res, db, "Couldn't reset event_type insert statement.");
|
||||
|
||||
static void fillTables(sqlite3 *db)
|
||||
{
|
||||
int i;
|
||||
sqlite3_stmt *statement;
|
||||
|
||||
int res = sqlite3_prepare_v2(db,
|
||||
"INSERT OR IGNORE INTO event_kind (name, description, enum)"
|
||||
"VALUES (?, ?, ?)",
|
||||
-1, /* prepare whole string as statement */
|
||||
&statement,
|
||||
NULL);
|
||||
if (res != SQLITE_OK)
|
||||
sqlite_error(res, db, "event_kind preparation failed");
|
||||
|
||||
i = 0;
|
||||
EventKindENUM(EVENT_KIND_DO_INSERT, X);
|
||||
|
||||
res = sqlite3_finalize(statement);
|
||||
if (res != SQLITE_OK)
|
||||
sqlite_error(res, db, "event_kind finalize failed");
|
||||
|
||||
res = sqlite3_prepare_v2(db,
|
||||
"INSERT OR IGNORE INTO event_type (name, code, always, kind)"
|
||||
"VALUES (?, ?, ?, ?)",
|
||||
-1, /* prepare whole string as statement */
|
||||
&statement,
|
||||
NULL);
|
||||
if (res != SQLITE_OK)
|
||||
sqlite_error(res, db, "event_type preparation failed");
|
||||
|
||||
EVENT_LIST(EVENT_TYPE_DO_INSERT, X);
|
||||
|
||||
res = sqlite3_finalize(statement);
|
||||
if (res != SQLITE_OK)
|
||||
sqlite_error(res, db, "event_type finalize failed");
|
||||
int i;
|
||||
sqlite3_stmt *statement;
|
||||
int res;
|
||||
|
||||
res = sqlite3_prepare_v2(db,
|
||||
"INSERT OR IGNORE INTO event_kind (name, description, enum)"
|
||||
"VALUES (?, ?, ?)",
|
||||
-1, /* prepare whole string as statement */
|
||||
&statement,
|
||||
NULL);
|
||||
if (res != SQLITE_OK)
|
||||
sqlite_error(res, db, "event_kind preparation failed");
|
||||
|
||||
i = 0;
|
||||
EventKindENUM(EVENT_KIND_DO_INSERT, X);
|
||||
|
||||
res = sqlite3_finalize(statement);
|
||||
if (res != SQLITE_OK)
|
||||
sqlite_error(res, db, "event_kind finalize failed");
|
||||
|
||||
res = sqlite3_prepare_v2(db,
|
||||
"INSERT OR IGNORE INTO event_type (name, code, always, kind)"
|
||||
"VALUES (?, ?, ?, ?)",
|
||||
-1, /* prepare whole string as statement */
|
||||
&statement,
|
||||
NULL);
|
||||
if (res != SQLITE_OK)
|
||||
sqlite_error(res, db, "event_type preparation failed");
|
||||
|
||||
EVENT_LIST(EVENT_TYPE_DO_INSERT, X);
|
||||
|
||||
res = sqlite3_finalize(statement);
|
||||
if (res != SQLITE_OK)
|
||||
sqlite_error(res, db, "event_type finalize failed");
|
||||
}
|
||||
|
||||
static void makeTables(sqlite3 *db)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
int res;
|
||||
|
||||
for (i=0; i < (sizeof(createStatements)/sizeof(createStatements[0])); ++i) {
|
||||
log(LOG_SOMETIMES, "Creating tables. SQL command: %s", createStatements[i]);
|
||||
res = sqlite3_exec(db,
|
||||
createStatements[i],
|
||||
NULL, /* No callback */
|
||||
NULL, /* No callback closure */
|
||||
NULL); /* error messages handled by sqlite_error */
|
||||
if (res != SQLITE_OK)
|
||||
sqlite_error(res, db, "Table creation failed: %s", createStatements[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i < (sizeof(createStatements)/sizeof(createStatements[0])); ++i) {
|
||||
log(LOG_SOMETIMES, "Creating tables. SQL command: %s", createStatements[i]);
|
||||
int res = sqlite3_exec(db,
|
||||
createStatements[i],
|
||||
NULL, /* No callback */
|
||||
NULL, /* No callback closure */
|
||||
NULL); /* error messages handled by sqlite_error */
|
||||
if (res != SQLITE_OK)
|
||||
sqlite_error(res, db, "Table creation failed: %s", createStatements[i]);
|
||||
}
|
||||
void closeDatabase(sqlite3 *db)
|
||||
{
|
||||
int res = sqlite3_close(db);
|
||||
if (res != SQLITE_OK)
|
||||
sqlite_error(res, db, "Closing database failed");
|
||||
log(LOG_ALWAYS, "Closed database.");
|
||||
}
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
sqlite3 *db;
|
||||
|
||||
openDatabase(&db);
|
||||
makeTables(db);
|
||||
fillTables(db);
|
||||
return 0;
|
||||
sqlite3 *db;
|
||||
|
||||
openDatabase(&db);
|
||||
makeTables(db);
|
||||
fillTables(db);
|
||||
closeDatabase(db);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue