Skip to content

sql-storage-adapter v0.6.16

Choose a tag to compare

@github-actions github-actions released this 15 Oct 20:27
· 315 commits to master since this release
9ce0771

Added

  • typeParsers on the PostgreSQL adapter's options sets, per pool, how int8 ('string', 'number' or 'bigint'), numeric ('string' or 'number'), date ('date' or 'string') and json/jsonb ('parse' or 'string') come back, through pg's per-client type parsers. pg returns int8 and numeric as strings and a DATE as a Date at local midnight. 'number' for int8 refuses a value past Number.MAX_SAFE_INTEGER, and a value the option does not know fails open(). Left out, pg's defaults hold.
  • A host logger. setStorageLogger(logger) routes the library's log lines to it, and logger on createDatabase() and resolveStorageAdapter() takes one call's resolver lines. Each line goes as a fields object and a message, which fits pino as it is (StorageLogger). The lines covered are the resolver's (the adapter chosen, each fallback with its error, the Electron hints), the PostgreSQL adapter's failed-ROLLBACK warning and the adapter base class's. setStorageLogger(null) writes to the console again, and the console lines read as before. The IndexedDB, Capacitor, sync and Electron modules write to the console directly.
  • foreignKeys on createDatabase(), and on StorageOpenOptions for the resolver's openOptions and open(), sets SQLite's foreign-key enforcement (true on, false off) when better-sqlite3, sql.js, IndexedDB or Capacitor opens. Left out, each engine keeps its default, and they differ: better-sqlite3 is built with SQLITE_DEFAULT_FOREIGN_KEYS=1 and enforces foreign keys, while sql.js, IndexedDB and Capacitor do not, so one schema behaved differently per engine. foreignKeys: true makes them agree. sql.js resets PRAGMAs whenever export() reopens its connection, on every save to a file or to IndexedDB, on exportDatabase() and on importDatabase(), so the sql.js and IndexedDB adapters apply it again after each. On Capacitor it runs outside the plugin's transaction, where SQLite ignores it. Each engine's default holds without the option, as before.
  • isUniqueViolation(error) recognises a unique or primary-key violation from any adapter: PostgreSQL's SQLSTATE 23505, better-sqlite3's SQLITE_CONSTRAINT_UNIQUE and SQLITE_CONSTRAINT_PRIMARYKEY, and the "UNIQUE constraint failed" message from sql.js, IndexedDB and Capacitor. It follows cause up to ten levels and does not loop on a cycle, so an error a product wraps still counts.
  • The SQLite adapters (better-sqlite3, sql.js, IndexedDB, Capacitor) take $1, $2, ... bound from a positional array, as PostgreSQL does, so one statement runs on both. SQLite reads $1 as a named parameter: better-sqlite3 refused to bind it from an array ("Too many parameter values were provided"), and sql.js bound it in order of first appearance, so $2, $1 got the values swapped. Each $n outside literals and comments becomes ? with the values in $n order, repeats included. A statement that mixes ? and $n is refused with an error.

Changed

  • On sql.js and IndexedDB, an array value binds as JSON text, as on better-sqlite3 and Capacitor. sql.js bound it as a blob of its elements.
  • On PostgreSQL, a statement that already uses $n placeholders is sent as written, and a statement run without parameters keeps its ?. Both were rewritten before, which broke the jsonb ? operator in them.

Fixed

  • The SQLite adapters convert values as they bind them, positional and named. A boolean binds as 1 or 0, a Date as its ISO 8601 text (an Invalid Date is refused), an array or a plain object as JSON text, and undefined as NULL. better-sqlite3 threw "SQLite3 can only bind numbers, strings, bigints, buffers, and null" on booleans, Dates and objects. sql.js threw on a Date and bound an array as a blob.
  • The IndexedDB adapter binds named parameters written @id, :id or $id from a bare-key object ({ id }), as the sql.js adapter does. It passed the object to sql.js as given, and sql.js binds a key only when it matches the placeholder as written, so every named value was NULL.
  • PostgreSQL placeholder rewriting reads SQL as the server does. A ? or @name inside a string literal ('What should this week hold?'), an E'...' string, a quoted identifier, a dollar-quoted string or a comment was rewritten to $n. The text was stored corrupted, or the statement failed with a parameter-count error. Such text is left as written now. The jsonb operators work: ?? is the ? operator in a statement with ? placeholders, and ?| and ?& are never placeholders. A statement that already uses $n is sent as written, where its ? operators were rewritten. A statement run without parameters keeps its ?, where each became an unbound $n.