| author | Stephen Paul Weber
<singpolyma@singpolyma.net> 2025-04-14 18:18:51 UTC |
| committer | Stephen Paul Weber
<singpolyma@singpolyma.net> 2025-04-14 18:18:51 UTC |
| parent | 7705d954e6799815f415747e9178f6a8c7388272 |
| snikket/persistence/Sqlite.hx | +22 | -22 |
| snikket/persistence/SqliteDriver.hx | +18 | -2 |
| snikket/persistence/SqliteDriver.js.hx | +14 | -3 |
diff --git a/snikket/persistence/Sqlite.hx b/snikket/persistence/Sqlite.hx index 68979ad..dcd55bd 100644 --- a/snikket/persistence/Sqlite.hx +++ b/snikket/persistence/Sqlite.hx @@ -36,10 +36,10 @@ class Sqlite implements Persistence implements KeyValueStore { this.media = media; media.setKV(this); db = new SqliteDriver(dbfile); - final version = db.exec("PRAGMA user_version;").then(iter -> { + db.exec("PRAGMA user_version;").then(iter -> { final version = Std.parseInt(iter.next()?.user_version) ?? 0; return if (version < 1) { - db.exec("CREATE TABLE messages ( + db.exec(["CREATE TABLE messages ( account_id TEXT NOT NULL, mam_id TEXT NOT NULL, mam_by TEXT NOT NULL, @@ -54,10 +54,10 @@ class Sqlite implements Persistence implements KeyValueStore { type INTEGER NOT NULL, stanza TEXT NOT NULL, PRIMARY KEY (account_id, mam_id, mam_by, stanza_id) - ) STRICT; - CREATE INDEX messages_created_at ON messages (account_id, chat_id, created_at); - CREATE INDEX messages_correction_id ON messages (correction_id); - CREATE TABLE chats ( + ) STRICT;", + "CREATE INDEX messages_created_at ON messages (account_id, chat_id, created_at);", + "CREATE INDEX messages_correction_id ON messages (correction_id);", + "CREATE TABLE chats ( account_id TEXT NOT NULL, chat_id TEXT NOT NULL, trusted INTEGER NOT NULL, @@ -72,24 +72,24 @@ class Sqlite implements Persistence implements KeyValueStore { presence BLOB NOT NULL, class TEXT NOT NULL, PRIMARY KEY (account_id, chat_id) - ) STRICT; - CREATE TABLE keyvaluepairs ( + ) STRICT;", + "CREATE TABLE keyvaluepairs ( k TEXT NOT NULL PRIMARY KEY, v TEXT NOT NULL - ) STRICT; - CREATE TABLE caps ( + ) STRICT;", + "CREATE TABLE caps ( sha1 BLOB NOT NULL PRIMARY KEY, caps BLOB NOT NULL - ) STRICT; - CREATE TABLE services ( + ) STRICT;", + "CREATE TABLE services ( account_id TEXT NOT NULL, service_id TEXT NOT NULL, name TEXT, node TEXT, caps BLOB NOT NULL, PRIMARY KEY (account_id, service_id) - ) STRICT; - CREATE TABLE accounts ( + ) STRICT;", + "CREATE TABLE accounts ( account_id TEXT NOT NULL, client_id TEXT NOT NULL, display_name TEXT, @@ -97,8 +97,8 @@ class Sqlite implements Persistence implements KeyValueStore { fast_count INTEGER NOT NULL DEFAULT 0, sm_state BLOB, PRIMARY KEY (account_id) - ) STRICT; - CREATE TABLE reactions ( + ) STRICT;", + "CREATE TABLE reactions ( account_id TEXT NOT NULL, update_id TEXT NOT NULL, mam_id TEXT, @@ -110,13 +110,13 @@ class Sqlite implements Persistence implements KeyValueStore { reactions BLOB NOT NULL, kind INTEGER NOT NULL, PRIMARY KEY (account_id, chat_id, sender_id, update_id) - ) STRICT; - PRAGMA user_version = 1;"); + ) STRICT;", + "PRAGMA user_version = 1;"]); } else if (version < 2) { - db.exec("ALTER TABLE chats ADD COLUMN notifications_filtered INTEGER; - ALTER TABLE chats ADD COLUMN notify_mention INTEGER NOT NULL DEFAULT 0; - ALTER TABLE chats ADD COLUMN notify_reply INTEGER NOT NULL DEFAULT 0; - PRAGMA user_version = 2;"); + db.exec(["ALTER TABLE chats ADD COLUMN notifications_filtered INTEGER;", + "ALTER TABLE chats ADD COLUMN notify_mention INTEGER NOT NULL DEFAULT 0;", + "ALTER TABLE chats ADD COLUMN notify_reply INTEGER NOT NULL DEFAULT 0;", + "PRAGMA user_version = 2;"]); } else { Promise.resolve(null); } diff --git a/snikket/persistence/SqliteDriver.hx b/snikket/persistence/SqliteDriver.hx index 099d880..f90b584 100644 --- a/snikket/persistence/SqliteDriver.hx +++ b/snikket/persistence/SqliteDriver.hx @@ -12,9 +12,22 @@ class SqliteDriver { db = sys.db.Sqlite.open(dbfile); } - public function exec(sql: String, ?params: Array<Dynamic>) { + public function exec(sql: haxe.extern.EitherType<String, Array<String>>, ?params: Array<Dynamic>) { + var result = null; + final qs = if (Std.isOfType(sql, String)) { + [sql]; + } else { + cast (sql, Array<Dynamic>); + } try { - final result = db.request(prepare(sql, params ?? [])); + for (q in qs) { + if (result == null) { + final prepared = prepare(q, params ?? []); + result = db.request(prepared); + } else { + db.request(q); + } + } return Promise.resolve(result); } catch (e) { return Promise.reject(e); @@ -35,6 +48,9 @@ class SqliteDriver { Std.string(p); case TNull: "NULL"; + case TClass(Array): + var bytes:Bytes = Bytes.ofData(p); + "X'" + bytes.toHex() + "'"; case TClass(haxe.io.Bytes): var bytes:Bytes = cast p; "X'" + bytes.toHex() + "'"; diff --git a/snikket/persistence/SqliteDriver.js.hx b/snikket/persistence/SqliteDriver.js.hx index 5dcdade..99be4b3 100644 --- a/snikket/persistence/SqliteDriver.js.hx +++ b/snikket/persistence/SqliteDriver.js.hx @@ -28,20 +28,21 @@ class SqliteDriver { }); } - public function exec(sql: String, ?params: Array<Dynamic>): Promise<haxe.iterators.ArrayIterator<Dynamic>> { + public function exec(sql: haxe.extern.EitherType<String, Array<String>>, ?params: Array<Dynamic>) { if (sqlite == null || dbId == null) { // Not ready yet return new Promise((resolve, reject) -> haxe.Timer.delay(() -> resolve(null), 100)) .then(_ -> exec(sql, params)); } + final qs = Std.isOfType(sql, String) ? sql : (cast sql).join(""); final items: Array<Dynamic> = []; var signalAllDone; final allDone = new Promise((resolve, reject) -> signalAllDone = resolve); return sqlite('exec', { dbId: dbId, - sql: sql, - bind: params, + sql: qs, + bind: params.map(formatParam), rowMode: "object", callback: (r) -> { if (r.rowNumber == null) { @@ -53,4 +54,14 @@ class SqliteDriver { } }).then(_ -> allDone).then(_ -> items.iterator()); } + + private function formatParam(p: Dynamic): Dynamic { + return switch (Type.typeof(p)) { + case TClass(haxe.io.Bytes): + var bytes:Bytes = cast p; + return bytes.getData(); + case _: + return p; + } + } }