@toiroakr/lines-db 0.1.0
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/LICENSE +21 -0
- package/bin/cli.js +1373 -0
- package/dist/index.cjs +1212 -0
- package/dist/index.d.cts +486 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.ts +486 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1181 -0
- package/dist/index.js.map +1 -0
- package/package.json +64 -0
- package/src/cli.ts +333 -0
- package/src/database.test.ts +493 -0
- package/src/database.ts +1025 -0
- package/src/directory-scanner.test.ts +91 -0
- package/src/directory-scanner.ts +38 -0
- package/src/error-formatter.ts +166 -0
- package/src/index.ts +35 -0
- package/src/jsonl-migration.ts +76 -0
- package/src/jsonl-reader.test.ts +168 -0
- package/src/jsonl-reader.ts +135 -0
- package/src/jsonl-writer.test.ts +101 -0
- package/src/jsonl-writer.ts +33 -0
- package/src/runtime.ts +34 -0
- package/src/schema-loader.test.ts +136 -0
- package/src/schema-loader.ts +64 -0
- package/src/schema.ts +135 -0
- package/src/sqlite-adapter.ts +99 -0
- package/src/type-generator.ts +201 -0
- package/src/types.ts +99 -0
- package/src/validator.test.ts +337 -0
- package/src/validator.ts +207 -0
- package/tsconfig.json +20 -0
- package/tsconfig.test.json +8 -0
- package/tsdown.config.ts +26 -0
- package/vitest.config.ts +9 -0
|
@@ -0,0 +1,493 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { LinesDB } from './database.js';
|
|
3
|
+
import type { DatabaseConfig } from './types.js';
|
|
4
|
+
import { writeFile, mkdir, rm } from 'node:fs/promises';
|
|
5
|
+
import { join } from 'node:path';
|
|
6
|
+
import { tmpdir } from 'node:os';
|
|
7
|
+
|
|
8
|
+
describe('LinesDB', () => {
|
|
9
|
+
let testDir: string;
|
|
10
|
+
const GENERIC_SCHEMA_SOURCE = `import * as v from 'valibot';
|
|
11
|
+
import { defineSchema } from 'lines-db';
|
|
12
|
+
|
|
13
|
+
const rawSchema = v.record(v.string(), v.unknown());
|
|
14
|
+
|
|
15
|
+
export const schema = defineSchema(rawSchema);
|
|
16
|
+
`;
|
|
17
|
+
|
|
18
|
+
const writeTable = async (tableName: string, contents: string) => {
|
|
19
|
+
await writeFile(join(testDir, `${tableName}.jsonl`), contents);
|
|
20
|
+
await writeFile(join(testDir, `${tableName}.schema.ts`), GENERIC_SCHEMA_SOURCE);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
beforeEach(async () => {
|
|
24
|
+
testDir = join(tmpdir(), `linesdb-test-${Date.now()}`);
|
|
25
|
+
await mkdir(testDir, { recursive: true });
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
afterEach(async () => {
|
|
29
|
+
await rm(testDir, { recursive: true, force: true });
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
describe('initialization', () => {
|
|
33
|
+
it('should create and initialize database', async () => {
|
|
34
|
+
await writeTable('users', '{"id":1,"name":"Alice"}\n{"id":2,"name":"Bob"}\n');
|
|
35
|
+
|
|
36
|
+
type Tables = {
|
|
37
|
+
users: { id: number; name: string };
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const config: DatabaseConfig<Tables> = { dataDir: testDir };
|
|
41
|
+
const db = LinesDB.create(config);
|
|
42
|
+
await db.initialize();
|
|
43
|
+
|
|
44
|
+
const tables = db.getTableNames();
|
|
45
|
+
expect(tables).toContain('users');
|
|
46
|
+
|
|
47
|
+
await db.close();
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('should load multiple tables', async () => {
|
|
51
|
+
await writeTable('users', '{"id":1}\n');
|
|
52
|
+
await writeTable('products', '{"id":1}\n');
|
|
53
|
+
|
|
54
|
+
type Tables = {
|
|
55
|
+
users: { id: number };
|
|
56
|
+
products: { id: number };
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const config: DatabaseConfig<Tables> = { dataDir: testDir };
|
|
60
|
+
const db = LinesDB.create(config);
|
|
61
|
+
await db.initialize();
|
|
62
|
+
|
|
63
|
+
const tableNames = db.getTableNames();
|
|
64
|
+
expect(tableNames).toHaveLength(2);
|
|
65
|
+
expect(tableNames).toContain('users');
|
|
66
|
+
expect(tableNames).toContain('products');
|
|
67
|
+
|
|
68
|
+
await db.close();
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('should infer schema from data', async () => {
|
|
72
|
+
await writeTable('users', '{"id":1,"name":"Alice","age":30}\n');
|
|
73
|
+
|
|
74
|
+
type Tables = {
|
|
75
|
+
users: { id: number; name: string; age: number };
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const config: DatabaseConfig<Tables> = { dataDir: testDir };
|
|
79
|
+
const db = LinesDB.create(config);
|
|
80
|
+
await db.initialize();
|
|
81
|
+
|
|
82
|
+
const schema = db.getSchema('users');
|
|
83
|
+
expect(schema).toBeDefined();
|
|
84
|
+
expect(schema?.name).toBe('users');
|
|
85
|
+
expect(schema?.columns).toHaveLength(3);
|
|
86
|
+
|
|
87
|
+
await db.close();
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
describe('query operations', () => {
|
|
92
|
+
it('should select all rows', async () => {
|
|
93
|
+
await writeTable('users', '{"id":1,"name":"Alice"}\n{"id":2,"name":"Bob"}\n');
|
|
94
|
+
|
|
95
|
+
type Tables = {
|
|
96
|
+
users: { id: number; name: string };
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const config: DatabaseConfig<Tables> = { dataDir: testDir };
|
|
100
|
+
const db = LinesDB.create(config);
|
|
101
|
+
await db.initialize();
|
|
102
|
+
|
|
103
|
+
const users = db.find('users');
|
|
104
|
+
expect(users).toHaveLength(2);
|
|
105
|
+
expect(users[0]).toEqual({ id: 1, name: 'Alice' });
|
|
106
|
+
expect(users[1]).toEqual({ id: 2, name: 'Bob' });
|
|
107
|
+
|
|
108
|
+
await db.close();
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it('should find rows by condition', async () => {
|
|
112
|
+
await writeTable(
|
|
113
|
+
'users',
|
|
114
|
+
'{"id":1,"name":"Alice"}\n{"id":2,"name":"Bob"}\n{"id":3,"name":"Alice"}\n',
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
type Tables = {
|
|
118
|
+
users: { id: number; name: string };
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
const config: DatabaseConfig<Tables> = { dataDir: testDir };
|
|
122
|
+
const db = LinesDB.create(config);
|
|
123
|
+
await db.initialize();
|
|
124
|
+
|
|
125
|
+
const alices = db.find('users', { name: 'Alice' });
|
|
126
|
+
expect(alices).toHaveLength(2);
|
|
127
|
+
expect(alices[0].id).toBe(1);
|
|
128
|
+
expect(alices[1].id).toBe(3);
|
|
129
|
+
|
|
130
|
+
await db.close();
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it('should find single row', async () => {
|
|
134
|
+
await writeTable('users', '{"id":1,"name":"Alice"}\n{"id":2,"name":"Bob"}\n');
|
|
135
|
+
|
|
136
|
+
type Tables = {
|
|
137
|
+
users: { id: number; name: string };
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
const config: DatabaseConfig<Tables> = { dataDir: testDir };
|
|
141
|
+
const db = LinesDB.create(config);
|
|
142
|
+
await db.initialize();
|
|
143
|
+
|
|
144
|
+
const user = db.findOne('users', { id: 2 });
|
|
145
|
+
expect(user).toEqual({ id: 2, name: 'Bob' });
|
|
146
|
+
|
|
147
|
+
await db.close();
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it('should return null when row not found', async () => {
|
|
151
|
+
await writeTable('users', '{"id":1,"name":"Alice"}\n');
|
|
152
|
+
|
|
153
|
+
type Tables = {
|
|
154
|
+
users: { id: number; name: string };
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
const config: DatabaseConfig<Tables> = { dataDir: testDir };
|
|
158
|
+
const db = LinesDB.create(config);
|
|
159
|
+
await db.initialize();
|
|
160
|
+
|
|
161
|
+
const user = db.findOne('users', { id: 999 });
|
|
162
|
+
expect(user).toBeNull();
|
|
163
|
+
|
|
164
|
+
await db.close();
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
describe('insert operations', () => {
|
|
169
|
+
it('should insert new row', async () => {
|
|
170
|
+
await writeTable('users', '{"id":1,"name":"Alice"}\n');
|
|
171
|
+
|
|
172
|
+
type Tables = {
|
|
173
|
+
users: { id: number; name: string };
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
const config: DatabaseConfig<Tables> = { dataDir: testDir };
|
|
177
|
+
const db = LinesDB.create(config);
|
|
178
|
+
await db.initialize();
|
|
179
|
+
|
|
180
|
+
const result = db.insert('users', { id: 2, name: 'Bob' });
|
|
181
|
+
expect(result.changes).toBe(1);
|
|
182
|
+
|
|
183
|
+
const users = db.find('users');
|
|
184
|
+
expect(users).toHaveLength(2);
|
|
185
|
+
|
|
186
|
+
await db.close();
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it('should validate on insert when schema exists', async () => {
|
|
190
|
+
await writeFile(join(testDir, 'users.jsonl'), '{"id":1,"name":"Alice"}\n');
|
|
191
|
+
await writeFile(
|
|
192
|
+
join(testDir, 'users.schema.ts'),
|
|
193
|
+
`
|
|
194
|
+
export const schema = {
|
|
195
|
+
'~standard': {
|
|
196
|
+
version: 1,
|
|
197
|
+
vendor: 'test',
|
|
198
|
+
validate: (data) => {
|
|
199
|
+
const issues = [];
|
|
200
|
+
if (!data.name || data.name.length === 0) {
|
|
201
|
+
issues.push({ message: 'Name is required' });
|
|
202
|
+
}
|
|
203
|
+
return { value: data, issues };
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
`,
|
|
208
|
+
);
|
|
209
|
+
|
|
210
|
+
type Tables = {
|
|
211
|
+
users: { id: number; name: string };
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
const config: DatabaseConfig<Tables> = { dataDir: testDir };
|
|
215
|
+
const db = LinesDB.create(config);
|
|
216
|
+
await db.initialize();
|
|
217
|
+
|
|
218
|
+
expect(() => {
|
|
219
|
+
db.insert('users', { id: 2, name: '' });
|
|
220
|
+
}).toThrow(/Validation/);
|
|
221
|
+
|
|
222
|
+
await db.close();
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
it('should batch insert rows', async () => {
|
|
226
|
+
await writeTable('users', '{"id":1,"name":"Alice"}\n');
|
|
227
|
+
|
|
228
|
+
type Tables = {
|
|
229
|
+
users: { id: number; name: string };
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
const config: DatabaseConfig<Tables> = { dataDir: testDir };
|
|
233
|
+
const db = LinesDB.create(config);
|
|
234
|
+
await db.initialize();
|
|
235
|
+
|
|
236
|
+
const result = db.batchInsert('users', [
|
|
237
|
+
{ id: 2, name: 'Bob' },
|
|
238
|
+
{ id: 3, name: 'Carol' },
|
|
239
|
+
]);
|
|
240
|
+
|
|
241
|
+
expect(result.changes).toBe(2n);
|
|
242
|
+
|
|
243
|
+
const users = db.find('users');
|
|
244
|
+
expect(users).toHaveLength(3);
|
|
245
|
+
expect(users.map((u) => u.name).sort()).toEqual(['Alice', 'Bob', 'Carol']);
|
|
246
|
+
|
|
247
|
+
await db.close();
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
describe('update operations', () => {
|
|
252
|
+
it('should update existing rows', async () => {
|
|
253
|
+
await writeTable(
|
|
254
|
+
'users',
|
|
255
|
+
'{"id":1,"name":"Alice","age":30}\n{"id":2,"name":"Bob","age":25}\n',
|
|
256
|
+
);
|
|
257
|
+
|
|
258
|
+
type Tables = {
|
|
259
|
+
users: { id: number; name: string; age: number };
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
const config: DatabaseConfig<Tables> = { dataDir: testDir };
|
|
263
|
+
const db = LinesDB.create(config);
|
|
264
|
+
await db.initialize();
|
|
265
|
+
|
|
266
|
+
const result = db.update('users', { age: 31 }, { id: 1 });
|
|
267
|
+
expect(result.changes).toBe(1);
|
|
268
|
+
|
|
269
|
+
const user = db.findOne('users', { id: 1 });
|
|
270
|
+
expect(user?.age).toBe(31);
|
|
271
|
+
|
|
272
|
+
await db.close();
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
it('should update multiple rows', async () => {
|
|
276
|
+
await writeTable(
|
|
277
|
+
'users',
|
|
278
|
+
'{"id":1,"name":"Alice","active":true}\n{"id":2,"name":"Bob","active":true}\n',
|
|
279
|
+
);
|
|
280
|
+
|
|
281
|
+
type Tables = {
|
|
282
|
+
users: { id: number; name: string; active: boolean };
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
const config: DatabaseConfig<Tables> = { dataDir: testDir };
|
|
286
|
+
const db = LinesDB.create(config);
|
|
287
|
+
await db.initialize();
|
|
288
|
+
|
|
289
|
+
const result = db.update('users', { active: false }, { active: true });
|
|
290
|
+
expect(result.changes).toBe(2);
|
|
291
|
+
|
|
292
|
+
await db.close();
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
it('should batch update rows with distinct values', async () => {
|
|
296
|
+
await writeTable(
|
|
297
|
+
'users',
|
|
298
|
+
'{"id":1,"name":"Alice","age":30}\n{"id":2,"name":"Bob","age":25}\n',
|
|
299
|
+
);
|
|
300
|
+
|
|
301
|
+
type Tables = {
|
|
302
|
+
users: { id: number; name: string; age: number };
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
const config: DatabaseConfig<Tables> = { dataDir: testDir };
|
|
306
|
+
const db = LinesDB.create(config);
|
|
307
|
+
await db.initialize();
|
|
308
|
+
|
|
309
|
+
const result = db.batchUpdate('users', [
|
|
310
|
+
{ id: 1, age: 31 },
|
|
311
|
+
{ id: 2, age: 27 },
|
|
312
|
+
]);
|
|
313
|
+
expect(result.changes).toBe(2n);
|
|
314
|
+
|
|
315
|
+
const users = db.find('users');
|
|
316
|
+
const alice = users.find((u) => u.id === 1);
|
|
317
|
+
const bob = users.find((u) => u.id === 2);
|
|
318
|
+
expect(alice?.age).toBe(31);
|
|
319
|
+
expect(bob?.age).toBe(27);
|
|
320
|
+
|
|
321
|
+
await db.close();
|
|
322
|
+
});
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
describe('delete operations', () => {
|
|
326
|
+
it('should delete rows', async () => {
|
|
327
|
+
await writeTable('users', '{"id":1,"name":"Alice"}\n{"id":2,"name":"Bob"}\n');
|
|
328
|
+
|
|
329
|
+
type Tables = {
|
|
330
|
+
users: { id: number; name: string };
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
const config: DatabaseConfig<Tables> = { dataDir: testDir };
|
|
334
|
+
const db = LinesDB.create(config);
|
|
335
|
+
await db.initialize();
|
|
336
|
+
|
|
337
|
+
const result = db.delete('users', { id: 1 });
|
|
338
|
+
expect(result.changes).toBe(1);
|
|
339
|
+
|
|
340
|
+
const users = db.find('users');
|
|
341
|
+
expect(users).toHaveLength(1);
|
|
342
|
+
expect(users[0].id).toBe(2);
|
|
343
|
+
|
|
344
|
+
await db.close();
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
it('should delete multiple rows', async () => {
|
|
348
|
+
await writeTable(
|
|
349
|
+
'users',
|
|
350
|
+
'{"id":1,"name":"Alice"}\n{"id":2,"name":"Alice"}\n{"id":3,"name":"Bob"}\n',
|
|
351
|
+
);
|
|
352
|
+
|
|
353
|
+
type Tables = {
|
|
354
|
+
users: { id: number; name: string };
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
const config: DatabaseConfig<Tables> = { dataDir: testDir };
|
|
358
|
+
const db = LinesDB.create(config);
|
|
359
|
+
await db.initialize();
|
|
360
|
+
|
|
361
|
+
const result = db.delete('users', { name: 'Alice' });
|
|
362
|
+
expect(result.changes).toBe(2);
|
|
363
|
+
|
|
364
|
+
const users = db.find('users');
|
|
365
|
+
expect(users).toHaveLength(1);
|
|
366
|
+
|
|
367
|
+
await db.close();
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
it('should batch delete rows by primary key', async () => {
|
|
371
|
+
await writeTable(
|
|
372
|
+
'users',
|
|
373
|
+
'{"id":1,"name":"Alice"}\n{"id":2,"name":"Bob"}\n{"id":3,"name":"Carol"}\n',
|
|
374
|
+
);
|
|
375
|
+
|
|
376
|
+
type Tables = {
|
|
377
|
+
users: { id: number; name: string };
|
|
378
|
+
};
|
|
379
|
+
|
|
380
|
+
const config: DatabaseConfig<Tables> = { dataDir: testDir };
|
|
381
|
+
const db = LinesDB.create(config);
|
|
382
|
+
await db.initialize();
|
|
383
|
+
|
|
384
|
+
const result = db.batchDelete('users', [{ id: 1 }, { id: 3 }]);
|
|
385
|
+
expect(result.changes).toBe(2n);
|
|
386
|
+
|
|
387
|
+
const users = db.find('users');
|
|
388
|
+
expect(users).toHaveLength(1);
|
|
389
|
+
expect(users[0].id).toBe(2);
|
|
390
|
+
|
|
391
|
+
await db.close();
|
|
392
|
+
});
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
describe('JSON columns', () => {
|
|
396
|
+
it('should handle JSON objects', async () => {
|
|
397
|
+
await writeTable('records', '{"id":1,"data":{"key":"value"}}\n');
|
|
398
|
+
|
|
399
|
+
type Tables = {
|
|
400
|
+
records: { id: number; data: { key: string } };
|
|
401
|
+
};
|
|
402
|
+
|
|
403
|
+
const config: DatabaseConfig<Tables> = { dataDir: testDir };
|
|
404
|
+
const db = LinesDB.create(config);
|
|
405
|
+
await db.initialize();
|
|
406
|
+
|
|
407
|
+
const records = db.find('records');
|
|
408
|
+
expect(records[0].data).toEqual({ key: 'value' });
|
|
409
|
+
|
|
410
|
+
await db.close();
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
it('should handle JSON arrays', async () => {
|
|
414
|
+
await writeTable('records', '{"id":1,"tags":["a","b","c"]}\n');
|
|
415
|
+
|
|
416
|
+
type Tables = {
|
|
417
|
+
records: { id: number; tags: string[] };
|
|
418
|
+
};
|
|
419
|
+
|
|
420
|
+
const config: DatabaseConfig<Tables> = { dataDir: testDir };
|
|
421
|
+
const db = LinesDB.create(config);
|
|
422
|
+
await db.initialize();
|
|
423
|
+
|
|
424
|
+
const records = db.find('records');
|
|
425
|
+
expect(records[0].tags).toEqual(['a', 'b', 'c']);
|
|
426
|
+
|
|
427
|
+
await db.close();
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
it('should insert JSON columns', async () => {
|
|
431
|
+
await writeTable('records', '{"id":1,"data":{}}\n');
|
|
432
|
+
|
|
433
|
+
type Tables = {
|
|
434
|
+
records: { id: number; data: { key: string } };
|
|
435
|
+
};
|
|
436
|
+
|
|
437
|
+
const config: DatabaseConfig<Tables> = { dataDir: testDir };
|
|
438
|
+
const db = LinesDB.create(config);
|
|
439
|
+
await db.initialize();
|
|
440
|
+
|
|
441
|
+
db.insert('records', { id: 2, data: { key: 'new value' } });
|
|
442
|
+
|
|
443
|
+
const record = db.findOne('records', { id: 2 });
|
|
444
|
+
expect(record?.data).toEqual({ key: 'new value' });
|
|
445
|
+
|
|
446
|
+
await db.close();
|
|
447
|
+
});
|
|
448
|
+
});
|
|
449
|
+
|
|
450
|
+
describe('raw SQL queries', () => {
|
|
451
|
+
it('should execute raw queries', async () => {
|
|
452
|
+
await writeFile(
|
|
453
|
+
join(testDir, 'users.jsonl'),
|
|
454
|
+
'{"id":1,"name":"Alice"}\n{"id":2,"name":"Bob"}\n',
|
|
455
|
+
);
|
|
456
|
+
|
|
457
|
+
type Tables = {
|
|
458
|
+
users: { id: number; name: string };
|
|
459
|
+
};
|
|
460
|
+
|
|
461
|
+
const config: DatabaseConfig<Tables> = { dataDir: testDir };
|
|
462
|
+
const db = LinesDB.create(config);
|
|
463
|
+
await db.initialize();
|
|
464
|
+
|
|
465
|
+
const result = db.query<{ id: number; name: string }>('SELECT * FROM users WHERE id > ?', [
|
|
466
|
+
1,
|
|
467
|
+
]);
|
|
468
|
+
|
|
469
|
+
expect(result).toHaveLength(1);
|
|
470
|
+
expect(result[0].name).toBe('Bob');
|
|
471
|
+
|
|
472
|
+
await db.close();
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
it('should execute queryOne', async () => {
|
|
476
|
+
await writeTable('users', '{"id":1,"name":"Alice"}\n');
|
|
477
|
+
|
|
478
|
+
type Tables = {
|
|
479
|
+
users: { id: number; name: string };
|
|
480
|
+
};
|
|
481
|
+
|
|
482
|
+
const config: DatabaseConfig<Tables> = { dataDir: testDir };
|
|
483
|
+
const db = LinesDB.create(config);
|
|
484
|
+
await db.initialize();
|
|
485
|
+
|
|
486
|
+
const result = db.queryOne<{ name: string }>('SELECT name FROM users WHERE id = ?', [1]);
|
|
487
|
+
|
|
488
|
+
expect(result?.name).toBe('Alice');
|
|
489
|
+
|
|
490
|
+
await db.close();
|
|
491
|
+
});
|
|
492
|
+
});
|
|
493
|
+
});
|