diff --git a/wdmtg.vala b/wdmtg.vala index 534d76e..5fb3aec 100644 --- a/wdmtg.vala +++ b/wdmtg.vala @@ -290,6 +290,52 @@ namespace Wdmtg { set_idle_alarm (ref idle_alarm_inactive, X.Sync.TestType.PositiveComparison, idle_timeout); + var data_path = Path.build_filename (Environment.get_user_data_dir (), + Config.PROJECT_NAME); + DirUtils.create_with_parents (data_path, 0755); + + Sqlite.Database db; + var db_path = Path.build_filename (data_path, "db.sqlite"); + int rc = Sqlite.Database.open (db_path, out db); + if (rc != Sqlite.OK) + exit_fatal ("%s: %s", db_path, db.errmsg ()); + + // This shouldn't normally happen but external applications may decide + // to read things out, and mess with us. When that takes too long, we may + // a/ wait for it to finish, b/ start with a whole-database lock or, even + // more simply, c/ crash on the BUSY error. + db.busy_timeout (1000); + + string errmsg; + if ((rc = db.exec ("BEGIN", null, out errmsg)) != Sqlite.OK) + exit_fatal ("%s: %s", db_path, errmsg); + + Sqlite.Statement stmt; + if ((rc = db.prepare_v2 ("PRAGMA user_version", -1, out stmt, null)) + != Sqlite.OK) + exit_fatal ("%s: %s", db_path, db.errmsg ()); + if ((rc = stmt.step ()) != Sqlite.ROW || stmt.data_count () != 1) + exit_fatal ("%s: %s", db_path, "cannot retrieve user version"); + + var user_version = stmt.column_int (0); + if (user_version == 0) { + if ((rc = db.exec ("""CREATE TABLE events ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + timestamp INTEGER, + title TEXT, + idle BOOLEAN + )""", null, out errmsg)) != Sqlite.OK) + exit_fatal ("%s: %s", db_path, errmsg); + + if ((rc = db.exec ("PRAGMA user_version = 1", null, out errmsg)) + != Sqlite.OK) + exit_fatal ("%s: %s", db_path, errmsg); + } else if (user_version != 1) { + exit_fatal ("%s: unsupported DB version: %d", db_path, user_version); + } + if ((rc = db.exec ("COMMIT", null, out errmsg)) != Sqlite.OK) + exit_fatal ("%s: %s", db_path, errmsg); + var loop = new MainLoop (); var channel = new IOChannel.unix_new (dpy.connection_number ()); channel.add_watch (IOCondition.IN, (source, condition) => {