borogove

created pr with borogove/sqlite-injectable-driver.1 on 2026-11-09T19:46:34Z · by 3c31bc8c
commented on 2026-11-09T19:46:34Z · by 3c31bc8c
Changes are available at https://tangled.org/mrry.band/borogove on branch sqlite-injectable-driver.
added borogove/sqlite-injectable-driver.2 on 2026-11-09T20:05:07Z · by 3c31bc8c
1: 981fe7d = 1: 981fe7d Use arrays
2: ef9e639 = 2: ef9e639 Make prepare public, remove formatParam and first
3: f949361 ! 3: a97c836 Allow injectable drivers for Sqlite
commented on 2026-11-09T20:49:02Z · by 9e834e0d
browser tests dont pass
added borogove/sqlite-injectable-driver.3 on 2026-11-09T21:28:45Z · by 3c31bc8c
1: 981fe7d = 1: 981fe7d Use arrays
2: ef9e639 ! 2: 11eb826 Make prepare public, remove formatParam and first
3: a97c836 ! 3: 34cee7d Allow injectable drivers for Sqlite
cmds
checkout latest patchset:
ssh pr.pico.sh pull borogove:sqlite-injectable-driver | git am -3
checkout specific patchset revision:
ssh pr.pico.sh pull borogove:sqlite-injectable-driver [rev] | git am -3
add changes to patch request:
git format-patch main --stdout | ssh pr.pico.sh borogove:sqlite-injectable-driver
add comment to patch request:
ssh pr.pico.sh comment borogove:sqlite-injectable-driver "lgtm!"

Patchset borogove/sqlite-injectable-driver.2 on 2026-11-09T20:05:07Z · commit 981fe7d

Use arrays
Eric Roberts 2026-11-09T19:27:25Z
We are not getting any benefit out of using iterators, and only pain and
suffering.

Trying to write an injectable driver for the tauri app to use, and I
don't want to have to have it send in something that acts like an
iterator when we just have arrays.
Semantic diff summary
0 added, 0 modified, 0 signature changed, 0 removed across 0 analyzed files (4 files skipped: unsupported file type)
+19 -21 borogove/persistence/Sqlite.hx #
......@@ -90,8 +90,8 @@ class Sqlite implements Persistence implements KeyValueStore {
9090 this.media = media;
9191 media.setKV(this);
9292 db = new SqliteDriver(dbfile, (exec) -> {
93- exec(["PRAGMA user_version"]).then(iter -> {
94- final version = Std.parseInt(iter.next()?.user_version) ?? 0;
93+ exec(["PRAGMA user_version"]).then(rows -> {
94+ final version = Std.parseInt(rows[0]?.user_version) ?? 0;
9595 return Promise.resolve(null).then(_ -> {
9696 if (version < 1) {
9797 return exec(["CREATE TABLE messages (
......@@ -644,7 +644,7 @@ class Sqlite implements Persistence implements KeyValueStore {
644644 "SELECT member_id, display_name, photo_uri, is_self, chat, json(roles) AS roles, json(presence) AS presence, jid FROM members WHERE account_id=? AND member_id=? LIMIT 1",
645645 [accountId, update.id]
646646 ).then(rows ->
647- return rows.hasNext() ? rows.next() : null
647+ return rows[0]
648648 )).then(existing -> {
649649 if (existing != null || update.jid == null) return Promise.resolve(existing);
650650
......@@ -652,7 +652,7 @@ class Sqlite implements Persistence implements KeyValueStore {
652652 "SELECT member_id, display_name, photo_uri, is_self, chat, json(roles) AS roles, json(presence) AS presence, jid FROM members WHERE account_id=? AND chat_id=? AND jid=? LIMIT 1",
653653 [accountId, chat.chatId, update.jid.asString()]
654654 ).then(rows ->
655- return rows.hasNext() ? rows.next() : null
655+ return rows[0]
656656 );
657657 }).then(existing -> {
658658 final member = hydrateStoredMember(chat, existing);
......@@ -801,8 +801,7 @@ class Sqlite implements Persistence implements KeyValueStore {
801801 return db.exec(
802802 "SELECT chat_id, trusted, bookmarked, avatar_sha1, fn, ui_state, blocked, extensions, read_up_to_id, read_up_to_by, notifications_filtered, notify_mention, notify_reply, json(caps) AS caps, caps_ver, json(meta) AS meta, class FROM chats LEFT JOIN caps ON chats.caps_ver=caps.sha1 WHERE account_id=?",
803803 [accountId]
804- ).then(result -> {
805- final rows = { iterator: () -> result }.array();
804+ ).then(rows -> {
806805 return chatPresenceAndMembersForName(accountId, rows).then(chatData -> {
807806 final chats: Array<SerializedChat> = [];
808807 for (row in rows) {
......@@ -896,9 +895,9 @@ class Sqlite implements Persistence implements KeyValueStore {
896895 }
897896 q += " GROUP BY correction_id, CASE WHEN messages.type=? THEN 'call' ELSE messages.sender_id END";
898897 return db.exec(q, params).then(results -> {
899- final row = results.next();
898+ final row = results[0];
900899 if (row == null) return stub;
901- return hydrateMessages(accountId, [row].iterator())[0];
900+ return hydrateMessages(accountId, [row])[0];
902901 });
903902 }
904903
......@@ -1082,8 +1081,8 @@ class Sqlite implements Persistence implements KeyValueStore {
10821081 ',
10831082 [accountId, chat.chatId, MessageChannelPrivate, chat.readUpToId, MessageSent, accountId, chat.chatId, MessageChannelPrivate]
10841083 ).then(result -> {
1085- final row: Dynamic = result.next();
1086- final lastMessage = row.stanza == null ? [] : hydrateMessages(accountId, [row].iterator());
1084+ final row: Dynamic = result[0];
1085+ final lastMessage = row.stanza == null ? [] : hydrateMessages(accountId, [row]);
10871086 return { unreadCount: row.unreadCount, chatId: chat.chatId, message: lastMessage[0] };
10881087 });
10891088 }
......@@ -1266,7 +1265,7 @@ class Sqlite implements Persistence implements KeyValueStore {
12661265 @HaxeCBridge.noemit
12671266 public function listAccounts(): Promise<Array<String>> {
12681267 return db.exec("SELECT account_id FROM accounts").then(result ->
1269- result == null ? [] : { iterator: () -> result }.map(row -> row.account_id)
1268+ result == null ? [] : result.map(row -> row.account_id)
12701269 );
12711270 }
12721271
......@@ -1440,13 +1439,12 @@ class Sqlite implements Persistence implements KeyValueStore {
14401439 params = params.concat(stanzaIds);
14411440 }
14421441 db.exec(q.join(" UNION ALL "), params);
1443- }).then(iter -> {
1444- if (iter != null) {
1445- final parents = { iterator: () -> iter }.array();
1442+ }).then(parents -> {
1443+ if (parents != null) {
14461444 for (message in messages) {
14471445 if (message.replyToMessage != null) {
1448- final found: Dynamic = Util.findFast(parents, p -> p.chat_id == message.chatId() && (message.replyToMessage.serverId == null || p.mam_id == message.replyToMessage.serverId) && (message.replyToMessage.localId == null || p.stanza_id == message.replyToMessage.localId));
1449- if (found != null) message.set_replyToMessage(hydrateMessages(accountId, [found].iterator())[0]);
1446+ final found: Dynamic = Util.findFast(parents, (p: Dynamic) -> p.chat_id == message.chatId() && (message.replyToMessage.serverId == null || p.mam_id == message.replyToMessage.serverId) && (message.replyToMessage.localId == null || p.stanza_id == message.replyToMessage.localId));
1447+ if (found != null) message.set_replyToMessage(hydrateMessages(accountId, [found])[0]);
14501448 }
14511449 }
14521450 }
......@@ -1474,7 +1472,7 @@ class Sqlite implements Persistence implements KeyValueStore {
14741472
14751473 private function hydrateMessagesAndLoadMeta(
14761474 accountId: String,
1477- rows: Iterator<{
1475+ rows: Iterable<{
14781476 stanza: String,
14791477 time_sent: String,
14801478 time_received: String,
......@@ -1514,7 +1512,7 @@ class Sqlite implements Persistence implements KeyValueStore {
15141512
15151513 private function hydrateMessages(
15161514 accountId: String,
1517- rows: Iterator<{
1515+ rows: Iterable<{
15181516 stanza: String,
15191517 time_sent: String,
15201518 time_received: String,
......@@ -1535,7 +1533,7 @@ class Sqlite implements Persistence implements KeyValueStore {
15351533 ): Array<ChatMessage> {
15361534 // TODO: Calls can "edit" from multiple senders, but the original direction and sender holds
15371535 final accountJid = JID.parse(accountId);
1538- return { iterator: () -> rows }.map(row -> ChatMessage.fromStanza(Stanza.parse(row.stanza), accountJid, (builder, _) -> {
1536+ return Lambda.map(rows, row -> ChatMessage.fromStanza(Stanza.parse(row.stanza), accountJid, (builder, _) -> {
15391537 builder.syncPoint = row.sync_point != 0;
15401538 builder.timeSent = row.time_sent;
15411539 builder.timeReceived = row.time_received;
......@@ -1640,7 +1638,7 @@ class Sqlite implements Persistence implements KeyValueStore {
16401638 "SELECT device_id FROM omemo_devices WHERE identifier=?",
16411639 [identifier],
16421640 ).then(result -> {
1643- return { iterator: () -> result }.map(row -> row.device_id).array();
1641+ return result.map(row -> row.device_id);
16441642 });
16451643 }
16461644
......@@ -1730,7 +1728,7 @@ class Sqlite implements Persistence implements KeyValueStore {
17301728 return db.exec(
17311729 "SELECT key_id, private_key, public_key FROM omemo_prekeys WHERE account_id=? ORDER BY key_id",
17321730 [login],
1733- ).then(result -> { iterator: () -> result }.map(row -> ({
1731+ ).then(result -> result.map(row -> ({
17341732 keyId: row.key_id,
17351733 keyPair: {
17361734 privKey: row.private_key,
+2 -2 borogove/persistence/SqliteDriver.hx #
......@@ -14,7 +14,7 @@ class SqliteDriver {
1414 private var setReady: (Bool)->Void;
1515 private var setFailed: (Dynamic)->Void;
1616
17- public function new(dbfile: String, migrate: (Array<String>->Promise<haxe.iterators.ArrayIterator<Dynamic>>)->Promise<Any>) {
17+ public function new(dbfile: String, migrate: (Array<String>->Promise<Array<Dynamic>>)->Promise<Any>) {
1818 this.dbfile = dbfile;
1919 readPool = Config.constrainedMemoryMode ? writePool : new sys.thread.ElasticThreadPool(10);
2020 ready = new Promise((resolve, reject) -> {
......@@ -60,7 +60,7 @@ class SqliteDriver {
6060 final arr = { iterator: () -> result }.array();
6161 if (qs.length > 1) db.request("COMMIT");
6262 dbs.push(db);
63- resolve(arr.iterator());
63+ resolve(arr);
6464 } catch (e) {
6565 if (qs.length > 1) db.request("ROLLBACK");
6666 dbs.push(db);
+8 -8 borogove/persistence/SqliteDriver.js.hx #
......@@ -69,7 +69,7 @@ class SqliteDriver {
6969 return worker;
7070 }
7171
72- public function new(dbfile: String, migrate: (Array<String>->Promise<haxe.iterators.ArrayIterator<Dynamic>>)->Promise<Any>) {
72+ public function new(dbfile: String, migrate: (Array<String>->Promise<Array<Dynamic>>)->Promise<Any>) {
7373 ready = new Promise((resolve, reject) -> setReady = resolve);
7474
7575 writePool.push(mkWorker(dbfile, true));
......@@ -86,7 +86,7 @@ class SqliteDriver {
8686 });
8787 }
8888
89- private function execute(pool: Array<Worker>, qs: Array<{ sql: String, ?params: Array<Dynamic> }>): Promise<haxe.iterators.ArrayIterator<Dynamic>> {
89+ private function execute(pool: Array<Worker>, qs: Array<{ sql: String, ?params: Array<Dynamic> }>): Promise<Array<Dynamic>> {
9090 final worker = pool.pop();
9191 if (worker == null) {
9292 return new Promise((resolve, reject) -> haxe.Timer.delay(() -> resolve(null), 10)).then(_ ->
......@@ -98,11 +98,11 @@ class SqliteDriver {
9898 worker.postMessage({ id: id, qs: qs.map(q -> Sqlite.prepare(q)) });
9999 return promise.then(result -> {
100100 pool.push(worker);
101- return result.iterator();
101+ return result;
102102 });
103103 }
104104
105- public function execMany(qs: Array<{ sql: String, ?params: Array<Dynamic> }>): Promise<haxe.iterators.ArrayIterator<Dynamic>> {
105+ public function execMany(qs: Array<{ sql: String, ?params: Array<Dynamic> }>): Promise<Array<Dynamic>> {
106106 return ready.then(_ -> {
107107 final pool = StringTools.startsWith(qs[0].sql, "SELECT") ? readPool : writePool;
108108 return execute(pool, qs);
......@@ -126,7 +126,7 @@ class SqliteDriver {
126126 private final ready: Promise<Bool>;
127127 private var setReady: (Bool)->Void;
128128
129- public function new(dbfile: String, migrate: (Array<String>->Promise<haxe.iterators.ArrayIterator<Dynamic>>)->Promise<Any>) {
129+ public function new(dbfile: String, migrate: (Array<String>->Promise<Array<Dynamic>>)->Promise<Any>) {
130130 ready = new Promise((resolve, reject) -> setReady = resolve);
131131 Worker1.v2({
132132 worker: () -> new js.html.Worker(
......@@ -144,7 +144,7 @@ class SqliteDriver {
144144 });
145145 }
146146
147- private function execute(qs: Array<{ sql: String, ?params: Array<Dynamic> }>): Promise<haxe.iterators.ArrayIterator<Dynamic>> {
147+ private function execute(qs: Array<{ sql: String, ?params: Array<Dynamic> }>): Promise<Array<Dynamic>> {
148148 final first = qs.shift();
149149 final sql = qs.map(q -> Sqlite.prepare(q) + ";");
150150 final items: Array<Dynamic> = [];
......@@ -167,10 +167,10 @@ class SqliteDriver {
167167 }
168168 null;
169169 }
170- }).then(_ -> allDone).then(_ -> items.iterator());
170+ }).then(_ -> allDone).then(_ -> items);
171171 }
172172
173- public function execMany(qs: Array<{ sql: String, ?params: Array<Dynamic> }>): Promise<haxe.iterators.ArrayIterator<Dynamic>> {
173+ public function execMany(qs: Array<{ sql: String, ?params: Array<Dynamic> }>): Promise<Array<Dynamic>> {
174174 return ready.then(_ -> execute(qs));
175175 }
176176
+5 -5 test/TestSqlite.hx #
......@@ -607,7 +607,7 @@ class TestSqlite extends utest.Test {
607607 persistence.storeMessages(account, [correctable]).then(_ -> {
608608 return persistence.db.exec("SELECT correction_id FROM messages WHERE mam_id=?", [version.serverId]);
609609 }).then(rows -> {
610- final row = rows.next();
610+ final row = rows[0];
611611 Assert.equals("call-sid", row.correction_id);
612612 async.done();
613613 }).catchError(e -> {
......@@ -638,7 +638,7 @@ class TestSqlite extends utest.Test {
638638 persistence.storeMessages(account, [correctable]).then(_ -> {
639639 return persistence.db.exec("SELECT sync_point, chat_id, sender_id FROM messages WHERE mam_id=?", [version.serverId]);
640640 }).then(rows -> {
641- final row = rows.next();
641+ final row = rows[0];
642642 Assert.equals(1, row.sync_point);
643643 Assert.equals("correctable-chat@example.com", row.chat_id);
644644 Assert.equals("correctable@example.com", row.sender_id);
......@@ -666,7 +666,7 @@ class TestSqlite extends utest.Test {
666666 persistence.storeMessages(account, [correctable]).then(_ -> {
667667 return persistence.db.exec("SELECT correction_id FROM messages WHERE mam_id=?", [version.serverId]);
668668 }).then(rows -> {
669- Assert.equals("correctable-local-local", rows.next().correction_id);
669+ Assert.equals("correctable-local-local", rows[0].correction_id);
670670 async.done();
671671 }).catchError(e -> {
672672 Assert.fail(Std.string(e));
......@@ -690,7 +690,7 @@ class TestSqlite extends utest.Test {
690690 persistence.storeMessages(account, [correctable]).then(_ -> {
691691 return persistence.db.exec("SELECT correction_id FROM messages WHERE mam_id=?", [version.serverId]);
692692 }).then(rows -> {
693- Assert.equals("correctable-server-server", rows.next().correction_id);
693+ Assert.equals("correctable-server-server", rows[0].correction_id);
694694 async.done();
695695 }).catchError(e -> {
696696 Assert.fail(Std.string(e));
......@@ -709,7 +709,7 @@ class TestSqlite extends utest.Test {
709709 persistence.storeMessages(account, [message]).then(_ -> {
710710 return persistence.db.exec("SELECT strftime('%FT%H:%M:%fZ', time_received / 1000.0, 'unixepoch') AS time_received FROM messages WHERE mam_id=?", [message.serverId]);
711711 }).then(rows -> {
712- Assert.equals("2020-01-01T00:00:00.123Z", rows.next().time_received);
712+ Assert.equals("2020-01-01T00:00:00.123Z", rows[0].time_received);
713713 async.done();
714714 }).catchError(e -> {
715715 Assert.fail(Std.string(e));
Back to top