WiseLibs / better-sqlite3

The fastest and simplest library for SQLite3 in Node.js.
MIT License
5.22k stars 390 forks source link

cannot start from a readonly path #1184

Closed FrancYescO closed 2 months ago

FrancYescO commented 2 months ago

i'm trying to embed a typeorm app with sqlite db in an ISO:

Basically the conf is:

export const dataSourceOptions: DataSourceOptions = {
  name: 'DB',
  type: 'better-sqlite3',
  database: 'db.db',
  migrationsRun: false,
  logging: true,
  synchronize: false,
  readonly: true
};

when running locally, or setting an absolute path like database: 'C:\aaaa\db.db' all is working, while running from a mounted iso, so D: is readonly and database in D:\db.db , i'm getting: Error: EPERM: operation not permitted, mkdir 'D:\'

just for reference in these issue similar issues are getting managed https://github.com/WiseLibs/better-sqlite3/issues/628 https://github.com/WiseLibs/better-sqlite3/issues/640

maybe the issue is "just" this line that is trying to check if the folder exists https://github.com/WiseLibs/better-sqlite3/blob/master/lib/database.js#L64

mceachen commented 2 months ago

I was unable to reproduce this on Windows 11 on a forced-read-only drive:

  1. Mount USB disk to D:\
  2. const bs = require("better-sqlite3");
    const db = bs("D:\\test.sqlite3");
    db.exec("create table t (id INTEGER)");
    db.prepare("insert into t(id) values (1),(2),(3)").run();
    db.close();
  3. Unmount USB disk
  4. Enable write protection:
    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\StorageDevicePolicies]
    "WriteProtect"=dword:00000001
  5. Remount disk. Verify the drive is read-only by attempting to delete or rename D:\test.sqlite3.
  6. const bs = require("better-sqlite3");
    const db = bs("D:\\test.sqlite3");
    db.prepare("select * from t").all();
    [ { id: 1 }, { id: 2 }, { id: 3 } ]

(if you do this to verify, undo the write protection by setting 00000001 to 00000000).

maybe the issue is "just" this line that is trying to check if the folder exists https://github.com/WiseLibs/better-sqlite3/blob/master/lib/database.js#L64

You're getting an EPERM from mkdir. The line you referenced only checks for the existence of the directory using stat--it's not doing a mkdir.

Please open an issue on your ORM, or just run your code in your debugger and trap the exception--it should point you right at the codepath you're fighting.

FrancYescO commented 2 months ago

Thanks for the hint, i'll try to give a more consistent test case... in the meantime i've also found this node issue that seems related https://github.com/nodejs/node/issues/38347