|
6 | 6 | RunResults, |
7 | 7 | SqliteDriverConnection, |
8 | 8 | SqliteDriverConnectionPool, |
| 9 | + UpdateListener, |
9 | 10 | } from "../driver-api.js"; |
10 | 11 | const Database = require("better-sqlite3"); |
11 | 12 |
|
@@ -118,4 +119,46 @@ export class BetterSqliteConnection implements SqliteDriverConnection { |
118 | 119 | dispose(): void { |
119 | 120 | // No-op |
120 | 121 | } |
| 122 | + |
| 123 | + onUpdate( |
| 124 | + listener: UpdateListener, |
| 125 | + options?: |
| 126 | + | { tables?: string[] | undefined; batchLimit?: number | undefined } |
| 127 | + | undefined |
| 128 | + ): () => void { |
| 129 | + // Proof-of-concept implementation, based on the idea here: |
| 130 | + // https://github.com/WiseLibs/better-sqlite3/issues/62 |
| 131 | + // TODO: |
| 132 | + // 1. Handle multiple registrations. |
| 133 | + // 2. Don't re-register triggers. |
| 134 | + // 3. De-register listener. |
| 135 | + // 4. Batching. |
| 136 | + // |
| 137 | + // More fundamental limitations: |
| 138 | + // 1. The table needs to exist before registering the listener. |
| 139 | + // 2. Deleting and re-creating the same will dereigster the listener for that table. |
| 140 | + |
| 141 | + this.con.function("_logger", function (table: any, type: any, rowid: any) { |
| 142 | + listener({ events: [{ table, rowId: rowid, type }] }); |
| 143 | + }); |
| 144 | + let tables = options?.tables; |
| 145 | + if (tables == null) { |
| 146 | + tables = this.con |
| 147 | + .prepare(`select name from sqlite_master where type = 'table'`) |
| 148 | + .all() |
| 149 | + .map((row) => (row as any).name as string); |
| 150 | + } |
| 151 | + for (let table of tables) { |
| 152 | + this.con.exec( |
| 153 | + `CREATE TEMPORARY TRIGGER IF NOT EXISTS _logger_notification_${table}__update AFTER UPDATE ON ${table} BEGIN SELECT _logger('${table}', 'update', NEW.rowid); END` |
| 154 | + ); |
| 155 | + this.con.exec( |
| 156 | + `CREATE TEMPORARY TRIGGER IF NOT EXISTS _logger_notification_${table}__insert AFTER INSERT ON ${table} BEGIN SELECT _logger('${table}', 'insert', NEW.rowid); END` |
| 157 | + ); |
| 158 | + this.con.exec( |
| 159 | + `CREATE TEMPORARY TRIGGER IF NOT EXISTS _logger_notification_${table}__delete AFTER DELETE ON ${table} BEGIN SELECT _logger('${table}', 'delete', OLD.rowid); END` |
| 160 | + ); |
| 161 | + } |
| 162 | + return () => {}; |
| 163 | + } |
121 | 164 | } |
0 commit comments