tursodatabase / libsql

libSQL is a fork of SQLite that is both Open Source, and Open Contributions.
https://turso.tech/libsql
MIT License
9.55k stars 252 forks source link

Interactive Transaction on :memory: fails with missing table #1411

Open erkannt opened 4 months ago

erkannt commented 4 months ago

Using the TS client simply opening and closing a transaction make a subsequent SELECT fail, complaining about a table not existing. The same code works fine if the url is a file instead of :memory:

import * as libsqlClient from '@libsql/client';
import {log} from 'console';
import {randomUUID} from 'crypto';

void (async () => {
  // This succeeds
  const fileClient = libsqlClient.createClient({
    url: `file:/tmp/${randomUUID()}.db`,
  });
  await fileClient.execute('CREATE TABLE events (id TEXT)');
  log(await fileClient.execute('SELECT * FROM events;'));
  const fileTransaction = await fileClient.transaction();
  fileTransaction.close();
  log(await fileClient.execute('SELECT * FROM events;'));

  // This fails
  const client = libsqlClient.createClient({url: ':memory:'});
  await client.execute('CREATE TABLE events (id TEXT)');
  log(await client.execute('SELECT * FROM events;'));
  const transaction = await client.transaction();
  transaction.close();
  log(await client.execute('SELECT * FROM events;'));
})();

The second SELECT for the memory client fails:

$ bun src/test-transactions.ts
ResultSetImpl {
  columns: [ "id" ],
  columnTypes: [ "TEXT" ],
  rows: [],
  rowsAffected: 0,
  lastInsertRowid: undefined,
  toJSON: [Function: toJSON],
}
ResultSetImpl {
  columns: [ "id" ],
  columnTypes: [ "TEXT" ],
  rows: [],
  rowsAffected: 0,
  lastInsertRowid: undefined,
  toJSON: [Function: toJSON],
}
ResultSetImpl {
  columns: [ "id" ],
  columnTypes: [ "TEXT" ],
  rows: [],
  rowsAffected: 0,
  lastInsertRowid: undefined,
  toJSON: [Function: toJSON],
}
 6 |     rawCode;
 7 |     constructor(message, code, rawCode, cause) {
 8 |         if (code !== undefined) {
 9 |             message = `${code}: ${message}`;
10 |         }
11 |         super(message, { cause });
             ^
LibsqlError: SQLITE_ERROR: no such table: events
 cause: {
  "stack": "Error: no such table: events\n    at convertError (/home/hff/repos/makespace-members-app/node_modules/libsql/index.js:49:9)\n    at prepare (/home/hff/repos/makespace-members-app/node_modules/libsql/index.js:110:28)\n    at executeStmt (/home/hff/repos/makespace-members-app/node_modules/@libsql/client/lib-esm/sqlite3.js:194:26)\n    at execute (/home/hff/repos/makespace-members-app/node_modules/@libsql/client/lib-esm/sqlite3.js:60:15)\n    at <anonymous> (/home/hff/repos/makespace-members-app/src/test-transactions.ts:17:14)",
  "code": "SQLITE_ERROR",
  "rawCode": 1
}
 code: "SQLITE_ERROR"

      at new LibsqlError (/home/hff/repos/makespace-members-app/node_modules/@libsql/core/lib-esm/api.js:11:9)
      at mapSqliteError (/home/hff/repos/makespace-members-app/node_modules/@libsql/client/lib-esm/sqlite3.js:312:16)
      at executeStmt (/home/hff/repos/makespace-members-app/node_modules/@libsql/client/lib-esm/sqlite3.js:222:15)
      at execute (/home/hff/repos/makespace-members-app/node_modules/@libsql/client/lib-esm/sqlite3.js:59:19)
      at /home/hff/repos/makespace-members-app/src/test-transactions.ts:22:13
khuezy commented 1 month ago

This is fixed in 0.9.0, you need to use file::memory:?cache=shared