@livestore/wa-sqlite 0.4.0-dev.22 → 0.4.0-dev.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -36
- package/dist/README.md +13 -13
- package/dist/fts5/wa-sqlite.mjs +1 -1
- package/dist/fts5/wa-sqlite.node.mjs +1 -1
- package/dist/fts5/wa-sqlite.node.wasm +0 -0
- package/dist/fts5/wa-sqlite.wasm +0 -0
- package/dist/wa-sqlite-async.mjs +1 -1
- package/dist/wa-sqlite-async.wasm +0 -0
- package/dist/wa-sqlite-jspi.mjs +1 -1
- package/dist/wa-sqlite-jspi.wasm +0 -0
- package/dist/wa-sqlite.mjs +1 -1
- package/dist/wa-sqlite.node.mjs +1 -1
- package/dist/wa-sqlite.node.wasm +0 -0
- package/dist/wa-sqlite.wasm +0 -0
- package/package.json +40 -29
- package/src/FacadeVFS.js +252 -261
- package/src/VFS.js +84 -85
- package/src/WebLocksMixin.js +357 -351
- package/src/examples/AccessHandlePoolVFS.js +185 -194
- package/src/examples/IDBBatchAtomicVFS.js +429 -409
- package/src/examples/IDBMirrorVFS.js +402 -409
- package/src/examples/MemoryAsyncVFS.js +32 -37
- package/src/examples/MemoryVFS.js +71 -75
- package/src/examples/OPFSAdaptiveVFS.js +206 -206
- package/src/examples/OPFSAnyContextVFS.js +141 -140
- package/src/examples/OPFSCoopSyncVFS.js +297 -299
- package/src/examples/OPFSPermutedVFS.js +529 -540
- package/src/examples/README.md +27 -15
- package/src/examples/tag.js +27 -27
- package/src/sqlite-api.js +910 -941
- package/src/sqlite-constants.js +246 -232
- package/src/types/globals.d.ts +52 -52
- package/src/types/index.d.ts +586 -576
- package/test/AccessHandlePoolVFS.test.js +21 -21
- package/test/IDBBatchAtomicVFS.test.js +69 -69
- package/test/IDBMirrorVFS.test.js +21 -21
- package/test/MemoryAsyncVFS.test.js +21 -21
- package/test/MemoryVFS.test.js +21 -21
- package/test/OPFSAdaptiveVFS.test.js +21 -21
- package/test/OPFSAnyContextVFS.test.js +21 -21
- package/test/OPFSCoopSyncVFS.test.js +21 -21
- package/test/OPFSPermutedVFS.test.js +21 -21
- package/test/TestContext.js +44 -41
- package/test/WebLocksMixin.test.js +369 -360
- package/test/api.test.js +23 -23
- package/test/api_exec.js +72 -61
- package/test/api_misc.js +53 -54
- package/test/api_statements.js +271 -279
- package/test/callbacks.test.js +492 -478
- package/test/data/idbv5.json +1135 -1
- package/test/sql.test.js +30 -30
- package/test/sql_0001.js +49 -33
- package/test/sql_0002.js +55 -34
- package/test/sql_0003.js +85 -49
- package/test/sql_0004.js +76 -47
- package/test/sql_0005.js +60 -44
- package/test/test-worker.js +171 -163
- package/test/vfs_xAccess.js +1 -2
- package/test/vfs_xClose.js +50 -49
- package/test/vfs_xOpen.js +73 -72
- package/test/vfs_xRead.js +31 -31
- package/test/vfs_xWrite.js +30 -29
package/test/callbacks.test.js
CHANGED
|
@@ -1,286 +1,255 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
import * as SQLite from '../src/sqlite-api.js'
|
|
1
|
+
import AsyncifyFactory from 'wa-sqlite/dist/wa-sqlite-async.mjs'
|
|
2
|
+
import JSPIFactory from 'wa-sqlite/dist/wa-sqlite-jspi.mjs'
|
|
3
|
+
|
|
4
|
+
import * as SQLite from '../src/sqlite-api.js'
|
|
5
|
+
import { TestContext } from './TestContext.js'
|
|
5
6
|
|
|
6
7
|
const FACTORIES = new Map([
|
|
7
8
|
['asyncify', AsyncifyFactory],
|
|
8
|
-
['jspi', JSPIFactory]
|
|
9
|
-
])
|
|
9
|
+
['jspi', JSPIFactory],
|
|
10
|
+
])
|
|
10
11
|
|
|
11
|
-
const supportsJSPI = await TestContext.supportsJSPI()
|
|
12
|
+
const supportsJSPI = await TestContext.supportsJSPI()
|
|
12
13
|
|
|
13
14
|
for (const [key, factory] of FACTORIES) {
|
|
14
|
-
if (key === 'jspi' && !supportsJSPI) continue
|
|
15
|
-
|
|
16
|
-
const sqlite3 = await factory().then(module => SQLite.Factory(module))
|
|
17
|
-
describe(`${key} create_function`, function() {
|
|
18
|
-
let db
|
|
19
|
-
beforeEach(async function() {
|
|
20
|
-
db = await sqlite3.open_v2(':memory:')
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
afterEach(async function() {
|
|
24
|
-
await sqlite3.close(db)
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
it('should return an int', async function() {
|
|
28
|
-
let rc
|
|
29
|
-
|
|
30
|
-
rc = await sqlite3.create_function(
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
expect(
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
rc = await sqlite3.create_function(
|
|
50
|
-
db,
|
|
51
|
-
'fn',
|
|
52
|
-
0,
|
|
53
|
-
SQLite.SQLITE_DETERMINISTIC, 0,
|
|
54
|
-
(function(context, values) {
|
|
55
|
-
sqlite3.result_int64(context, 0x7FFF_FFFF_FFFF_FFFFn);
|
|
56
|
-
}));
|
|
57
|
-
expect(rc).toEqual(SQLite.SQLITE_OK);
|
|
58
|
-
|
|
15
|
+
if (key === 'jspi' && !supportsJSPI) continue
|
|
16
|
+
|
|
17
|
+
const sqlite3 = await factory().then((module) => SQLite.Factory(module))
|
|
18
|
+
describe(`${key} create_function`, function () {
|
|
19
|
+
let db
|
|
20
|
+
beforeEach(async function () {
|
|
21
|
+
db = await sqlite3.open_v2(':memory:')
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
afterEach(async function () {
|
|
25
|
+
await sqlite3.close(db)
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
it('should return an int', async function () {
|
|
29
|
+
let rc
|
|
30
|
+
|
|
31
|
+
rc = await sqlite3.create_function(db, 'fn', 0, SQLite.SQLITE_DETERMINISTIC, 0, function (context, values) {
|
|
32
|
+
sqlite3.result_int(context, 42)
|
|
33
|
+
})
|
|
34
|
+
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
35
|
+
|
|
36
|
+
let result
|
|
37
|
+
rc = await sqlite3.exec(db, 'SELECT fn()', (row) => (result = row[0]))
|
|
38
|
+
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
39
|
+
expect(result).toEqual(42)
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
it('should return an int64', async function () {
|
|
43
|
+
let rc
|
|
44
|
+
|
|
45
|
+
rc = await sqlite3.create_function(db, 'fn', 0, SQLite.SQLITE_DETERMINISTIC, 0, function (context, values) {
|
|
46
|
+
sqlite3.result_int64(context, 0x7fff_ffff_ffff_ffffn)
|
|
47
|
+
})
|
|
48
|
+
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
49
|
+
|
|
59
50
|
for await (const stmt of sqlite3.statements(db, 'SELECT fn()')) {
|
|
60
|
-
while (await sqlite3.step(stmt) === SQLite.SQLITE_ROW) {
|
|
61
|
-
const value = sqlite3.column_int64(stmt, 0)
|
|
62
|
-
expect(value).toEqual(
|
|
51
|
+
while ((await sqlite3.step(stmt)) === SQLite.SQLITE_ROW) {
|
|
52
|
+
const value = sqlite3.column_int64(stmt, 0)
|
|
53
|
+
expect(value).toEqual(0x7fff_ffff_ffff_ffffn)
|
|
63
54
|
}
|
|
64
55
|
}
|
|
65
|
-
})
|
|
66
|
-
|
|
67
|
-
it('should return a double', async function() {
|
|
68
|
-
let rc
|
|
69
|
-
|
|
70
|
-
rc = await sqlite3.create_function(
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
expect(
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
it('should return a double', async function () {
|
|
59
|
+
let rc
|
|
60
|
+
|
|
61
|
+
rc = await sqlite3.create_function(db, 'fn', 0, SQLite.SQLITE_DETERMINISTIC, 0, function (context, values) {
|
|
62
|
+
sqlite3.result_double(context, 3.14)
|
|
63
|
+
})
|
|
64
|
+
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
65
|
+
|
|
66
|
+
let result
|
|
67
|
+
rc = await sqlite3.exec(db, 'SELECT fn()', (row) => (result = row[0]))
|
|
68
|
+
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
69
|
+
expect(result).toEqual(3.14)
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
it('should return a string', async function () {
|
|
73
|
+
let rc
|
|
74
|
+
|
|
75
|
+
rc = await sqlite3.create_function(db, 'fn', 0, SQLite.SQLITE_DETERMINISTIC, 0, function (context, values) {
|
|
76
|
+
sqlite3.result_text(context, 'foobar')
|
|
77
|
+
})
|
|
78
|
+
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
79
|
+
|
|
80
|
+
let result
|
|
81
|
+
rc = await sqlite3.exec(db, 'SELECT fn()', (row) => (result = row[0]))
|
|
82
|
+
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
83
|
+
expect(result).toEqual('foobar')
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
it('should return a blob', async function () {
|
|
87
|
+
let rc
|
|
88
|
+
|
|
89
|
+
rc = await sqlite3.create_function(db, 'fn', 0, SQLite.SQLITE_DETERMINISTIC, 0, function (context, values) {
|
|
90
|
+
sqlite3.result_blob(context, new Uint8Array([0x12, 0x34, 0x56]))
|
|
91
|
+
})
|
|
92
|
+
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
93
|
+
|
|
94
|
+
let result
|
|
95
|
+
rc = await sqlite3.exec(db, 'SELECT fn()', (row) => (result = row[0]))
|
|
96
|
+
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
97
|
+
expect(result).toEqual(new Uint8Array([0x12, 0x34, 0x56]))
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
it('should return null', async function () {
|
|
101
|
+
let rc
|
|
102
|
+
|
|
103
|
+
rc = await sqlite3.create_function(db, 'fn', 0, SQLite.SQLITE_DETERMINISTIC, 0, function (context, values) {
|
|
104
|
+
sqlite3.result_null(context)
|
|
105
|
+
})
|
|
106
|
+
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
107
|
+
|
|
108
|
+
let result
|
|
109
|
+
rc = await sqlite3.exec(db, 'SELECT fn()', (row) => (result = row[0]))
|
|
110
|
+
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
111
|
+
expect(result).toEqual(null)
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
it('should pass a fixed number of arguments', async function () {
|
|
115
|
+
let rc
|
|
116
|
+
|
|
117
|
+
rc = await sqlite3.create_function(db, 'fn', 5, SQLite.SQLITE_DETERMINISTIC, 0, function (context, values) {
|
|
118
|
+
expect(sqlite3.value_type(values[0])).toEqual(SQLite.SQLITE_INTEGER)
|
|
119
|
+
expect(sqlite3.value_int(values[0])).toEqual(42)
|
|
120
|
+
expect(sqlite3.value_int64(values[0])).toEqual(42n)
|
|
121
|
+
expect(sqlite3.value(values[0])).toEqual(42)
|
|
122
|
+
|
|
123
|
+
expect(sqlite3.value_type(values[1])).toEqual(SQLite.SQLITE_FLOAT)
|
|
124
|
+
expect(sqlite3.value_double(values[1])).toEqual(3.14)
|
|
125
|
+
expect(sqlite3.value(values[1])).toEqual(3.14)
|
|
126
|
+
|
|
127
|
+
expect(sqlite3.value_type(values[2])).toEqual(SQLite.SQLITE_TEXT)
|
|
128
|
+
expect(sqlite3.value_text(values[2])).toEqual('hello')
|
|
129
|
+
expect(sqlite3.value(values[2])).toEqual('hello')
|
|
130
|
+
|
|
131
|
+
expect(sqlite3.value_type(values[3])).toEqual(SQLite.SQLITE_BLOB)
|
|
132
|
+
expect(sqlite3.value_blob(values[3])).toEqual(new Uint8Array([0x12, 0x34, 0x56]))
|
|
133
|
+
expect(sqlite3.value_bytes(values[3])).toEqual(3)
|
|
134
|
+
expect(sqlite3.value(values[3])).toEqual(new Uint8Array([0x12, 0x34, 0x56]))
|
|
135
|
+
|
|
136
|
+
expect(sqlite3.value_type(values[4])).toEqual(SQLite.SQLITE_NULL)
|
|
137
|
+
})
|
|
138
|
+
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
139
|
+
|
|
140
|
+
rc = await sqlite3.exec(
|
|
90
141
|
db,
|
|
91
|
-
|
|
92
|
-
0,
|
|
93
|
-
SQLite.SQLITE_DETERMINISTIC, 0,
|
|
94
|
-
(function(context, values) {
|
|
95
|
-
sqlite3.result_text(context, 'foobar');
|
|
96
|
-
}));
|
|
97
|
-
expect(rc).toEqual(SQLite.SQLITE_OK);
|
|
98
|
-
|
|
99
|
-
let result;
|
|
100
|
-
rc = await sqlite3.exec(db, 'SELECT fn()', row => result = row[0]);
|
|
101
|
-
expect(rc).toEqual(SQLite.SQLITE_OK);
|
|
102
|
-
expect(result).toEqual('foobar');
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
it('should return a blob', async function() {
|
|
106
|
-
let rc;
|
|
107
|
-
|
|
108
|
-
rc = await sqlite3.create_function(
|
|
109
|
-
db,
|
|
110
|
-
'fn',
|
|
111
|
-
0,
|
|
112
|
-
SQLite.SQLITE_DETERMINISTIC, 0,
|
|
113
|
-
(function(context, values) {
|
|
114
|
-
sqlite3.result_blob(context, new Uint8Array([0x12, 0x34, 0x56]));
|
|
115
|
-
}));
|
|
116
|
-
expect(rc).toEqual(SQLite.SQLITE_OK);
|
|
117
|
-
|
|
118
|
-
let result;
|
|
119
|
-
rc = await sqlite3.exec(db, 'SELECT fn()', row => result = row[0]);
|
|
120
|
-
expect(rc).toEqual(SQLite.SQLITE_OK);
|
|
121
|
-
expect(result).toEqual(new Uint8Array([0x12, 0x34, 0x56]));
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
it('should return null', async function() {
|
|
125
|
-
let rc;
|
|
126
|
-
|
|
127
|
-
rc = await sqlite3.create_function(
|
|
128
|
-
db,
|
|
129
|
-
'fn',
|
|
130
|
-
0,
|
|
131
|
-
SQLite.SQLITE_DETERMINISTIC, 0,
|
|
132
|
-
(function(context, values) {
|
|
133
|
-
sqlite3.result_null(context);
|
|
134
|
-
}));
|
|
135
|
-
expect(rc).toEqual(SQLite.SQLITE_OK);
|
|
136
|
-
|
|
137
|
-
let result;
|
|
138
|
-
rc = await sqlite3.exec(db, 'SELECT fn()', row => result = row[0]);
|
|
139
|
-
expect(rc).toEqual(SQLite.SQLITE_OK);
|
|
140
|
-
expect(result).toEqual(null);
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
it('should pass a fixed number of arguments', async function() {
|
|
144
|
-
let rc;
|
|
145
|
-
|
|
146
|
-
rc = await sqlite3.create_function(
|
|
147
|
-
db,
|
|
148
|
-
'fn',
|
|
149
|
-
5,
|
|
150
|
-
SQLite.SQLITE_DETERMINISTIC, 0,
|
|
151
|
-
(function(context, values) {
|
|
152
|
-
expect(sqlite3.value_type(values[0])).toEqual(SQLite.SQLITE_INTEGER);
|
|
153
|
-
expect(sqlite3.value_int(values[0])).toEqual(42);
|
|
154
|
-
expect(sqlite3.value_int64(values[0])).toEqual(42n);
|
|
155
|
-
expect(sqlite3.value(values[0])).toEqual(42);
|
|
156
|
-
|
|
157
|
-
expect(sqlite3.value_type(values[1])).toEqual(SQLite.SQLITE_FLOAT);
|
|
158
|
-
expect(sqlite3.value_double(values[1])).toEqual(3.14);
|
|
159
|
-
expect(sqlite3.value(values[1])).toEqual(3.14);
|
|
160
|
-
|
|
161
|
-
expect(sqlite3.value_type(values[2])).toEqual(SQLite.SQLITE_TEXT);
|
|
162
|
-
expect(sqlite3.value_text(values[2])).toEqual('hello');
|
|
163
|
-
expect(sqlite3.value(values[2])).toEqual('hello');
|
|
164
|
-
|
|
165
|
-
expect(sqlite3.value_type(values[3])).toEqual(SQLite.SQLITE_BLOB);
|
|
166
|
-
expect(sqlite3.value_blob(values[3])).toEqual(new Uint8Array([0x12, 0x34, 0x56]));
|
|
167
|
-
expect(sqlite3.value_bytes(values[3])).toEqual(3);
|
|
168
|
-
expect(sqlite3.value(values[3])).toEqual(new Uint8Array([0x12, 0x34, 0x56]));
|
|
169
|
-
|
|
170
|
-
expect(sqlite3.value_type(values[4])).toEqual(SQLite.SQLITE_NULL);
|
|
171
|
-
}));
|
|
172
|
-
expect(rc).toEqual(SQLite.SQLITE_OK);
|
|
173
|
-
|
|
174
|
-
rc = await sqlite3.exec(db, `
|
|
142
|
+
`
|
|
175
143
|
SELECT fn(42, 3.14, 'hello', x'123456', NULL)
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
144
|
+
`,
|
|
145
|
+
)
|
|
146
|
+
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
it('should pass a variable number of arguments', async function () {
|
|
150
|
+
let rc
|
|
151
|
+
|
|
152
|
+
rc = await sqlite3.create_function(db, 'fn', -1, SQLite.SQLITE_DETERMINISTIC, 0, function (context, values) {
|
|
153
|
+
expect(values.length).toBe(5)
|
|
154
|
+
|
|
155
|
+
expect(sqlite3.value_type(values[0])).toEqual(SQLite.SQLITE_INTEGER)
|
|
156
|
+
expect(sqlite3.value_int(values[0])).toEqual(42)
|
|
157
|
+
expect(sqlite3.value_int64(values[0])).toEqual(42n)
|
|
158
|
+
expect(sqlite3.value_double(values[0])).toEqual(42.0)
|
|
159
|
+
expect(sqlite3.value(values[0])).toEqual(42)
|
|
160
|
+
|
|
161
|
+
expect(sqlite3.value_type(values[1])).toEqual(SQLite.SQLITE_FLOAT)
|
|
162
|
+
expect(sqlite3.value_double(values[1])).toEqual(3.14)
|
|
163
|
+
expect(sqlite3.value(values[1])).toEqual(3.14)
|
|
164
|
+
|
|
165
|
+
expect(sqlite3.value_type(values[2])).toEqual(SQLite.SQLITE_TEXT)
|
|
166
|
+
expect(sqlite3.value_text(values[2])).toEqual('hello')
|
|
167
|
+
expect(sqlite3.value(values[2])).toEqual('hello')
|
|
168
|
+
|
|
169
|
+
expect(sqlite3.value_type(values[3])).toEqual(SQLite.SQLITE_BLOB)
|
|
170
|
+
expect(sqlite3.value_blob(values[3])).toEqual(new Uint8Array([0x12, 0x34, 0x56]))
|
|
171
|
+
expect(sqlite3.value_bytes(values[3])).toEqual(3)
|
|
172
|
+
expect(sqlite3.value(values[3])).toEqual(new Uint8Array([0x12, 0x34, 0x56]))
|
|
173
|
+
|
|
174
|
+
expect(sqlite3.value_type(values[4])).toEqual(SQLite.SQLITE_NULL)
|
|
175
|
+
})
|
|
176
|
+
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
177
|
+
|
|
178
|
+
rc = await sqlite3.exec(
|
|
184
179
|
db,
|
|
185
|
-
|
|
186
|
-
-1,
|
|
187
|
-
SQLite.SQLITE_DETERMINISTIC, 0,
|
|
188
|
-
(function(context, values) {
|
|
189
|
-
expect(values.length).toBe(5);
|
|
190
|
-
|
|
191
|
-
expect(sqlite3.value_type(values[0])).toEqual(SQLite.SQLITE_INTEGER);
|
|
192
|
-
expect(sqlite3.value_int(values[0])).toEqual(42);
|
|
193
|
-
expect(sqlite3.value_int64(values[0])).toEqual(42n);
|
|
194
|
-
expect(sqlite3.value_double(values[0])).toEqual(42.0);
|
|
195
|
-
expect(sqlite3.value(values[0])).toEqual(42);
|
|
196
|
-
|
|
197
|
-
expect(sqlite3.value_type(values[1])).toEqual(SQLite.SQLITE_FLOAT);
|
|
198
|
-
expect(sqlite3.value_double(values[1])).toEqual(3.14);
|
|
199
|
-
expect(sqlite3.value(values[1])).toEqual(3.14);
|
|
200
|
-
|
|
201
|
-
expect(sqlite3.value_type(values[2])).toEqual(SQLite.SQLITE_TEXT);
|
|
202
|
-
expect(sqlite3.value_text(values[2])).toEqual('hello');
|
|
203
|
-
expect(sqlite3.value(values[2])).toEqual('hello');
|
|
204
|
-
|
|
205
|
-
expect(sqlite3.value_type(values[3])).toEqual(SQLite.SQLITE_BLOB);
|
|
206
|
-
expect(sqlite3.value_blob(values[3])).toEqual(new Uint8Array([0x12, 0x34, 0x56]));
|
|
207
|
-
expect(sqlite3.value_bytes(values[3])).toEqual(3);
|
|
208
|
-
expect(sqlite3.value(values[3])).toEqual(new Uint8Array([0x12, 0x34, 0x56]));
|
|
209
|
-
|
|
210
|
-
expect(sqlite3.value_type(values[4])).toEqual(SQLite.SQLITE_NULL);
|
|
211
|
-
}));
|
|
212
|
-
expect(rc).toEqual(SQLite.SQLITE_OK);
|
|
213
|
-
|
|
214
|
-
rc = await sqlite3.exec(db, `
|
|
180
|
+
`
|
|
215
181
|
SELECT fn(42, 3.14, 'hello', x'123456', NULL)
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
182
|
+
`,
|
|
183
|
+
)
|
|
184
|
+
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
it('should create an aggregate function', async function () {
|
|
188
|
+
let rc
|
|
189
|
+
|
|
190
|
+
let product = 1
|
|
224
191
|
rc = await sqlite3.create_function(
|
|
225
192
|
db,
|
|
226
193
|
'fn',
|
|
227
194
|
1,
|
|
228
|
-
SQLite.SQLITE_DETERMINISTIC,
|
|
195
|
+
SQLite.SQLITE_DETERMINISTIC,
|
|
196
|
+
0,
|
|
229
197
|
null,
|
|
230
|
-
|
|
231
|
-
const value = sqlite3.value_double(values[0])
|
|
232
|
-
product *= value
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
sqlite3.result_double(context, product)
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
198
|
+
function (context, values) {
|
|
199
|
+
const value = sqlite3.value_double(values[0])
|
|
200
|
+
product *= value
|
|
201
|
+
},
|
|
202
|
+
function (context) {
|
|
203
|
+
sqlite3.result_double(context, product)
|
|
204
|
+
},
|
|
205
|
+
)
|
|
206
|
+
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
207
|
+
|
|
208
|
+
rc = await sqlite3.exec(
|
|
209
|
+
db,
|
|
210
|
+
`
|
|
240
211
|
SELECT fn(column1) FROM (VALUES (1), (2), (3), (4), (5));
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
expect(
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
212
|
+
`,
|
|
213
|
+
)
|
|
214
|
+
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
215
|
+
expect(product).toEqual(1 * 2 * 3 * 4 * 5)
|
|
216
|
+
})
|
|
217
|
+
|
|
218
|
+
it('should return asynchronously', async function () {
|
|
219
|
+
let rc
|
|
220
|
+
|
|
221
|
+
rc = await sqlite3.create_function(db, 'fn', 0, SQLite.SQLITE_DETERMINISTIC, 0, async (context, values) => {
|
|
222
|
+
await new Promise((resolve) => setTimeout(resolve))
|
|
223
|
+
sqlite3.result_int(context, 42)
|
|
224
|
+
})
|
|
225
|
+
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
226
|
+
|
|
227
|
+
let result
|
|
228
|
+
rc = await sqlite3.exec(db, 'SELECT fn()', (row) => (result = row[0]))
|
|
229
|
+
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
230
|
+
expect(result).toEqual(42)
|
|
231
|
+
})
|
|
232
|
+
})
|
|
233
|
+
|
|
234
|
+
describe(`${key} progress_handler`, function () {
|
|
235
|
+
let db
|
|
236
|
+
beforeEach(async function () {
|
|
237
|
+
db = await sqlite3.open_v2(':memory:')
|
|
238
|
+
})
|
|
239
|
+
|
|
240
|
+
afterEach(async function () {
|
|
241
|
+
await sqlite3.close(db)
|
|
242
|
+
})
|
|
243
|
+
|
|
244
|
+
it('should call progress handler', async function () {
|
|
245
|
+
let rc
|
|
246
|
+
|
|
247
|
+
let count = 0
|
|
248
|
+
await sqlite3.progress_handler(db, 1, () => ++count && 0, null)
|
|
249
|
+
|
|
250
|
+
rc = await sqlite3.exec(
|
|
250
251
|
db,
|
|
251
|
-
|
|
252
|
-
0,
|
|
253
|
-
SQLite.SQLITE_DETERMINISTIC, 0,
|
|
254
|
-
async (context, values) => {
|
|
255
|
-
await new Promise(resolve => setTimeout(resolve));
|
|
256
|
-
sqlite3.result_int(context, 42);
|
|
257
|
-
});
|
|
258
|
-
expect(rc).toEqual(SQLite.SQLITE_OK);
|
|
259
|
-
|
|
260
|
-
let result;
|
|
261
|
-
rc = await sqlite3.exec(db, 'SELECT fn()', row => result = row[0]);
|
|
262
|
-
expect(rc).toEqual(SQLite.SQLITE_OK);
|
|
263
|
-
expect(result).toEqual(42);
|
|
264
|
-
});
|
|
265
|
-
});
|
|
266
|
-
|
|
267
|
-
describe(`${key} progress_handler`, function() {
|
|
268
|
-
let db;
|
|
269
|
-
beforeEach(async function() {
|
|
270
|
-
db = await sqlite3.open_v2(':memory:');
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
afterEach(async function() {
|
|
274
|
-
await sqlite3.close(db);
|
|
275
|
-
});
|
|
276
|
-
|
|
277
|
-
it('should call progress handler', async function() {
|
|
278
|
-
let rc;
|
|
279
|
-
|
|
280
|
-
let count = 0;
|
|
281
|
-
await sqlite3.progress_handler(db, 1, () => ++count && 0, null);
|
|
282
|
-
|
|
283
|
-
rc = await sqlite3.exec(db, `
|
|
252
|
+
`
|
|
284
253
|
CREATE TABLE t AS
|
|
285
254
|
WITH RECURSIVE cnt(x) AS (
|
|
286
255
|
SELECT 1
|
|
@@ -289,18 +258,21 @@ for (const [key, factory] of FACTORIES) {
|
|
|
289
258
|
LIMIT 100
|
|
290
259
|
)
|
|
291
260
|
SELECT x FROM cnt;
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
expect(
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
261
|
+
`,
|
|
262
|
+
)
|
|
263
|
+
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
264
|
+
expect(count).toBeGreaterThan(0)
|
|
265
|
+
})
|
|
266
|
+
|
|
267
|
+
it('should call asynchronous progress handler', async function () {
|
|
268
|
+
let rc
|
|
269
|
+
|
|
270
|
+
let count = 0
|
|
271
|
+
await sqlite3.progress_handler(db, 1, async () => ++count && 0, null)
|
|
272
|
+
|
|
273
|
+
rc = await sqlite3.exec(
|
|
274
|
+
db,
|
|
275
|
+
`
|
|
304
276
|
CREATE TABLE t AS
|
|
305
277
|
WITH RECURSIVE cnt(x) AS (
|
|
306
278
|
SELECT 1
|
|
@@ -309,273 +281,315 @@ for (const [key, factory] of FACTORIES) {
|
|
|
309
281
|
LIMIT 100
|
|
310
282
|
)
|
|
311
283
|
SELECT x FROM cnt;
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
expect(
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
284
|
+
`,
|
|
285
|
+
)
|
|
286
|
+
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
287
|
+
expect(count).toBeGreaterThan(0)
|
|
288
|
+
})
|
|
289
|
+
})
|
|
290
|
+
|
|
291
|
+
describe(`${key} set_authorizer`, function () {
|
|
292
|
+
let db
|
|
293
|
+
beforeEach(async function () {
|
|
294
|
+
db = await sqlite3.open_v2(':memory:')
|
|
295
|
+
})
|
|
296
|
+
|
|
297
|
+
afterEach(async function () {
|
|
298
|
+
await sqlite3.close(db)
|
|
299
|
+
})
|
|
300
|
+
|
|
301
|
+
it('should call authorizer', async function () {
|
|
302
|
+
let rc
|
|
303
|
+
|
|
304
|
+
const authorizations = []
|
|
332
305
|
rc = sqlite3.set_authorizer(db, (_, iActionCode, p3, p4, p5, p6) => {
|
|
333
|
-
authorizations.push([iActionCode, p3, p4, p5, p6])
|
|
334
|
-
return SQLite.SQLITE_OK
|
|
335
|
-
})
|
|
336
|
-
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
306
|
+
authorizations.push([iActionCode, p3, p4, p5, p6])
|
|
307
|
+
return SQLite.SQLITE_OK
|
|
308
|
+
})
|
|
309
|
+
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
337
310
|
|
|
338
|
-
rc = await sqlite3.exec(db, 'CREATE TABLE t(x)')
|
|
339
|
-
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
311
|
+
rc = await sqlite3.exec(db, 'CREATE TABLE t(x)')
|
|
312
|
+
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
340
313
|
|
|
341
|
-
let authCreateTable = false
|
|
314
|
+
let authCreateTable = false
|
|
342
315
|
for (const authorization of authorizations) {
|
|
343
316
|
switch (authorization[0]) {
|
|
344
317
|
case SQLite.SQLITE_CREATE_TABLE:
|
|
345
|
-
authCreateTable = true
|
|
346
|
-
expect(authorization[1]).toEqual('t')
|
|
347
|
-
expect(authorization[2]).toEqual('')
|
|
348
|
-
expect(authorization[3]).toEqual('main')
|
|
349
|
-
expect(authorization[4]).toEqual('')
|
|
350
|
-
break
|
|
318
|
+
authCreateTable = true
|
|
319
|
+
expect(authorization[1]).toEqual('t')
|
|
320
|
+
expect(authorization[2]).toEqual('')
|
|
321
|
+
expect(authorization[3]).toEqual('main')
|
|
322
|
+
expect(authorization[4]).toEqual('')
|
|
323
|
+
break
|
|
351
324
|
}
|
|
352
325
|
}
|
|
353
|
-
expect(authCreateTable).toBeTrue()
|
|
354
|
-
})
|
|
326
|
+
expect(authCreateTable).toBeTrue()
|
|
327
|
+
})
|
|
355
328
|
|
|
356
|
-
it('should deny authorization', async function() {
|
|
357
|
-
let rc
|
|
329
|
+
it('should deny authorization', async function () {
|
|
330
|
+
let rc
|
|
358
331
|
|
|
359
332
|
rc = sqlite3.set_authorizer(db, (_, iActionCode, p3, p4, p5, p6) => {
|
|
360
|
-
return SQLite.SQLITE_DENY
|
|
361
|
-
})
|
|
362
|
-
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
333
|
+
return SQLite.SQLITE_DENY
|
|
334
|
+
})
|
|
335
|
+
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
363
336
|
|
|
364
|
-
const result = sqlite3.exec(db, 'CREATE TABLE t(x)')
|
|
365
|
-
await expectAsync(result).toBeRejectedWith(new Error('not authorized'))
|
|
366
|
-
})
|
|
337
|
+
const result = sqlite3.exec(db, 'CREATE TABLE t(x)')
|
|
338
|
+
await expectAsync(result).toBeRejectedWith(new Error('not authorized'))
|
|
339
|
+
})
|
|
367
340
|
|
|
368
|
-
it('should call async authorizer', async function() {
|
|
369
|
-
let rc
|
|
341
|
+
it('should call async authorizer', async function () {
|
|
342
|
+
let rc
|
|
370
343
|
|
|
371
|
-
const authorizations = []
|
|
344
|
+
const authorizations = []
|
|
372
345
|
rc = sqlite3.set_authorizer(db, async (_, iActionCode, p3, p4, p5, p6) => {
|
|
373
|
-
authorizations.push([iActionCode, p3, p4, p5, p6])
|
|
374
|
-
return SQLite.SQLITE_OK
|
|
375
|
-
})
|
|
376
|
-
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
377
|
-
|
|
378
|
-
rc = await sqlite3.exec(db, 'CREATE TABLE t(x)')
|
|
379
|
-
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
380
|
-
|
|
381
|
-
expect(authorizations.length).toBeGreaterThan(0)
|
|
382
|
-
})
|
|
383
|
-
})
|
|
384
|
-
|
|
385
|
-
describe(`${key} update_hook`, function() {
|
|
386
|
-
let db
|
|
387
|
-
beforeEach(async function() {
|
|
388
|
-
db = await sqlite3.open_v2(':memory:')
|
|
389
|
-
})
|
|
390
|
-
|
|
391
|
-
afterEach(async function() {
|
|
392
|
-
await sqlite3.close(db)
|
|
393
|
-
})
|
|
394
|
-
|
|
395
|
-
it('should call update hook', async function() {
|
|
396
|
-
let rc
|
|
397
|
-
|
|
398
|
-
let calls = []
|
|
346
|
+
authorizations.push([iActionCode, p3, p4, p5, p6])
|
|
347
|
+
return SQLite.SQLITE_OK
|
|
348
|
+
})
|
|
349
|
+
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
350
|
+
|
|
351
|
+
rc = await sqlite3.exec(db, 'CREATE TABLE t(x)')
|
|
352
|
+
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
353
|
+
|
|
354
|
+
expect(authorizations.length).toBeGreaterThan(0)
|
|
355
|
+
})
|
|
356
|
+
})
|
|
357
|
+
|
|
358
|
+
describe(`${key} update_hook`, function () {
|
|
359
|
+
let db
|
|
360
|
+
beforeEach(async function () {
|
|
361
|
+
db = await sqlite3.open_v2(':memory:')
|
|
362
|
+
})
|
|
363
|
+
|
|
364
|
+
afterEach(async function () {
|
|
365
|
+
await sqlite3.close(db)
|
|
366
|
+
})
|
|
367
|
+
|
|
368
|
+
it('should call update hook', async function () {
|
|
369
|
+
let rc
|
|
370
|
+
|
|
371
|
+
let calls = []
|
|
399
372
|
sqlite3.update_hook(db, (updateType, dbName, tblName, rowid) => {
|
|
400
|
-
calls.push([updateType, dbName, tblName, rowid])
|
|
401
|
-
})
|
|
373
|
+
calls.push([updateType, dbName, tblName, rowid])
|
|
374
|
+
})
|
|
402
375
|
|
|
403
|
-
rc = await sqlite3.exec(
|
|
376
|
+
rc = await sqlite3.exec(
|
|
377
|
+
db,
|
|
378
|
+
`
|
|
404
379
|
CREATE TABLE t(i integer primary key, x);
|
|
405
380
|
INSERT INTO t VALUES (1, 'foo'), (2, 'bar'), (12345678987654321, 'baz');
|
|
406
|
-
|
|
407
|
-
|
|
381
|
+
`,
|
|
382
|
+
)
|
|
383
|
+
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
408
384
|
expect(calls).toEqual([
|
|
409
|
-
[18,
|
|
410
|
-
[18,
|
|
411
|
-
[18,
|
|
412
|
-
])
|
|
413
|
-
|
|
414
|
-
calls.splice(0, calls.length)
|
|
415
|
-
|
|
416
|
-
await sqlite3.exec(db, `DELETE FROM t WHERE i = 2`)
|
|
417
|
-
expect(calls).toEqual([[9,
|
|
418
|
-
|
|
419
|
-
calls.splice(0, calls.length)
|
|
420
|
-
|
|
421
|
-
await sqlite3.exec(db, `UPDATE t SET x = 'bar' WHERE i = 1`)
|
|
422
|
-
expect(calls).toEqual([[23,
|
|
423
|
-
})
|
|
424
|
-
})
|
|
425
|
-
|
|
426
|
-
describe(`${key} commit_hook`, function() {
|
|
427
|
-
let db
|
|
428
|
-
beforeEach(async function() {
|
|
429
|
-
db = await sqlite3.open_v2(':memory:')
|
|
430
|
-
})
|
|
431
|
-
|
|
432
|
-
afterEach(async function() {
|
|
433
|
-
await sqlite3.close(db)
|
|
434
|
-
})
|
|
435
|
-
|
|
436
|
-
it('should call commit hook', async function() {
|
|
437
|
-
let rc
|
|
438
|
-
|
|
439
|
-
let callsCount = 0
|
|
440
|
-
const resetCallsCount = () => callsCount = 0
|
|
385
|
+
[18, 'main', 't', 1n],
|
|
386
|
+
[18, 'main', 't', 2n],
|
|
387
|
+
[18, 'main', 't', 12345678987654321n],
|
|
388
|
+
])
|
|
389
|
+
|
|
390
|
+
calls.splice(0, calls.length)
|
|
391
|
+
|
|
392
|
+
await sqlite3.exec(db, `DELETE FROM t WHERE i = 2`)
|
|
393
|
+
expect(calls).toEqual([[9, 'main', 't', 2n]])
|
|
394
|
+
|
|
395
|
+
calls.splice(0, calls.length)
|
|
396
|
+
|
|
397
|
+
await sqlite3.exec(db, `UPDATE t SET x = 'bar' WHERE i = 1`)
|
|
398
|
+
expect(calls).toEqual([[23, 'main', 't', 1n]])
|
|
399
|
+
})
|
|
400
|
+
})
|
|
401
|
+
|
|
402
|
+
describe(`${key} commit_hook`, function () {
|
|
403
|
+
let db
|
|
404
|
+
beforeEach(async function () {
|
|
405
|
+
db = await sqlite3.open_v2(':memory:')
|
|
406
|
+
})
|
|
407
|
+
|
|
408
|
+
afterEach(async function () {
|
|
409
|
+
await sqlite3.close(db)
|
|
410
|
+
})
|
|
411
|
+
|
|
412
|
+
it('should call commit hook', async function () {
|
|
413
|
+
let rc
|
|
414
|
+
|
|
415
|
+
let callsCount = 0
|
|
416
|
+
const resetCallsCount = () => (callsCount = 0)
|
|
441
417
|
|
|
442
418
|
sqlite3.commit_hook(db, () => {
|
|
443
|
-
callsCount
|
|
444
|
-
return 0
|
|
445
|
-
})
|
|
446
|
-
expect(callsCount).toEqual(0)
|
|
447
|
-
resetCallsCount()
|
|
419
|
+
callsCount++
|
|
420
|
+
return 0
|
|
421
|
+
})
|
|
422
|
+
expect(callsCount).toEqual(0)
|
|
423
|
+
resetCallsCount()
|
|
448
424
|
|
|
449
|
-
rc = await sqlite3.exec(
|
|
425
|
+
rc = await sqlite3.exec(
|
|
426
|
+
db,
|
|
427
|
+
`
|
|
450
428
|
CREATE TABLE t(i integer primary key, x);
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
expect(
|
|
454
|
-
|
|
429
|
+
`,
|
|
430
|
+
)
|
|
431
|
+
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
432
|
+
expect(callsCount).toEqual(1)
|
|
433
|
+
resetCallsCount()
|
|
455
434
|
|
|
456
|
-
rc = await sqlite3.exec(
|
|
435
|
+
rc = await sqlite3.exec(
|
|
436
|
+
db,
|
|
437
|
+
`
|
|
457
438
|
SELECT * FROM t;
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
439
|
+
`,
|
|
440
|
+
)
|
|
441
|
+
expect(callsCount).toEqual(0)
|
|
442
|
+
resetCallsCount()
|
|
461
443
|
|
|
462
|
-
rc = await sqlite3.exec(
|
|
444
|
+
rc = await sqlite3.exec(
|
|
445
|
+
db,
|
|
446
|
+
`
|
|
463
447
|
BEGIN TRANSACTION;
|
|
464
448
|
INSERT INTO t VALUES (1, 'foo');
|
|
465
449
|
ROLLBACK;
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
450
|
+
`,
|
|
451
|
+
)
|
|
452
|
+
expect(callsCount).toEqual(0)
|
|
453
|
+
resetCallsCount()
|
|
469
454
|
|
|
470
|
-
rc = await sqlite3.exec(
|
|
455
|
+
rc = await sqlite3.exec(
|
|
456
|
+
db,
|
|
457
|
+
`
|
|
471
458
|
BEGIN TRANSACTION;
|
|
472
459
|
INSERT INTO t VALUES (1, 'foo');
|
|
473
460
|
INSERT INTO t VALUES (2, 'bar');
|
|
474
461
|
COMMIT;
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
rc
|
|
462
|
+
`,
|
|
463
|
+
)
|
|
464
|
+
expect(callsCount).toEqual(1)
|
|
465
|
+
resetCallsCount()
|
|
466
|
+
})
|
|
467
|
+
|
|
468
|
+
it('can change commit hook', async function () {
|
|
469
|
+
let rc
|
|
470
|
+
rc = await sqlite3.exec(
|
|
471
|
+
db,
|
|
472
|
+
`
|
|
483
473
|
CREATE TABLE t(i integer primary key, x);
|
|
484
|
-
|
|
485
|
-
|
|
474
|
+
`,
|
|
475
|
+
)
|
|
476
|
+
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
486
477
|
|
|
487
|
-
let a = 0
|
|
488
|
-
let b = 0
|
|
478
|
+
let a = 0
|
|
479
|
+
let b = 0
|
|
489
480
|
|
|
490
481
|
// set hook to increment `a` on commit
|
|
491
482
|
sqlite3.commit_hook(db, () => {
|
|
492
|
-
a
|
|
493
|
-
return 0
|
|
494
|
-
})
|
|
495
|
-
rc = await sqlite3.exec(
|
|
483
|
+
a++
|
|
484
|
+
return 0
|
|
485
|
+
})
|
|
486
|
+
rc = await sqlite3.exec(
|
|
487
|
+
db,
|
|
488
|
+
`
|
|
496
489
|
INSERT INTO t VALUES (1, 'foo');
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
expect(
|
|
490
|
+
`,
|
|
491
|
+
)
|
|
492
|
+
expect(a).toEqual(1)
|
|
493
|
+
expect(b).toEqual(0)
|
|
500
494
|
|
|
501
495
|
// switch to increment `b`
|
|
502
496
|
sqlite3.commit_hook(db, () => {
|
|
503
|
-
b
|
|
504
|
-
return 0
|
|
505
|
-
})
|
|
497
|
+
b++
|
|
498
|
+
return 0
|
|
499
|
+
})
|
|
506
500
|
|
|
507
|
-
rc = await sqlite3.exec(
|
|
501
|
+
rc = await sqlite3.exec(
|
|
502
|
+
db,
|
|
503
|
+
`
|
|
508
504
|
INSERT INTO t VALUES (2, 'bar');
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
expect(
|
|
512
|
-
expect(
|
|
505
|
+
`,
|
|
506
|
+
)
|
|
507
|
+
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
508
|
+
expect(a).toEqual(1)
|
|
509
|
+
expect(b).toEqual(1)
|
|
513
510
|
|
|
514
511
|
// disable hook by passing null
|
|
515
|
-
sqlite3.commit_hook(db, null)
|
|
512
|
+
sqlite3.commit_hook(db, null)
|
|
516
513
|
|
|
517
|
-
rc = await sqlite3.exec(
|
|
514
|
+
rc = await sqlite3.exec(
|
|
515
|
+
db,
|
|
516
|
+
`
|
|
518
517
|
INSERT INTO t VALUES (3, 'qux');
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
expect(
|
|
522
|
-
expect(
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
rc
|
|
518
|
+
`,
|
|
519
|
+
)
|
|
520
|
+
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
521
|
+
expect(a).toEqual(1)
|
|
522
|
+
expect(b).toEqual(1)
|
|
523
|
+
})
|
|
524
|
+
|
|
525
|
+
it('can rollback based on return value', async function () {
|
|
526
|
+
let rc
|
|
527
|
+
rc = await sqlite3.exec(
|
|
528
|
+
db,
|
|
529
|
+
`
|
|
528
530
|
CREATE TABLE t(i integer primary key, x);
|
|
529
|
-
|
|
530
|
-
|
|
531
|
+
`,
|
|
532
|
+
)
|
|
533
|
+
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
531
534
|
|
|
532
535
|
// accept commit by returning 0
|
|
533
|
-
sqlite3.commit_hook(db, () => 0)
|
|
534
|
-
rc = await sqlite3.exec(
|
|
536
|
+
sqlite3.commit_hook(db, () => 0)
|
|
537
|
+
rc = await sqlite3.exec(
|
|
538
|
+
db,
|
|
539
|
+
`
|
|
535
540
|
INSERT INTO t VALUES (1, 'foo');
|
|
536
|
-
|
|
537
|
-
|
|
541
|
+
`,
|
|
542
|
+
)
|
|
543
|
+
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
538
544
|
|
|
539
545
|
// reject commit by returning 1, causing rollback
|
|
540
|
-
sqlite3.commit_hook(db, () => 1)
|
|
541
|
-
await expectAsync(
|
|
542
|
-
sqlite3.exec(db, `INSERT INTO t VALUES (2, 'bar');`)
|
|
543
|
-
).toBeRejected();
|
|
546
|
+
sqlite3.commit_hook(db, () => 1)
|
|
547
|
+
await expectAsync(sqlite3.exec(db, `INSERT INTO t VALUES (2, 'bar');`)).toBeRejected()
|
|
544
548
|
|
|
545
549
|
// double-check that the insert was rolled back
|
|
546
|
-
let hasRow = false
|
|
547
|
-
rc = await sqlite3.exec(
|
|
550
|
+
let hasRow = false
|
|
551
|
+
rc = await sqlite3.exec(
|
|
552
|
+
db,
|
|
553
|
+
`
|
|
548
554
|
SELECT * FROM t WHERE i = 2;
|
|
549
|
-
`,
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
555
|
+
`,
|
|
556
|
+
() => (hasRow = true),
|
|
557
|
+
)
|
|
558
|
+
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
559
|
+
expect(hasRow).toBeFalse()
|
|
560
|
+
})
|
|
561
|
+
|
|
562
|
+
it('does not overwrite update_hook', async function () {
|
|
563
|
+
let rc
|
|
564
|
+
rc = await sqlite3.exec(
|
|
565
|
+
db,
|
|
566
|
+
`
|
|
557
567
|
CREATE TABLE t(i integer primary key, x);
|
|
558
|
-
|
|
559
|
-
|
|
568
|
+
`,
|
|
569
|
+
)
|
|
570
|
+
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
560
571
|
|
|
561
|
-
let updateHookInvocationsCount = 0
|
|
572
|
+
let updateHookInvocationsCount = 0
|
|
562
573
|
sqlite3.update_hook(db, (...args) => {
|
|
563
|
-
updateHookInvocationsCount
|
|
564
|
-
})
|
|
574
|
+
updateHookInvocationsCount++
|
|
575
|
+
})
|
|
565
576
|
|
|
566
|
-
let commitHookInvocationsCount = 0
|
|
577
|
+
let commitHookInvocationsCount = 0
|
|
567
578
|
sqlite3.commit_hook(db, () => {
|
|
568
|
-
commitHookInvocationsCount
|
|
569
|
-
return 0
|
|
570
|
-
})
|
|
579
|
+
commitHookInvocationsCount++
|
|
580
|
+
return 0
|
|
581
|
+
})
|
|
571
582
|
|
|
572
|
-
rc = await sqlite3.exec(
|
|
583
|
+
rc = await sqlite3.exec(
|
|
584
|
+
db,
|
|
585
|
+
`
|
|
573
586
|
INSERT INTO t VALUES (1, 'foo');
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
expect(
|
|
579
|
-
|
|
580
|
-
|
|
587
|
+
`,
|
|
588
|
+
)
|
|
589
|
+
expect(rc).toEqual(SQLite.SQLITE_OK)
|
|
590
|
+
|
|
591
|
+
expect(updateHookInvocationsCount).toEqual(1)
|
|
592
|
+
expect(commitHookInvocationsCount).toEqual(1)
|
|
593
|
+
})
|
|
594
|
+
})
|
|
581
595
|
}
|