mirror of
https://github.com/aljazceru/turso.git
synced 2025-12-22 10:44:19 +01:00
168 lines
6.0 KiB
TypeScript
168 lines
6.0 KiB
TypeScript
import { unlinkSync } from "node:fs";
|
|
import { expect, test } from 'vitest'
|
|
import { Database, connect } from './promise.js'
|
|
import { sql } from 'drizzle-orm';
|
|
import { drizzle } from 'drizzle-orm/better-sqlite3';
|
|
|
|
test('drizzle-orm', async () => {
|
|
const path = `test-${(Math.random() * 10000) | 0}.db`;
|
|
try {
|
|
const conn = await connect(path);
|
|
const db = drizzle(conn);
|
|
await db.run('CREATE TABLE t(x, y)');
|
|
let tasks = [];
|
|
for (let i = 0; i < 1234; i++) {
|
|
tasks.push(db.run(sql`INSERT INTO t VALUES (${i}, randomblob(${i} * 5))`))
|
|
}
|
|
await Promise.all(tasks);
|
|
expect(await db.all("SELECT COUNT(*) as cnt FROM t")).toEqual([{ cnt: 1234 }])
|
|
} finally {
|
|
unlinkSync(path);
|
|
unlinkSync(`${path}-wal`);
|
|
}
|
|
})
|
|
|
|
test('in-memory-db-async', async () => {
|
|
const db = await connect(":memory:");
|
|
await db.exec("CREATE TABLE t(x)");
|
|
await db.exec("INSERT INTO t VALUES (1), (2), (3)");
|
|
const stmt = db.prepare("SELECT * FROM t WHERE x % 2 = ?");
|
|
const rows = await stmt.all([1]);
|
|
expect(rows).toEqual([{ x: 1 }, { x: 3 }]);
|
|
})
|
|
|
|
test('exec multiple statements', async () => {
|
|
const db = await connect(":memory:");
|
|
await db.exec("CREATE TABLE t(x); INSERT INTO t VALUES (1); INSERT INTO t VALUES (2)");
|
|
const stmt = db.prepare("SELECT * FROM t");
|
|
const rows = await stmt.all();
|
|
expect(rows).toEqual([{ x: 1 }, { x: 2 }]);
|
|
})
|
|
|
|
test('readonly-db', async () => {
|
|
const path = `test-${(Math.random() * 10000) | 0}.db`;
|
|
try {
|
|
{
|
|
const rw = await connect(path);
|
|
await rw.exec("CREATE TABLE t(x)");
|
|
await rw.exec("INSERT INTO t VALUES (1)");
|
|
rw.close();
|
|
}
|
|
{
|
|
const ro = await connect(path, { readonly: true });
|
|
await expect(async () => await ro.exec("INSERT INTO t VALUES (2)")).rejects.toThrowError(/Resource is read-only/g);
|
|
expect(await ro.prepare("SELECT * FROM t").all()).toEqual([{ x: 1 }])
|
|
ro.close();
|
|
}
|
|
} finally {
|
|
unlinkSync(path);
|
|
unlinkSync(`${path}-wal`);
|
|
}
|
|
})
|
|
|
|
test('file-must-exist', async () => {
|
|
const path = `test-${(Math.random() * 10000) | 0}.db`;
|
|
await expect(async () => await connect(path, { fileMustExist: true })).rejects.toThrowError(/failed to open file/);
|
|
})
|
|
|
|
test('explicit connect', async () => {
|
|
const db = new Database(':memory:');
|
|
expect(() => db.prepare("SELECT 1")).toThrowError(/database must be connected/g);
|
|
await db.connect();
|
|
expect(await db.prepare("SELECT 1 as x").all()).toEqual([{ x: 1 }]);
|
|
})
|
|
|
|
test('on-disk db', async () => {
|
|
const path = `test-${(Math.random() * 10000) | 0}.db`;
|
|
try {
|
|
const db1 = await connect(path);
|
|
await db1.exec("CREATE TABLE t(x)");
|
|
await db1.exec("INSERT INTO t VALUES (1), (2), (3)");
|
|
const stmt1 = db1.prepare("SELECT * FROM t WHERE x % 2 = ?");
|
|
expect(stmt1.columns()).toEqual([{ name: "x", column: null, database: null, table: null, type: null }]);
|
|
const rows1 = await stmt1.all([1]);
|
|
expect(rows1).toEqual([{ x: 1 }, { x: 3 }]);
|
|
db1.close();
|
|
|
|
const db2 = await connect(path);
|
|
const stmt2 = db2.prepare("SELECT * FROM t WHERE x % 2 = ?");
|
|
expect(stmt2.columns()).toEqual([{ name: "x", column: null, database: null, table: null, type: null }]);
|
|
const rows2 = await stmt2.all([1]);
|
|
expect(rows2).toEqual([{ x: 1 }, { x: 3 }]);
|
|
db2.close();
|
|
} finally {
|
|
unlinkSync(path);
|
|
unlinkSync(`${path}-wal`);
|
|
}
|
|
})
|
|
|
|
test('attach', async () => {
|
|
const path1 = `test-${(Math.random() * 10000) | 0}.db`;
|
|
const path2 = `test-${(Math.random() * 10000) | 0}.db`;
|
|
try {
|
|
const db1 = await connect(path1);
|
|
await db1.exec("CREATE TABLE t(x)");
|
|
await db1.exec("INSERT INTO t VALUES (1), (2), (3)");
|
|
const db2 = await connect(path2);
|
|
await db2.exec("CREATE TABLE q(x)");
|
|
await db2.exec("INSERT INTO q VALUES (4), (5), (6)");
|
|
|
|
await db1.exec(`ATTACH '${path2}' as secondary`);
|
|
|
|
const stmt = db1.prepare("SELECT * FROM t UNION ALL SELECT * FROM secondary.q");
|
|
expect(stmt.columns()).toEqual([{ name: "x", column: null, database: null, table: null, type: null }]);
|
|
const rows = await stmt.all([1]);
|
|
expect(rows).toEqual([{ x: 1 }, { x: 2 }, { x: 3 }, { x: 4 }, { x: 5 }, { x: 6 }]);
|
|
} finally {
|
|
unlinkSync(path1);
|
|
unlinkSync(`${path1}-wal`);
|
|
unlinkSync(path2);
|
|
unlinkSync(`${path2}-wal`);
|
|
}
|
|
})
|
|
|
|
test('blobs', async () => {
|
|
const db = await connect(":memory:");
|
|
const rows = await db.prepare("SELECT x'1020' as x").all();
|
|
expect(rows).toEqual([{ x: Buffer.from([16, 32]) }])
|
|
})
|
|
|
|
|
|
test('example-1', async () => {
|
|
const db = await connect(':memory:');
|
|
await db.exec('CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)');
|
|
|
|
const insert = db.prepare('INSERT INTO users (name, email) VALUES (?, ?)');
|
|
await insert.run('Alice', 'alice@example.com');
|
|
await insert.run('Bob', 'bob@example.com');
|
|
|
|
const users = await db.prepare('SELECT * FROM users').all();
|
|
expect(users).toEqual([
|
|
{ id: 1, name: 'Alice', email: 'alice@example.com' },
|
|
{ id: 2, name: 'Bob', email: 'bob@example.com' }
|
|
]);
|
|
})
|
|
|
|
test('example-2', async () => {
|
|
const db = await connect(':memory:');
|
|
await db.exec('CREATE TABLE users (name, email)');
|
|
// Using transactions for atomic operations
|
|
const transaction = db.transaction(async (users) => {
|
|
const insert = db.prepare('INSERT INTO users (name, email) VALUES (?, ?)');
|
|
for (const user of users) {
|
|
await insert.run(user.name, user.email);
|
|
}
|
|
});
|
|
|
|
// Execute transaction
|
|
await transaction([
|
|
{ name: 'Alice', email: 'alice@example.com' },
|
|
{ name: 'Bob', email: 'bob@example.com' }
|
|
]);
|
|
|
|
const rows = await db.prepare('SELECT * FROM users').all();
|
|
expect(rows).toEqual([
|
|
{ name: 'Alice', email: 'alice@example.com' },
|
|
{ name: 'Bob', email: 'bob@example.com' }
|
|
]);
|
|
}) |