dbgate-sqlite-dumper 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +674 -674
- package/README.md +247 -230
- package/dist/better-sqlite3.cjs.map +1 -1
- package/dist/better-sqlite3.d.cts +1 -1
- package/dist/better-sqlite3.d.ts +1 -1
- package/dist/better-sqlite3.js.map +1 -1
- package/dist/d1.cjs +260 -0
- package/dist/d1.cjs.map +1 -0
- package/dist/d1.d.cts +101 -0
- package/dist/d1.d.ts +101 -0
- package/dist/d1.js +229 -0
- package/dist/d1.js.map +1 -0
- package/dist/errors-CplNzuYs.d.cts +20 -0
- package/dist/errors-CplNzuYs.d.ts +20 -0
- package/dist/index.cjs +405 -90
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +58 -24
- package/dist/index.d.ts +58 -24
- package/dist/index.js +400 -89
- package/dist/index.js.map +1 -1
- package/dist/{types-CTyJTzB6.d.cts → types-DziV5ysl.d.cts} +67 -2
- package/dist/{types-CTyJTzB6.d.ts → types-DziV5ysl.d.ts} +67 -2
- package/docs/architecture.md +180 -157
- package/docs/better-sqlite3-adapter.md +83 -83
- package/docs/d1-adapter.md +98 -0
- package/docs/dump-api.md +253 -253
- package/docs/known-limitations.md +100 -88
- package/docs/native-compatibility.md +124 -124
- package/docs/restore-api.md +234 -234
- package/docs/round-trip-testing.md +84 -84
- package/docs/supported-data-types.md +74 -74
- package/docs/supported-objects.md +85 -85
- package/package.json +96 -89
|
@@ -1,74 +1,74 @@
|
|
|
1
|
-
# Supported data types
|
|
2
|
-
|
|
3
|
-
SQLite stores every value in one of five storage classes, whatever a column is declared
|
|
4
|
-
as. A dump writes each value according to its storage class, exactly as the native `.dump`
|
|
5
|
-
writes it — and restoring it yields the same storage class and the same value.
|
|
6
|
-
|
|
7
|
-
| Storage class | Written as | Example |
|
|
8
|
-
| ------------- | --------------------------------------------- | ---------------------------------------- |
|
|
9
|
-
| `NULL` | `NULL` | `NULL` |
|
|
10
|
-
| `INTEGER` | decimal | `9223372036854775807` |
|
|
11
|
-
| `REAL` | `%lld.0` when integral, else `%!.20g` | `3.0`, `0.100000000000000005`, `1.0e+20` |
|
|
12
|
-
| | infinities | `9.0e+999`, `-9.0e+999` |
|
|
13
|
-
| `TEXT` | quoted, `'` doubled, newlines via `replace()` | `replace('a\nb','\n',char(10))` |
|
|
14
|
-
| `BLOB` | lower-case hex | `X'00ff'`, `X''` |
|
|
15
|
-
|
|
16
|
-
## How values are read
|
|
17
|
-
|
|
18
|
-
Row data never passes through a JavaScript number, and text never passes through the
|
|
19
|
-
driver's decoder. The `SELECT` that reads a table has SQLite itself produce, per column:
|
|
20
|
-
|
|
21
|
-
- `INTEGER` → `CAST(x AS TEXT)`: exact at 64 bits, whatever the driver would have done;
|
|
22
|
-
- `REAL` → the literal, computed in SQL with the shell's own rule — including SQLite's
|
|
23
|
-
`printf('%!.20g')`, so the digits are the ones SQLite writes, which no JavaScript number
|
|
24
|
-
formatting reproduces;
|
|
25
|
-
- `TEXT` → `CAST(x AS BLOB)`: the stored bytes (in a UTF-16 database, the text itself);
|
|
26
|
-
- `BLOB` → the bytes.
|
|
27
|
-
|
|
28
|
-
## Notes per class
|
|
29
|
-
|
|
30
|
-
### `INTEGER`
|
|
31
|
-
|
|
32
|
-
Exact across the full 64-bit range. `AUTOINCREMENT` counters are read as text too, so a
|
|
33
|
-
counter past 2^53 resumes at exactly the right value.
|
|
34
|
-
|
|
35
|
-
### `REAL`
|
|
36
|
-
|
|
37
|
-
The literal round-trips to the identical double: `%!.20g` carries more than the 17
|
|
38
|
-
significant digits that identify one. The digits beyond the 17th vary between SQLite
|
|
39
|
-
releases (see [native-compatibility.md](native-compatibility.md#the-one-exception-real-digit-tails)),
|
|
40
|
-
never the value.
|
|
41
|
-
|
|
42
|
-
A `REAL` holding an integral value is written with `.0` (`3.0`), so it is restored as a
|
|
43
|
-
`REAL`, not an `INTEGER`. `-0.0` is written as `0.0`, as natively.
|
|
44
|
-
|
|
45
|
-
### `TEXT`
|
|
46
|
-
|
|
47
|
-
- **Quoting:** the only escape SQLite has is a doubled `'`. There are no backslash escapes.
|
|
48
|
-
- **Newlines and carriage returns** are written as `replace('…\n…','\n',char(10))` (and
|
|
49
|
-
`char(13)`), with a placeholder that does not otherwise occur in the text — so each
|
|
50
|
-
`INSERT` stays on one line and survives tools that rewrite line endings. With
|
|
51
|
-
`dataExport.rawNewlines` (native `--newlines`) they are written raw instead.
|
|
52
|
-
- **Bytes that are not valid UTF-8** — SQLite does not validate what it stores — are
|
|
53
|
-
written raw, as natively, so the dump reproduces the stored value exactly. Such a dump is
|
|
54
|
-
not valid UTF-8, which is why the writer and the restore handle bytes. On restore through
|
|
55
|
-
a JavaScript driver, such a literal is executed as `CAST(X'…' AS TEXT)`, the identical
|
|
56
|
-
bytes.
|
|
57
|
-
- **`NUL` characters** are kept, written as `'a'||char(0)||'b'`. The native shell truncates
|
|
58
|
-
text at the first `NUL`; this is the one place this package writes something the shell
|
|
59
|
-
would not, and only for text the shell cannot represent.
|
|
60
|
-
|
|
61
|
-
### `BLOB`
|
|
62
|
-
|
|
63
|
-
Always hex. An empty blob is `X''`, distinct from `NULL` and from the empty string `''`.
|
|
64
|
-
|
|
65
|
-
## Declared types
|
|
66
|
-
|
|
67
|
-
A column's declared type — `VARCHAR(20)`, `DATETIME`, `BOOLEAN`, `JSON`, or none at all —
|
|
68
|
-
is part of the table's DDL and is reproduced verbatim. It only determines the column's
|
|
69
|
-
_affinity_, which SQLite applies on insert; since every value is written in the storage
|
|
70
|
-
class it already has, affinity cannot change it on restore. `STRICT` tables are restored as
|
|
71
|
-
`STRICT`, with their type checks.
|
|
72
|
-
|
|
73
|
-
Dates and times have no storage class of their own in SQLite; they are whatever text,
|
|
74
|
-
number or blob the application stored, and are dumped as such.
|
|
1
|
+
# Supported data types
|
|
2
|
+
|
|
3
|
+
SQLite stores every value in one of five storage classes, whatever a column is declared
|
|
4
|
+
as. A dump writes each value according to its storage class, exactly as the native `.dump`
|
|
5
|
+
writes it — and restoring it yields the same storage class and the same value.
|
|
6
|
+
|
|
7
|
+
| Storage class | Written as | Example |
|
|
8
|
+
| ------------- | --------------------------------------------- | ---------------------------------------- |
|
|
9
|
+
| `NULL` | `NULL` | `NULL` |
|
|
10
|
+
| `INTEGER` | decimal | `9223372036854775807` |
|
|
11
|
+
| `REAL` | `%lld.0` when integral, else `%!.20g` | `3.0`, `0.100000000000000005`, `1.0e+20` |
|
|
12
|
+
| | infinities | `9.0e+999`, `-9.0e+999` |
|
|
13
|
+
| `TEXT` | quoted, `'` doubled, newlines via `replace()` | `replace('a\nb','\n',char(10))` |
|
|
14
|
+
| `BLOB` | lower-case hex | `X'00ff'`, `X''` |
|
|
15
|
+
|
|
16
|
+
## How values are read
|
|
17
|
+
|
|
18
|
+
Row data never passes through a JavaScript number, and text never passes through the
|
|
19
|
+
driver's decoder. The `SELECT` that reads a table has SQLite itself produce, per column:
|
|
20
|
+
|
|
21
|
+
- `INTEGER` → `CAST(x AS TEXT)`: exact at 64 bits, whatever the driver would have done;
|
|
22
|
+
- `REAL` → the literal, computed in SQL with the shell's own rule — including SQLite's
|
|
23
|
+
`printf('%!.20g')`, so the digits are the ones SQLite writes, which no JavaScript number
|
|
24
|
+
formatting reproduces;
|
|
25
|
+
- `TEXT` → `CAST(x AS BLOB)`: the stored bytes (in a UTF-16 database, the text itself);
|
|
26
|
+
- `BLOB` → the bytes.
|
|
27
|
+
|
|
28
|
+
## Notes per class
|
|
29
|
+
|
|
30
|
+
### `INTEGER`
|
|
31
|
+
|
|
32
|
+
Exact across the full 64-bit range. `AUTOINCREMENT` counters are read as text too, so a
|
|
33
|
+
counter past 2^53 resumes at exactly the right value.
|
|
34
|
+
|
|
35
|
+
### `REAL`
|
|
36
|
+
|
|
37
|
+
The literal round-trips to the identical double: `%!.20g` carries more than the 17
|
|
38
|
+
significant digits that identify one. The digits beyond the 17th vary between SQLite
|
|
39
|
+
releases (see [native-compatibility.md](native-compatibility.md#the-one-exception-real-digit-tails)),
|
|
40
|
+
never the value.
|
|
41
|
+
|
|
42
|
+
A `REAL` holding an integral value is written with `.0` (`3.0`), so it is restored as a
|
|
43
|
+
`REAL`, not an `INTEGER`. `-0.0` is written as `0.0`, as natively.
|
|
44
|
+
|
|
45
|
+
### `TEXT`
|
|
46
|
+
|
|
47
|
+
- **Quoting:** the only escape SQLite has is a doubled `'`. There are no backslash escapes.
|
|
48
|
+
- **Newlines and carriage returns** are written as `replace('…\n…','\n',char(10))` (and
|
|
49
|
+
`char(13)`), with a placeholder that does not otherwise occur in the text — so each
|
|
50
|
+
`INSERT` stays on one line and survives tools that rewrite line endings. With
|
|
51
|
+
`dataExport.rawNewlines` (native `--newlines`) they are written raw instead.
|
|
52
|
+
- **Bytes that are not valid UTF-8** — SQLite does not validate what it stores — are
|
|
53
|
+
written raw, as natively, so the dump reproduces the stored value exactly. Such a dump is
|
|
54
|
+
not valid UTF-8, which is why the writer and the restore handle bytes. On restore through
|
|
55
|
+
a JavaScript driver, such a literal is executed as `CAST(X'…' AS TEXT)`, the identical
|
|
56
|
+
bytes.
|
|
57
|
+
- **`NUL` characters** are kept, written as `'a'||char(0)||'b'`. The native shell truncates
|
|
58
|
+
text at the first `NUL`; this is the one place this package writes something the shell
|
|
59
|
+
would not, and only for text the shell cannot represent.
|
|
60
|
+
|
|
61
|
+
### `BLOB`
|
|
62
|
+
|
|
63
|
+
Always hex. An empty blob is `X''`, distinct from `NULL` and from the empty string `''`.
|
|
64
|
+
|
|
65
|
+
## Declared types
|
|
66
|
+
|
|
67
|
+
A column's declared type — `VARCHAR(20)`, `DATETIME`, `BOOLEAN`, `JSON`, or none at all —
|
|
68
|
+
is part of the table's DDL and is reproduced verbatim. It only determines the column's
|
|
69
|
+
_affinity_, which SQLite applies on insert; since every value is written in the storage
|
|
70
|
+
class it already has, affinity cannot change it on restore. `STRICT` tables are restored as
|
|
71
|
+
`STRICT`, with their type checks.
|
|
72
|
+
|
|
73
|
+
Dates and times have no storage class of their own in SQLite; they are whatever text,
|
|
74
|
+
number or blob the application stored, and are dumped as such.
|
|
@@ -1,85 +1,85 @@
|
|
|
1
|
-
# Supported objects
|
|
2
|
-
|
|
3
|
-
"Round-trip tested" means the object survives dump → restore and the restored database's
|
|
4
|
-
schema and rows deep-compare equal to the source, across all four paths of the
|
|
5
|
-
interoperability matrix (this package and the native `sqlite3` shell, each dumping and each
|
|
6
|
-
restoring).
|
|
7
|
-
|
|
8
|
-
## Object matrix
|
|
9
|
-
|
|
10
|
-
| Object | Dumped | Restored | Round-trip tested | Notes |
|
|
11
|
-
| -------------------------------------- | :----: | :------: | :---------------: | ---------------------------------------------------------------------- |
|
|
12
|
-
| Tables | ✅ | ✅ | ✅ | Verbatim stored DDL, so every clause survives. |
|
|
13
|
-
| Columns, defaults, collations, `CHECK` | ✅ | ✅ | ✅ | Inline in the table DDL. |
|
|
14
|
-
| Primary keys, `UNIQUE` constraints | ✅ | ✅ | ✅ | Their automatic indexes are recreated by the table DDL. |
|
|
15
|
-
| Foreign keys | ✅ | ✅ | ✅ | Circular and self-referencing both covered. |
|
|
16
|
-
| `INTEGER PRIMARY KEY` (rowid alias) | ✅ | ✅ | ✅ | The rowid _is_ the column, so it is always kept. |
|
|
17
|
-
| Hidden rowids | ✅ | ⚠️ | ✅ | Renumbered unless `preserveRowids`; see below. |
|
|
18
|
-
| `AUTOINCREMENT` counters | ✅ | ✅ | ✅ | `sqlite_sequence`, set after the rows. |
|
|
19
|
-
| `WITHOUT ROWID` tables | ✅ | ✅ | ✅ | |
|
|
20
|
-
| `STRICT` tables | ✅ | ✅ | ✅ | SQLite 3.37+ on the restoring side. |
|
|
21
|
-
| Generated columns (`VIRTUAL`/`STORED`) | ✅ | ✅ | ✅ | Not inserted; SQLite recomputes them. |
|
|
22
|
-
| Quoted and keyword names | ✅ | ✅ | ✅ | `"…"`, `'…'`, `[…]`, keywords, non-ASCII. |
|
|
23
|
-
| Indexes | ✅ | ✅ | ✅ | Partial, expression, `DESC`, `COLLATE`. |
|
|
24
|
-
| Views | ✅ | ✅ | ✅ | Including one created before the table it reads. |
|
|
25
|
-
| Triggers | ✅ | ✅ | ✅ | Multi-statement bodies; `INSTEAD OF` on views; created after the data. |
|
|
26
|
-
| Virtual tables (FTS5, R-tree, …) | ✅ | ✅ | ✅ | Shadow tables copied exactly; queryable after restore. |
|
|
27
|
-
| Statistics (`sqlite_stat1`/`stat4`) | ✅ | ✅ | ✅ | `ANALYZE sqlite_schema;` then the rows. |
|
|
28
|
-
| `user_version`, `application_id` | ⚙️ | ✅ | ✅ | With `render.includeDatabaseSettings`; otherwise reported. |
|
|
29
|
-
| Attached databases | ⚙️ | ✅ | — | One schema per dump: pass `schemaName`. |
|
|
30
|
-
| File settings (page size, WAL, …) | ❌ | — | — | See [known-limitations.md](known-limitations.md). |
|
|
31
|
-
| Application functions and collations | ❌ | — | — | Registered by the application, not stored in the database. |
|
|
32
|
-
|
|
33
|
-
⚙️ = opt-in.
|
|
34
|
-
|
|
35
|
-
## Model coverage
|
|
36
|
-
|
|
37
|
-
`introspectSqlite` returns a normalized `SqliteDatabase`:
|
|
38
|
-
|
|
39
|
-
```ts
|
|
40
|
-
{
|
|
41
|
-
schemaName, encoding, userVersion, applicationId, pageSize,
|
|
42
|
-
tables: SqliteTable[], // kind (table | virtual | shadow | system), sql, withoutRowid, strict,
|
|
43
|
-
// hasAutoincrement, virtualModule, ownerVirtualTable, rowidAliasColumn, columns
|
|
44
|
-
indexes: SqliteIndex[], // tableName, sql (null for automatic), isUnique, origin, isPartial, columns
|
|
45
|
-
views: SqliteView[],
|
|
46
|
-
triggers: SqliteTrigger[], // tableName
|
|
47
|
-
foreignKeys: SqliteForeignKey[], // referencedTableName, column pairs, onUpdate, onDelete, match
|
|
48
|
-
sequences: SqliteSequence[], // AUTOINCREMENT counters, as exact text
|
|
49
|
-
}
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
Per column: `declaredType` as written, `notNull`, `defaultValue` as written,
|
|
53
|
-
`primaryKeyPosition`, and `hidden`/`generated` from `PRAGMA table_xinfo`.
|
|
54
|
-
|
|
55
|
-
Every object also carries its `sqlite_schema` rowid (`schemaRowid`), which is the order the
|
|
56
|
-
dump uses.
|
|
57
|
-
|
|
58
|
-
## Notable behaviours
|
|
59
|
-
|
|
60
|
-
### Hidden rowids
|
|
61
|
-
|
|
62
|
-
A table without an `INTEGER PRIMARY KEY` still has a rowid, just not a declared column. The
|
|
63
|
-
native `.dump` does not write it, so a restore numbers the rows 1, 2, 3… in dump order —
|
|
64
|
-
closing any gaps deletions left. With `dataExport.preserveRowids` (the native
|
|
65
|
-
`--preserve-rowids`), the rowid is named in each `INSERT` and kept, under the first of
|
|
66
|
-
`rowid`, `_rowid_`, `oid` that is not a real column.
|
|
67
|
-
|
|
68
|
-
### Triggers
|
|
69
|
-
|
|
70
|
-
Created after all table data. A trigger created before the load would fire once per
|
|
71
|
-
restored row — an `AFTER INSERT` trigger writing an audit table would fabricate rows the
|
|
72
|
-
source never had. The archive records that as a _hard_ dependency. A trigger whose table is
|
|
73
|
-
not selected is dropped and reported.
|
|
74
|
-
|
|
75
|
-
### Virtual tables
|
|
76
|
-
|
|
77
|
-
Recreated the way the native `.dump` does it — by inserting the table's `sqlite_schema` row
|
|
78
|
-
directly, under `PRAGMA writable_schema=ON` — then filling the shadow tables with the
|
|
79
|
-
source's exact rows. The module's constructor never runs, so an FTS5 index or an R-tree
|
|
80
|
-
comes back byte-identical rather than rebuilt. This needs defensive mode off on the
|
|
81
|
-
restoring handle, which the restore arranges and undoes (see
|
|
82
|
-
[restore-api.md](restore-api.md#schemawrites)).
|
|
83
|
-
|
|
84
|
-
A schema-only dump instead creates each virtual table with its own `CREATE VIRTUAL TABLE`,
|
|
85
|
-
since no shadow rows follow and the module must set up its storage itself.
|
|
1
|
+
# Supported objects
|
|
2
|
+
|
|
3
|
+
"Round-trip tested" means the object survives dump → restore and the restored database's
|
|
4
|
+
schema and rows deep-compare equal to the source, across all four paths of the
|
|
5
|
+
interoperability matrix (this package and the native `sqlite3` shell, each dumping and each
|
|
6
|
+
restoring).
|
|
7
|
+
|
|
8
|
+
## Object matrix
|
|
9
|
+
|
|
10
|
+
| Object | Dumped | Restored | Round-trip tested | Notes |
|
|
11
|
+
| -------------------------------------- | :----: | :------: | :---------------: | ---------------------------------------------------------------------- |
|
|
12
|
+
| Tables | ✅ | ✅ | ✅ | Verbatim stored DDL, so every clause survives. |
|
|
13
|
+
| Columns, defaults, collations, `CHECK` | ✅ | ✅ | ✅ | Inline in the table DDL. |
|
|
14
|
+
| Primary keys, `UNIQUE` constraints | ✅ | ✅ | ✅ | Their automatic indexes are recreated by the table DDL. |
|
|
15
|
+
| Foreign keys | ✅ | ✅ | ✅ | Circular and self-referencing both covered. |
|
|
16
|
+
| `INTEGER PRIMARY KEY` (rowid alias) | ✅ | ✅ | ✅ | The rowid _is_ the column, so it is always kept. |
|
|
17
|
+
| Hidden rowids | ✅ | ⚠️ | ✅ | Renumbered unless `preserveRowids`; see below. |
|
|
18
|
+
| `AUTOINCREMENT` counters | ✅ | ✅ | ✅ | `sqlite_sequence`, set after the rows. |
|
|
19
|
+
| `WITHOUT ROWID` tables | ✅ | ✅ | ✅ | |
|
|
20
|
+
| `STRICT` tables | ✅ | ✅ | ✅ | SQLite 3.37+ on the restoring side. |
|
|
21
|
+
| Generated columns (`VIRTUAL`/`STORED`) | ✅ | ✅ | ✅ | Not inserted; SQLite recomputes them. |
|
|
22
|
+
| Quoted and keyword names | ✅ | ✅ | ✅ | `"…"`, `'…'`, `[…]`, keywords, non-ASCII. |
|
|
23
|
+
| Indexes | ✅ | ✅ | ✅ | Partial, expression, `DESC`, `COLLATE`. |
|
|
24
|
+
| Views | ✅ | ✅ | ✅ | Including one created before the table it reads. |
|
|
25
|
+
| Triggers | ✅ | ✅ | ✅ | Multi-statement bodies; `INSTEAD OF` on views; created after the data. |
|
|
26
|
+
| Virtual tables (FTS5, R-tree, …) | ✅ | ✅ | ✅ | Shadow tables copied exactly; queryable after restore. |
|
|
27
|
+
| Statistics (`sqlite_stat1`/`stat4`) | ✅ | ✅ | ✅ | `ANALYZE sqlite_schema;` then the rows. |
|
|
28
|
+
| `user_version`, `application_id` | ⚙️ | ✅ | ✅ | With `render.includeDatabaseSettings`; otherwise reported. |
|
|
29
|
+
| Attached databases | ⚙️ | ✅ | — | One schema per dump: pass `schemaName`. |
|
|
30
|
+
| File settings (page size, WAL, …) | ❌ | — | — | See [known-limitations.md](known-limitations.md). |
|
|
31
|
+
| Application functions and collations | ❌ | — | — | Registered by the application, not stored in the database. |
|
|
32
|
+
|
|
33
|
+
⚙️ = opt-in.
|
|
34
|
+
|
|
35
|
+
## Model coverage
|
|
36
|
+
|
|
37
|
+
`introspectSqlite` returns a normalized `SqliteDatabase`:
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
{
|
|
41
|
+
schemaName, encoding, userVersion, applicationId, pageSize,
|
|
42
|
+
tables: SqliteTable[], // kind (table | virtual | shadow | system), sql, withoutRowid, strict,
|
|
43
|
+
// hasAutoincrement, virtualModule, ownerVirtualTable, rowidAliasColumn, columns
|
|
44
|
+
indexes: SqliteIndex[], // tableName, sql (null for automatic), isUnique, origin, isPartial, columns
|
|
45
|
+
views: SqliteView[],
|
|
46
|
+
triggers: SqliteTrigger[], // tableName
|
|
47
|
+
foreignKeys: SqliteForeignKey[], // referencedTableName, column pairs, onUpdate, onDelete, match
|
|
48
|
+
sequences: SqliteSequence[], // AUTOINCREMENT counters, as exact text
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Per column: `declaredType` as written, `notNull`, `defaultValue` as written,
|
|
53
|
+
`primaryKeyPosition`, and `hidden`/`generated` from `PRAGMA table_xinfo`.
|
|
54
|
+
|
|
55
|
+
Every object also carries its `sqlite_schema` rowid (`schemaRowid`), which is the order the
|
|
56
|
+
dump uses.
|
|
57
|
+
|
|
58
|
+
## Notable behaviours
|
|
59
|
+
|
|
60
|
+
### Hidden rowids
|
|
61
|
+
|
|
62
|
+
A table without an `INTEGER PRIMARY KEY` still has a rowid, just not a declared column. The
|
|
63
|
+
native `.dump` does not write it, so a restore numbers the rows 1, 2, 3… in dump order —
|
|
64
|
+
closing any gaps deletions left. With `dataExport.preserveRowids` (the native
|
|
65
|
+
`--preserve-rowids`), the rowid is named in each `INSERT` and kept, under the first of
|
|
66
|
+
`rowid`, `_rowid_`, `oid` that is not a real column.
|
|
67
|
+
|
|
68
|
+
### Triggers
|
|
69
|
+
|
|
70
|
+
Created after all table data. A trigger created before the load would fire once per
|
|
71
|
+
restored row — an `AFTER INSERT` trigger writing an audit table would fabricate rows the
|
|
72
|
+
source never had. The archive records that as a _hard_ dependency. A trigger whose table is
|
|
73
|
+
not selected is dropped and reported.
|
|
74
|
+
|
|
75
|
+
### Virtual tables
|
|
76
|
+
|
|
77
|
+
Recreated the way the native `.dump` does it — by inserting the table's `sqlite_schema` row
|
|
78
|
+
directly, under `PRAGMA writable_schema=ON` — then filling the shadow tables with the
|
|
79
|
+
source's exact rows. The module's constructor never runs, so an FTS5 index or an R-tree
|
|
80
|
+
comes back byte-identical rather than rebuilt. This needs defensive mode off on the
|
|
81
|
+
restoring handle, which the restore arranges and undoes (see
|
|
82
|
+
[restore-api.md](restore-api.md#schemawrites)).
|
|
83
|
+
|
|
84
|
+
A schema-only dump instead creates each virtual table with its own `CREATE VIRTUAL TABLE`,
|
|
85
|
+
since no shadow rows follow and the module must set up its storage itself.
|
package/package.json
CHANGED
|
@@ -1,89 +1,96 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "dbgate-sqlite-dumper",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "Standalone, client-agnostic SQLite SQL dump and restore library for Node.js, compatible with the native sqlite3 .dump command",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"license": "GPL-3.0-only",
|
|
7
|
-
"repository": {
|
|
8
|
-
"type": "git",
|
|
9
|
-
"url": "git+https://github.com/dbgate/dbgate-sqlite-dumper.git"
|
|
10
|
-
},
|
|
11
|
-
"bugs": {
|
|
12
|
-
"url": "https://github.com/dbgate/dbgate-sqlite-dumper/issues"
|
|
13
|
-
},
|
|
14
|
-
"homepage": "https://github.com/dbgate/dbgate-sqlite-dumper#readme",
|
|
15
|
-
"engines": {
|
|
16
|
-
"node": ">=20"
|
|
17
|
-
},
|
|
18
|
-
"files": [
|
|
19
|
-
"LICENSE",
|
|
20
|
-
"README.md",
|
|
21
|
-
"dist",
|
|
22
|
-
"docs"
|
|
23
|
-
],
|
|
24
|
-
"main": "./dist/index.cjs",
|
|
25
|
-
"module": "./dist/index.js",
|
|
26
|
-
"types": "./dist/index.d.ts",
|
|
27
|
-
"exports": {
|
|
28
|
-
".": {
|
|
29
|
-
"types": "./dist/index.d.ts",
|
|
30
|
-
"import": "./dist/index.js",
|
|
31
|
-
"require": "./dist/index.cjs"
|
|
32
|
-
},
|
|
33
|
-
"./better-sqlite3": {
|
|
34
|
-
"types": "./dist/better-sqlite3.d.ts",
|
|
35
|
-
"import": "./dist/better-sqlite3.js",
|
|
36
|
-
"require": "./dist/better-sqlite3.cjs"
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
"
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
"
|
|
86
|
-
"
|
|
87
|
-
"
|
|
88
|
-
|
|
89
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "dbgate-sqlite-dumper",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Standalone, client-agnostic SQLite SQL dump and restore library for Node.js, compatible with the native sqlite3 .dump command, with adapters for better-sqlite3 and Cloudflare D1",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "GPL-3.0-only",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/dbgate/dbgate-sqlite-dumper.git"
|
|
10
|
+
},
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/dbgate/dbgate-sqlite-dumper/issues"
|
|
13
|
+
},
|
|
14
|
+
"homepage": "https://github.com/dbgate/dbgate-sqlite-dumper#readme",
|
|
15
|
+
"engines": {
|
|
16
|
+
"node": ">=20"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"LICENSE",
|
|
20
|
+
"README.md",
|
|
21
|
+
"dist",
|
|
22
|
+
"docs"
|
|
23
|
+
],
|
|
24
|
+
"main": "./dist/index.cjs",
|
|
25
|
+
"module": "./dist/index.js",
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"import": "./dist/index.js",
|
|
31
|
+
"require": "./dist/index.cjs"
|
|
32
|
+
},
|
|
33
|
+
"./better-sqlite3": {
|
|
34
|
+
"types": "./dist/better-sqlite3.d.ts",
|
|
35
|
+
"import": "./dist/better-sqlite3.js",
|
|
36
|
+
"require": "./dist/better-sqlite3.cjs"
|
|
37
|
+
},
|
|
38
|
+
"./d1": {
|
|
39
|
+
"types": "./dist/d1.d.ts",
|
|
40
|
+
"import": "./dist/d1.js",
|
|
41
|
+
"require": "./dist/d1.cjs"
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"scripts": {
|
|
45
|
+
"build": "tsup",
|
|
46
|
+
"clean": "tsup --clean",
|
|
47
|
+
"format": "prettier --write .",
|
|
48
|
+
"format:check": "prettier --check .",
|
|
49
|
+
"lint": "eslint . --max-warnings 0",
|
|
50
|
+
"prepublishOnly": "npm run lint && npm run typecheck && npm test && npm run build && node scripts/smoke.mjs",
|
|
51
|
+
"test": "vitest run",
|
|
52
|
+
"test:all": "npm run test && npm run test:integration",
|
|
53
|
+
"test:integration": "vitest run --config vitest.integration.config.ts",
|
|
54
|
+
"test:package": "npm run build && node scripts/smoke.mjs",
|
|
55
|
+
"test:watch": "vitest",
|
|
56
|
+
"typecheck": "tsc --noEmit"
|
|
57
|
+
},
|
|
58
|
+
"keywords": [
|
|
59
|
+
"sqlite",
|
|
60
|
+
"sqlite3",
|
|
61
|
+
"dump",
|
|
62
|
+
".dump",
|
|
63
|
+
"sql",
|
|
64
|
+
"backup",
|
|
65
|
+
"restore",
|
|
66
|
+
"database",
|
|
67
|
+
"better-sqlite3",
|
|
68
|
+
"cloudflare",
|
|
69
|
+
"d1"
|
|
70
|
+
],
|
|
71
|
+
"sideEffects": false,
|
|
72
|
+
"publishConfig": {
|
|
73
|
+
"access": "public",
|
|
74
|
+
"provenance": true
|
|
75
|
+
},
|
|
76
|
+
"peerDependencies": {
|
|
77
|
+
"better-sqlite3": ">=9.0.0"
|
|
78
|
+
},
|
|
79
|
+
"peerDependenciesMeta": {
|
|
80
|
+
"better-sqlite3": {
|
|
81
|
+
"optional": true
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
"devDependencies": {
|
|
85
|
+
"@eslint/js": "^9.25.1",
|
|
86
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
87
|
+
"@types/node": "^22.15.3",
|
|
88
|
+
"better-sqlite3": "^12.2.0",
|
|
89
|
+
"eslint": "^9.25.1",
|
|
90
|
+
"prettier": "^3.5.3",
|
|
91
|
+
"tsup": "^8.4.0",
|
|
92
|
+
"typescript": "^5.8.3",
|
|
93
|
+
"typescript-eslint": "^8.31.0",
|
|
94
|
+
"vitest": "^3.1.2"
|
|
95
|
+
}
|
|
96
|
+
}
|