Repository navigation
sql-storage-adapter v0.7.15
·
252 commits
to master
since this release
Added
PostgresExporterOptions, the second argument ofnew PostgresExporter(connectionString, { schema }):schemaexports one schema alone, by its exact name (pg_dump --schema). It is exported from the root and./core.new PostgresExporter(connectionString)also takes a function that gives the connection string when an export runs.migrateIndexedDbKeyValue({ source, adapter, into })in./kv(#63) moves one namespace of an old IndexedDB key-value store, the oneopenIndexedDbStoreopens, into aKeyValueStoreover an adapter, behind a marker (MIGRATION_MARKER), with the old store's writers locked out by the database's version. It answersmigrated,already,noneorblocked, resumes from the committed side after a reload, copies once when two moves run at once, and refuses a store that keeps nothing past the page.
Changed
PostgresExporterreads apostgres://orpostgresql://connection string as libpq reads it, so the password reachespg_dumpthroughPGPASSWORD, off its command line, in every form libpq takes: an empty host (postgresql://app:pw@/app?host=/var/run/postgresql), several hosts, a#or?in the password, and apasswordparameter, which libpq takes over the user part's password. 0.7.12 read the string with the WHATWG URL parser, which refuses the first three, so the export threw, and it left apasswordparameter on the command line. The scheme is read in any case, as pg reads it, and handed topg_dumpin lower case, the only case libpq reads.- A failed
pg_dumprejects withpg_dump's own words and its exit code, never with the command line, which can hold a password. A missingpg_dumpsays to install the PostgreSQL client tools, and a dump larger than 256 MiB fromexportToBytes()says to useexportToFile().
Fixed
createStorageFeatures(adapter).exporteron a segmented PostgreSQL adapter dumps the segment's schema alone. It dumped every schema of the database: the other segments' tables and the host's inpublic.createStorageFeatures(adapter).exporteron an adapter made with a pool of the caller's reaches the database the pool was made for, through the settings apgPoolkeeps as itsoptions. It had no connection string, so both export methods always threw. A pool whose settings name no database says so.createStorageFeatures(adapter).exporternames the PostgreSQL adapter's database when an export runs, from the pool the adapter runs on. An adapter given its connection string atopen()had none to export with, and one opened on another connection string than its options held exported the database of its options.- The exporter of a PostgreSQL adapter or pool whose
hostis a Unix-socket directory (/var/run/postgresql) reaches the database through it: the path went into the connection string unencoded, where libpq read it as the database name. A password given with no user name reachespg_dumptoo. - A segmented PostgreSQL adapter's
open()fails when the segment is not the current schema of its first connection, and says what to grant. PostgreSQL leaves a schema the role has noUSAGEprivilege on out of thesearch_pathwithout a word, so on an existing schema another role made, the segment's statements read and created tables inpublic. A pooler that drops startup options did the same. resolveStorageAdapter()andcreateDatabase()refuse a segment name inpostgres,indexedDborcapacitorthat cannot be a segment before any adapter is tried, as they refuse their own. A candidate whose options name no segment, tried after a candidate whose options named one, opens in that segment: withoutstrict, an unreachable PostgreSQL withpostgres.segmentfell through to better-sqlite3 on the shared file, outside the segment.- IndexedDB adapter: a PRAGMA through
all()orget()that setsuser_version,application_id,schema_version,page_size,auto_vacuumorencoding, or runsincremental_vacuumoroptimize, is saved. SQLite'stotal_changes()counts no PRAGMA, soget('PRAGMA user_version = 3')was stored neither withdurability: 'commit'nor byflush()orclose(). PRAGMA reads and connection settings still write nothing. createSqlKeyValueStore()refuses aProxywith aDataCloneError, as the structured clone and IndexedDB's put do. A proxy reads as the object it wraps to every check but the runtime's ownstructuredClone, which now runs first, soset()storednew Proxy({ x: 1 }, {})as{ x: 1 }.