@tursodatabase/database 0.1.5-pre.3 → 0.1.5
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 +14 -18
- package/dist/compat.d.ts +6 -0
- package/dist/compat.d.ts.map +1 -0
- package/dist/compat.js +4 -363
- package/dist/compat.test.d.ts +2 -0
- package/dist/compat.test.d.ts.map +1 -0
- package/dist/compat.test.js +62 -0
- package/dist/promise.d.ts +14 -0
- package/dist/promise.d.ts.map +1 -0
- package/dist/promise.js +5 -370
- package/dist/promise.test.d.ts +2 -0
- package/dist/promise.test.d.ts.map +1 -0
- package/dist/promise.test.js +95 -0
- package/index.js +141 -26
- package/package.json +28 -41
- package/browser.js +0 -1
- package/dist/bind.js +0 -68
- package/dist/sqlite-error.js +0 -12
- package/index.d.ts +0 -130
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<h1 align="center">Turso Database for JavaScript</h1>
|
|
2
|
+
<h1 align="center">Turso Database for JavaScript in Node</h1>
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<p align="center">
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
## About
|
|
16
16
|
|
|
17
|
-
This package is the Turso
|
|
17
|
+
This package is the Turso embedded database library for JavaScript in Node.
|
|
18
18
|
|
|
19
19
|
> **⚠️ Warning:** This software is ALPHA, only use for development, testing, and experimentation. We are working to make it production ready, but do not use it for critical data right now.
|
|
20
20
|
|
|
@@ -23,7 +23,7 @@ This package is the Turso in-memory database library for JavaScript.
|
|
|
23
23
|
- **SQLite compatible:** SQLite query language and file format support ([status](https://github.com/tursodatabase/turso/blob/main/COMPAT.md)).
|
|
24
24
|
- **In-process**: No network overhead, runs directly in your Node.js process
|
|
25
25
|
- **TypeScript support**: Full TypeScript definitions included
|
|
26
|
-
- **Cross-platform**: Supports Linux (x86 and arm64), macOS, Windows
|
|
26
|
+
- **Cross-platform**: Supports Linux (x86 and arm64), macOS, Windows (browser is supported in the separate package `@tursodatabase/database-browser` package)
|
|
27
27
|
|
|
28
28
|
## Installation
|
|
29
29
|
|
|
@@ -42,15 +42,15 @@ import { connect } from '@tursodatabase/database';
|
|
|
42
42
|
const db = await connect(':memory:');
|
|
43
43
|
|
|
44
44
|
// Create a table
|
|
45
|
-
db.exec('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)');
|
|
45
|
+
await db.exec('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)');
|
|
46
46
|
|
|
47
47
|
// Insert data
|
|
48
48
|
const insert = db.prepare('INSERT INTO users (name, email) VALUES (?, ?)');
|
|
49
|
-
insert.run('Alice', 'alice@example.com');
|
|
50
|
-
insert.run('Bob', 'bob@example.com');
|
|
49
|
+
await insert.run('Alice', 'alice@example.com');
|
|
50
|
+
await insert.run('Bob', 'bob@example.com');
|
|
51
51
|
|
|
52
52
|
// Query data
|
|
53
|
-
const users = db.prepare('SELECT * FROM users').all();
|
|
53
|
+
const users = await db.prepare('SELECT * FROM users').all();
|
|
54
54
|
console.log(users);
|
|
55
55
|
// Output: [
|
|
56
56
|
// { id: 1, name: 'Alice', email: 'alice@example.com' },
|
|
@@ -67,7 +67,7 @@ import { connect } from '@tursodatabase/database';
|
|
|
67
67
|
const db = await connect('my-database.db');
|
|
68
68
|
|
|
69
69
|
// Create a table
|
|
70
|
-
db.exec(`
|
|
70
|
+
await db.exec(`
|
|
71
71
|
CREATE TABLE IF NOT EXISTS posts (
|
|
72
72
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
73
73
|
title TEXT NOT NULL,
|
|
@@ -78,7 +78,7 @@ db.exec(`
|
|
|
78
78
|
|
|
79
79
|
// Insert a post
|
|
80
80
|
const insertPost = db.prepare('INSERT INTO posts (title, content) VALUES (?, ?)');
|
|
81
|
-
const result = insertPost.run('Hello World', 'This is my first blog post!');
|
|
81
|
+
const result = await insertPost.run('Hello World', 'This is my first blog post!');
|
|
82
82
|
|
|
83
83
|
console.log(`Inserted post with ID: ${result.lastInsertRowid}`);
|
|
84
84
|
```
|
|
@@ -91,27 +91,23 @@ import { connect } from '@tursodatabase/database';
|
|
|
91
91
|
const db = await connect('transactions.db');
|
|
92
92
|
|
|
93
93
|
// Using transactions for atomic operations
|
|
94
|
-
const transaction = db.transaction((users) => {
|
|
94
|
+
const transaction = db.transaction(async (users) => {
|
|
95
95
|
const insert = db.prepare('INSERT INTO users (name, email) VALUES (?, ?)');
|
|
96
96
|
for (const user of users) {
|
|
97
|
-
insert.run(user.name, user.email);
|
|
97
|
+
await insert.run(user.name, user.email);
|
|
98
98
|
}
|
|
99
99
|
});
|
|
100
100
|
|
|
101
101
|
// Execute transaction
|
|
102
|
-
transaction([
|
|
102
|
+
await transaction([
|
|
103
103
|
{ name: 'Alice', email: 'alice@example.com' },
|
|
104
104
|
{ name: 'Bob', email: 'bob@example.com' }
|
|
105
105
|
]);
|
|
106
106
|
```
|
|
107
107
|
|
|
108
|
-
### WebAssembly Support
|
|
109
|
-
|
|
110
|
-
Turso Database can run in browsers using WebAssembly. Check the `browser.js` and WASM artifacts for browser usage.
|
|
111
|
-
|
|
112
108
|
## API Reference
|
|
113
109
|
|
|
114
|
-
For complete API documentation, see [JavaScript API Reference](
|
|
110
|
+
For complete API documentation, see [JavaScript API Reference](../../../../docs/javascript-api-reference.md).
|
|
115
111
|
|
|
116
112
|
## Related Packages
|
|
117
113
|
|
|
@@ -126,4 +122,4 @@ This project is licensed under the [MIT license](../../LICENSE.md).
|
|
|
126
122
|
|
|
127
123
|
- [GitHub Issues](https://github.com/tursodatabase/turso/issues)
|
|
128
124
|
- [Documentation](https://docs.turso.tech)
|
|
129
|
-
- [Discord Community](https://tur.so/discord)
|
|
125
|
+
- [Discord Community](https://tur.so/discord)
|
package/dist/compat.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { DatabaseCompat, SqliteError, DatabaseOpts } from "@tursodatabase/database-common";
|
|
2
|
+
declare class Database extends DatabaseCompat {
|
|
3
|
+
constructor(path: string, opts?: DatabaseOpts);
|
|
4
|
+
}
|
|
5
|
+
export { Database, SqliteError };
|
|
6
|
+
//# sourceMappingURL=compat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compat.d.ts","sourceRoot":"","sources":["../compat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAkB,WAAW,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAA;AAG1G,cAAM,QAAS,SAAQ,cAAc;gBACrB,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,YAAiB;CAGpD;AAED,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAA"}
|
package/dist/compat.js
CHANGED
|
@@ -1,367 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
// Step result constants
|
|
5
|
-
const STEP_ROW = 1;
|
|
6
|
-
const STEP_DONE = 2;
|
|
7
|
-
const STEP_IO = 3;
|
|
8
|
-
const convertibleErrorTypes = { TypeError };
|
|
9
|
-
const CONVERTIBLE_ERROR_PREFIX = "[TURSO_CONVERT_TYPE]";
|
|
10
|
-
function convertError(err) {
|
|
11
|
-
if ((err.code ?? "").startsWith(CONVERTIBLE_ERROR_PREFIX)) {
|
|
12
|
-
return createErrorByName(err.code.substring(CONVERTIBLE_ERROR_PREFIX.length), err.message);
|
|
13
|
-
}
|
|
14
|
-
return new SqliteError(err.message, err.code, err.rawCode);
|
|
15
|
-
}
|
|
16
|
-
function createErrorByName(name, message) {
|
|
17
|
-
const ErrorConstructor = convertibleErrorTypes[name];
|
|
18
|
-
if (!ErrorConstructor) {
|
|
19
|
-
throw new Error(`unknown error type ${name} from Turso`);
|
|
20
|
-
}
|
|
21
|
-
return new ErrorConstructor(message);
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Database represents a connection that can prepare and execute SQL statements.
|
|
25
|
-
*/
|
|
26
|
-
class Database {
|
|
27
|
-
db;
|
|
28
|
-
memory;
|
|
29
|
-
open;
|
|
30
|
-
_inTransaction = false;
|
|
31
|
-
/**
|
|
32
|
-
* Creates a new database connection. If the database file pointed to by `path` does not exists, it will be created.
|
|
33
|
-
*
|
|
34
|
-
* @constructor
|
|
35
|
-
* @param {string} path - Path to the database file.
|
|
36
|
-
* @param {Object} opts - Options for database behavior.
|
|
37
|
-
* @param {boolean} [opts.readonly=false] - Open the database in read-only mode.
|
|
38
|
-
* @param {boolean} [opts.fileMustExist=false] - If true, throws if database file does not exist.
|
|
39
|
-
* @param {number} [opts.timeout=0] - Timeout duration in milliseconds for database operations. Defaults to 0 (no timeout).
|
|
40
|
-
*/
|
|
1
|
+
import { DatabaseCompat, SqliteError } from "@tursodatabase/database-common";
|
|
2
|
+
import { Database as NativeDB } from "#index";
|
|
3
|
+
class Database extends DatabaseCompat {
|
|
41
4
|
constructor(path, opts = {}) {
|
|
42
|
-
|
|
43
|
-
opts.fileMustExist =
|
|
44
|
-
opts.fileMustExist === undefined ? false : opts.fileMustExist;
|
|
45
|
-
opts.timeout = opts.timeout === undefined ? 0 : opts.timeout;
|
|
46
|
-
this.db = new NativeDB(path);
|
|
47
|
-
this.memory = this.db.memory;
|
|
48
|
-
const db = this.db;
|
|
49
|
-
Object.defineProperties(this, {
|
|
50
|
-
inTransaction: {
|
|
51
|
-
get: () => this._inTransaction,
|
|
52
|
-
},
|
|
53
|
-
name: {
|
|
54
|
-
get() {
|
|
55
|
-
return path;
|
|
56
|
-
},
|
|
57
|
-
},
|
|
58
|
-
readonly: {
|
|
59
|
-
get() {
|
|
60
|
-
return opts.readonly;
|
|
61
|
-
},
|
|
62
|
-
},
|
|
63
|
-
open: {
|
|
64
|
-
get() {
|
|
65
|
-
return this.db.open;
|
|
66
|
-
},
|
|
67
|
-
},
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Prepares a SQL statement for execution.
|
|
72
|
-
*
|
|
73
|
-
* @param {string} sql - The SQL statement string to prepare.
|
|
74
|
-
*/
|
|
75
|
-
prepare(sql) {
|
|
76
|
-
if (!this.open) {
|
|
77
|
-
throw new TypeError("The database connection is not open");
|
|
78
|
-
}
|
|
79
|
-
if (!sql) {
|
|
80
|
-
throw new RangeError("The supplied SQL string contains no statements");
|
|
81
|
-
}
|
|
82
|
-
try {
|
|
83
|
-
return new Statement(this.db.prepare(sql), this);
|
|
84
|
-
}
|
|
85
|
-
catch (err) {
|
|
86
|
-
throw convertError(err);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Returns a function that executes the given function in a transaction.
|
|
91
|
-
*
|
|
92
|
-
* @param {function} fn - The function to wrap in a transaction.
|
|
93
|
-
*/
|
|
94
|
-
transaction(fn) {
|
|
95
|
-
if (typeof fn !== "function")
|
|
96
|
-
throw new TypeError("Expected first argument to be a function");
|
|
97
|
-
const db = this;
|
|
98
|
-
const wrapTxn = (mode) => {
|
|
99
|
-
return (...bindParameters) => {
|
|
100
|
-
db.exec("BEGIN " + mode);
|
|
101
|
-
db._inTransaction = true;
|
|
102
|
-
try {
|
|
103
|
-
const result = fn(...bindParameters);
|
|
104
|
-
db.exec("COMMIT");
|
|
105
|
-
db._inTransaction = false;
|
|
106
|
-
return result;
|
|
107
|
-
}
|
|
108
|
-
catch (err) {
|
|
109
|
-
db.exec("ROLLBACK");
|
|
110
|
-
db._inTransaction = false;
|
|
111
|
-
throw err;
|
|
112
|
-
}
|
|
113
|
-
};
|
|
114
|
-
};
|
|
115
|
-
const properties = {
|
|
116
|
-
default: { value: wrapTxn("") },
|
|
117
|
-
deferred: { value: wrapTxn("DEFERRED") },
|
|
118
|
-
immediate: { value: wrapTxn("IMMEDIATE") },
|
|
119
|
-
exclusive: { value: wrapTxn("EXCLUSIVE") },
|
|
120
|
-
database: { value: this, enumerable: true },
|
|
121
|
-
};
|
|
122
|
-
Object.defineProperties(properties.default.value, properties);
|
|
123
|
-
Object.defineProperties(properties.deferred.value, properties);
|
|
124
|
-
Object.defineProperties(properties.immediate.value, properties);
|
|
125
|
-
Object.defineProperties(properties.exclusive.value, properties);
|
|
126
|
-
return properties.default.value;
|
|
127
|
-
}
|
|
128
|
-
pragma(source, options) {
|
|
129
|
-
if (options == null)
|
|
130
|
-
options = {};
|
|
131
|
-
if (typeof source !== "string")
|
|
132
|
-
throw new TypeError("Expected first argument to be a string");
|
|
133
|
-
if (typeof options !== "object")
|
|
134
|
-
throw new TypeError("Expected second argument to be an options object");
|
|
135
|
-
const pragma = `PRAGMA ${source}`;
|
|
136
|
-
const stmt = this.prepare(pragma);
|
|
137
|
-
const results = stmt.all();
|
|
138
|
-
return results;
|
|
139
|
-
}
|
|
140
|
-
backup(filename, options) {
|
|
141
|
-
throw new Error("not implemented");
|
|
142
|
-
}
|
|
143
|
-
serialize(options) {
|
|
144
|
-
throw new Error("not implemented");
|
|
145
|
-
}
|
|
146
|
-
function(name, options, fn) {
|
|
147
|
-
throw new Error("not implemented");
|
|
148
|
-
}
|
|
149
|
-
aggregate(name, options) {
|
|
150
|
-
throw new Error("not implemented");
|
|
151
|
-
}
|
|
152
|
-
table(name, factory) {
|
|
153
|
-
throw new Error("not implemented");
|
|
154
|
-
}
|
|
155
|
-
loadExtension(path) {
|
|
156
|
-
throw new Error("not implemented");
|
|
157
|
-
}
|
|
158
|
-
maxWriteReplicationIndex() {
|
|
159
|
-
throw new Error("not implemented");
|
|
160
|
-
}
|
|
161
|
-
/**
|
|
162
|
-
* Executes a SQL statement.
|
|
163
|
-
*
|
|
164
|
-
* @param {string} sql - The SQL statement string to execute.
|
|
165
|
-
*/
|
|
166
|
-
exec(sql) {
|
|
167
|
-
if (!this.open) {
|
|
168
|
-
throw new TypeError("The database connection is not open");
|
|
169
|
-
}
|
|
170
|
-
try {
|
|
171
|
-
this.db.batch(sql);
|
|
172
|
-
}
|
|
173
|
-
catch (err) {
|
|
174
|
-
throw convertError(err);
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
/**
|
|
178
|
-
* Interrupts the database connection.
|
|
179
|
-
*/
|
|
180
|
-
interrupt() {
|
|
181
|
-
throw new Error("not implemented");
|
|
182
|
-
}
|
|
183
|
-
/**
|
|
184
|
-
* Sets the default safe integers mode for all statements from this database.
|
|
185
|
-
*
|
|
186
|
-
* @param {boolean} [toggle] - Whether to use safe integers by default.
|
|
187
|
-
*/
|
|
188
|
-
defaultSafeIntegers(toggle) {
|
|
189
|
-
this.db.defaultSafeIntegers(toggle);
|
|
190
|
-
}
|
|
191
|
-
/**
|
|
192
|
-
* Closes the database connection.
|
|
193
|
-
*/
|
|
194
|
-
close() {
|
|
195
|
-
this.db.close();
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
/**
|
|
199
|
-
* Statement represents a prepared SQL statement that can be executed.
|
|
200
|
-
*/
|
|
201
|
-
class Statement {
|
|
202
|
-
stmt;
|
|
203
|
-
db;
|
|
204
|
-
constructor(stmt, database) {
|
|
205
|
-
this.stmt = stmt;
|
|
206
|
-
this.db = database;
|
|
207
|
-
}
|
|
208
|
-
/**
|
|
209
|
-
* Toggle raw mode.
|
|
210
|
-
*
|
|
211
|
-
* @param raw Enable or disable raw mode. If you don't pass the parameter, raw mode is enabled.
|
|
212
|
-
*/
|
|
213
|
-
raw(raw) {
|
|
214
|
-
this.stmt.raw(raw);
|
|
215
|
-
return this;
|
|
216
|
-
}
|
|
217
|
-
/**
|
|
218
|
-
* Toggle pluck mode.
|
|
219
|
-
*
|
|
220
|
-
* @param pluckMode Enable or disable pluck mode. If you don't pass the parameter, pluck mode is enabled.
|
|
221
|
-
*/
|
|
222
|
-
pluck(pluckMode) {
|
|
223
|
-
this.stmt.pluck(pluckMode);
|
|
224
|
-
return this;
|
|
225
|
-
}
|
|
226
|
-
/**
|
|
227
|
-
* Sets safe integers mode for this statement.
|
|
228
|
-
*
|
|
229
|
-
* @param {boolean} [toggle] - Whether to use safe integers.
|
|
230
|
-
*/
|
|
231
|
-
safeIntegers(toggle) {
|
|
232
|
-
this.stmt.safeIntegers(toggle);
|
|
233
|
-
return this;
|
|
234
|
-
}
|
|
235
|
-
/**
|
|
236
|
-
* Get column information for the statement.
|
|
237
|
-
*
|
|
238
|
-
* @returns {Array} An array of column objects with name, column, table, database, and type properties.
|
|
239
|
-
*/
|
|
240
|
-
columns() {
|
|
241
|
-
return this.stmt.columns();
|
|
242
|
-
}
|
|
243
|
-
get source() {
|
|
244
|
-
throw new Error("not implemented");
|
|
245
|
-
}
|
|
246
|
-
get reader() {
|
|
247
|
-
throw new Error("not implemented");
|
|
248
|
-
}
|
|
249
|
-
get database() {
|
|
250
|
-
return this.db;
|
|
251
|
-
}
|
|
252
|
-
/**
|
|
253
|
-
* Executes the SQL statement and returns an info object.
|
|
254
|
-
*/
|
|
255
|
-
run(...bindParameters) {
|
|
256
|
-
const totalChangesBefore = this.db.db.totalChanges();
|
|
257
|
-
this.stmt.reset();
|
|
258
|
-
bindParams(this.stmt, bindParameters);
|
|
259
|
-
for (;;) {
|
|
260
|
-
const stepResult = this.stmt.step();
|
|
261
|
-
if (stepResult === STEP_IO) {
|
|
262
|
-
this.db.db.ioLoopSync();
|
|
263
|
-
continue;
|
|
264
|
-
}
|
|
265
|
-
if (stepResult === STEP_DONE) {
|
|
266
|
-
break;
|
|
267
|
-
}
|
|
268
|
-
if (stepResult === STEP_ROW) {
|
|
269
|
-
// For run(), we don't need the row data, just continue
|
|
270
|
-
continue;
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
const lastInsertRowid = this.db.db.lastInsertRowid();
|
|
274
|
-
const changes = this.db.db.totalChanges() === totalChangesBefore ? 0 : this.db.db.changes();
|
|
275
|
-
return { changes, lastInsertRowid };
|
|
276
|
-
}
|
|
277
|
-
/**
|
|
278
|
-
* Executes the SQL statement and returns the first row.
|
|
279
|
-
*
|
|
280
|
-
* @param bindParameters - The bind parameters for executing the statement.
|
|
281
|
-
*/
|
|
282
|
-
get(...bindParameters) {
|
|
283
|
-
this.stmt.reset();
|
|
284
|
-
bindParams(this.stmt, bindParameters);
|
|
285
|
-
for (;;) {
|
|
286
|
-
const stepResult = this.stmt.step();
|
|
287
|
-
if (stepResult === STEP_IO) {
|
|
288
|
-
this.db.db.ioLoopSync();
|
|
289
|
-
continue;
|
|
290
|
-
}
|
|
291
|
-
if (stepResult === STEP_DONE) {
|
|
292
|
-
return undefined;
|
|
293
|
-
}
|
|
294
|
-
if (stepResult === STEP_ROW) {
|
|
295
|
-
return this.stmt.row();
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
/**
|
|
300
|
-
* Executes the SQL statement and returns an iterator to the resulting rows.
|
|
301
|
-
*
|
|
302
|
-
* @param bindParameters - The bind parameters for executing the statement.
|
|
303
|
-
*/
|
|
304
|
-
*iterate(...bindParameters) {
|
|
305
|
-
this.stmt.reset();
|
|
306
|
-
bindParams(this.stmt, bindParameters);
|
|
307
|
-
while (true) {
|
|
308
|
-
const stepResult = this.stmt.step();
|
|
309
|
-
if (stepResult === STEP_IO) {
|
|
310
|
-
this.db.db.ioLoopSync();
|
|
311
|
-
continue;
|
|
312
|
-
}
|
|
313
|
-
if (stepResult === STEP_DONE) {
|
|
314
|
-
break;
|
|
315
|
-
}
|
|
316
|
-
if (stepResult === STEP_ROW) {
|
|
317
|
-
yield this.stmt.row();
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
/**
|
|
322
|
-
* Executes the SQL statement and returns an array of the resulting rows.
|
|
323
|
-
*
|
|
324
|
-
* @param bindParameters - The bind parameters for executing the statement.
|
|
325
|
-
*/
|
|
326
|
-
all(...bindParameters) {
|
|
327
|
-
this.stmt.reset();
|
|
328
|
-
bindParams(this.stmt, bindParameters);
|
|
329
|
-
const rows = [];
|
|
330
|
-
for (;;) {
|
|
331
|
-
const stepResult = this.stmt.step();
|
|
332
|
-
if (stepResult === STEP_IO) {
|
|
333
|
-
this.db.db.ioLoopSync();
|
|
334
|
-
continue;
|
|
335
|
-
}
|
|
336
|
-
if (stepResult === STEP_DONE) {
|
|
337
|
-
break;
|
|
338
|
-
}
|
|
339
|
-
if (stepResult === STEP_ROW) {
|
|
340
|
-
rows.push(this.stmt.row());
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
return rows;
|
|
344
|
-
}
|
|
345
|
-
/**
|
|
346
|
-
* Interrupts the statement.
|
|
347
|
-
*/
|
|
348
|
-
interrupt() {
|
|
349
|
-
throw new Error("not implemented");
|
|
350
|
-
}
|
|
351
|
-
/**
|
|
352
|
-
* Binds the given parameters to the statement _permanently_
|
|
353
|
-
*
|
|
354
|
-
* @param bindParameters - The bind parameters for binding the statement.
|
|
355
|
-
* @returns this - Statement with binded parameters
|
|
356
|
-
*/
|
|
357
|
-
bind(...bindParameters) {
|
|
358
|
-
try {
|
|
359
|
-
bindParams(this.stmt, bindParameters);
|
|
360
|
-
return this;
|
|
361
|
-
}
|
|
362
|
-
catch (err) {
|
|
363
|
-
throw convertError(err);
|
|
364
|
-
}
|
|
5
|
+
super(new NativeDB(path, { tracing: opts.tracing }), opts);
|
|
365
6
|
}
|
|
366
7
|
}
|
|
367
8
|
export { Database, SqliteError };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compat.test.d.ts","sourceRoot":"","sources":["../compat.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { unlinkSync } from "node:fs";
|
|
2
|
+
import { expect, test } from 'vitest';
|
|
3
|
+
import { Database } from './compat.js';
|
|
4
|
+
test('in-memory db', () => {
|
|
5
|
+
const db = new Database(":memory:");
|
|
6
|
+
db.exec("CREATE TABLE t(x)");
|
|
7
|
+
db.exec("INSERT INTO t VALUES (1), (2), (3)");
|
|
8
|
+
const stmt = db.prepare("SELECT * FROM t WHERE x % 2 = ?");
|
|
9
|
+
const rows = stmt.all([1]);
|
|
10
|
+
expect(rows).toEqual([{ x: 1 }, { x: 3 }]);
|
|
11
|
+
});
|
|
12
|
+
test('on-disk db', () => {
|
|
13
|
+
const path = `test-${(Math.random() * 10000) | 0}.db`;
|
|
14
|
+
try {
|
|
15
|
+
const db1 = new Database(path);
|
|
16
|
+
db1.exec("CREATE TABLE t(x)");
|
|
17
|
+
db1.exec("INSERT INTO t VALUES (1), (2), (3)");
|
|
18
|
+
const stmt1 = db1.prepare("SELECT * FROM t WHERE x % 2 = ?");
|
|
19
|
+
expect(stmt1.columns()).toEqual([{ name: "x", column: null, database: null, table: null, type: null }]);
|
|
20
|
+
const rows1 = stmt1.all([1]);
|
|
21
|
+
expect(rows1).toEqual([{ x: 1 }, { x: 3 }]);
|
|
22
|
+
db1.close();
|
|
23
|
+
const db2 = new Database(path);
|
|
24
|
+
const stmt2 = db2.prepare("SELECT * FROM t WHERE x % 2 = ?");
|
|
25
|
+
expect(stmt2.columns()).toEqual([{ name: "x", column: null, database: null, table: null, type: null }]);
|
|
26
|
+
const rows2 = stmt2.all([1]);
|
|
27
|
+
expect(rows2).toEqual([{ x: 1 }, { x: 3 }]);
|
|
28
|
+
db2.close();
|
|
29
|
+
}
|
|
30
|
+
finally {
|
|
31
|
+
unlinkSync(path);
|
|
32
|
+
unlinkSync(`${path}-wal`);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
test('attach', () => {
|
|
36
|
+
const path1 = `test-${(Math.random() * 10000) | 0}.db`;
|
|
37
|
+
const path2 = `test-${(Math.random() * 10000) | 0}.db`;
|
|
38
|
+
try {
|
|
39
|
+
const db1 = new Database(path1);
|
|
40
|
+
db1.exec("CREATE TABLE t(x)");
|
|
41
|
+
db1.exec("INSERT INTO t VALUES (1), (2), (3)");
|
|
42
|
+
const db2 = new Database(path2);
|
|
43
|
+
db2.exec("CREATE TABLE q(x)");
|
|
44
|
+
db2.exec("INSERT INTO q VALUES (4), (5), (6)");
|
|
45
|
+
db1.exec(`ATTACH '${path2}' as secondary`);
|
|
46
|
+
const stmt = db1.prepare("SELECT * FROM t UNION ALL SELECT * FROM secondary.q");
|
|
47
|
+
expect(stmt.columns()).toEqual([{ name: "x", column: null, database: null, table: null, type: null }]);
|
|
48
|
+
const rows = stmt.all([1]);
|
|
49
|
+
expect(rows).toEqual([{ x: 1 }, { x: 2 }, { x: 3 }, { x: 4 }, { x: 5 }, { x: 6 }]);
|
|
50
|
+
}
|
|
51
|
+
finally {
|
|
52
|
+
unlinkSync(path1);
|
|
53
|
+
unlinkSync(`${path1}-wal`);
|
|
54
|
+
unlinkSync(path2);
|
|
55
|
+
unlinkSync(`${path2}-wal`);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
test('blobs', () => {
|
|
59
|
+
const db = new Database(":memory:");
|
|
60
|
+
const rows = db.prepare("SELECT x'1020' as x").all();
|
|
61
|
+
expect(rows).toEqual([{ x: Buffer.from([16, 32]) }]);
|
|
62
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { DatabasePromise, SqliteError, DatabaseOpts } from "@tursodatabase/database-common";
|
|
2
|
+
declare class Database extends DatabasePromise {
|
|
3
|
+
constructor(path: string, opts?: DatabaseOpts);
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Creates a new database connection asynchronously.
|
|
7
|
+
*
|
|
8
|
+
* @param {string} path - Path to the database file.
|
|
9
|
+
* @param {Object} opts - Options for database behavior.
|
|
10
|
+
* @returns {Promise<Database>} - A promise that resolves to a Database instance.
|
|
11
|
+
*/
|
|
12
|
+
declare function connect(path: string, opts?: any): Promise<Database>;
|
|
13
|
+
export { connect, Database, SqliteError };
|
|
14
|
+
//# sourceMappingURL=promise.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promise.d.ts","sourceRoot":"","sources":["../promise.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAkB,WAAW,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAA;AAG3G,cAAM,QAAS,SAAQ,eAAe;gBACtB,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,YAAiB;CAGpD;AAED;;;;;;GAMG;AACH,iBAAe,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,GAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAEtE;AAED,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAA"}
|