@zukhruf/sqlite-drift 0.0.0-stage → 0.3.30
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 +21 -0
- package/README.md +107 -2
- package/dist/declaration.d.ts +9 -0
- package/dist/declaration.d.ts.map +1 -0
- package/dist/declaration.js +83 -0
- package/dist/declaration.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/package.json +42 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ezzabuzaid
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,108 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @zukhruf/sqlite-drift
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A package keeps tables, indexes, views and triggers in a SQLite database. A later version of the package can declare them otherwise, for example with one more column. The database still stores the objects as the earlier version made them, and the new code fails on them, for example with `no such column`. This package compares the stored objects with their declaration, and makes the database store them as declared. No person keeps a version number. This is also known as declarative schema management, and the difference that it finds is known as schema drift.
|
|
4
|
+
|
|
5
|
+
The words in these documents have one meaning each. See the glossary in [CONTEXT.md](./CONTEXT.md).
|
|
6
|
+
|
|
7
|
+
## Use it
|
|
8
|
+
|
|
9
|
+
This project is an experiment. It uses only `node:sqlite`.
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npm install @zukhruf/sqlite-drift
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { mkdtempDisposable } from 'node:fs/promises';
|
|
17
|
+
import { tmpdir } from 'node:os';
|
|
18
|
+
import { join } from 'node:path';
|
|
19
|
+
import { DatabaseSync } from 'node:sqlite';
|
|
20
|
+
|
|
21
|
+
import { Declaration } from '@zukhruf/sqlite-drift';
|
|
22
|
+
|
|
23
|
+
await using scratch = await mkdtempDisposable(join(tmpdir(), 'drift-'));
|
|
24
|
+
using database = new DatabaseSync(join(scratch.path, 'app.sqlite'));
|
|
25
|
+
// An earlier version made the table without failed_at.
|
|
26
|
+
database.exec(`CREATE TABLE failures (directory TEXT PRIMARY KEY, error TEXT NOT NULL);
|
|
27
|
+
INSERT INTO failures VALUES ('/data/notes', 'denied')`);
|
|
28
|
+
|
|
29
|
+
const failures = new Declaration([
|
|
30
|
+
'CREATE TABLE failures (directory TEXT PRIMARY KEY, error TEXT NOT NULL, failed_at TEXT NOT NULL)',
|
|
31
|
+
]);
|
|
32
|
+
console.log(failures.drift(database));
|
|
33
|
+
failures.apply(database);
|
|
34
|
+
console.log(failures.drift(database));
|
|
35
|
+
console.log(database.prepare('SELECT count(*) AS rows FROM failures').get());
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Output:
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
stale
|
|
42
|
+
fits
|
|
43
|
+
[Object: null prototype] { rows: 0 }
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## A declaration compares the text that SQLite stores
|
|
47
|
+
|
|
48
|
+
- `new Declaration(statements)` makes the objects once in an empty database in memory, and keeps the text that SQLite stores for each one. [ADR 0001](./docs/adr/0001-compare-the-text-that-sqlite-stores.md) tells why.
|
|
49
|
+
- `drift(database)` gives `missing` when the database stores none of the objects, `fits` when it stores each one as declared, and `stale` for all other cases. It only reads, so it also works on a database opened read-only.
|
|
50
|
+
- Each change to a CREATE statement is drift: a column, a type, a CHECK, STRICT, the query of a view.
|
|
51
|
+
- A change of meaning with no change of text is not drift. When the meaning of a column changes, change its name too.
|
|
52
|
+
- SQLite takes names that are different only in ASCII case as one name.
|
|
53
|
+
|
|
54
|
+
## Apply makes the database store the declaration
|
|
55
|
+
|
|
56
|
+
- `apply(database)` does nothing when the drift is `fits`.
|
|
57
|
+
- When no stored object is stale, `apply` makes each missing object, and the other objects keep their rows.
|
|
58
|
+
- When one stored object is stale, `apply` replaces every object of the declaration, and their rows are gone. [ADR 0002](./docs/adr/0002-a-stale-object-replaces-the-whole-declaration.md) tells why.
|
|
59
|
+
- `apply` does not drop an object that the declaration does not name.
|
|
60
|
+
- In a transaction of the caller, `apply` works in a savepoint, and a rollback of the caller removes its changes. With no transaction, `apply` writes in its own `BEGIN IMMEDIATE` transaction.
|
|
61
|
+
- A caller that must keep the rows of a stale table asks `drift`, and changes the table itself.
|
|
62
|
+
|
|
63
|
+
## Write a declaration
|
|
64
|
+
|
|
65
|
+
- List a table before the tables that refer to it.
|
|
66
|
+
- A declaration must stand alone in an empty database. Do not declare a trigger or an index on a table that the declaration does not name, and do not use a function that only your connection registers.
|
|
67
|
+
- Give each table its own declaration when it must keep its rows while another table changes.
|
|
68
|
+
|
|
69
|
+
## Errors
|
|
70
|
+
|
|
71
|
+
| Error | When |
|
|
72
|
+
| ------------------------ | ------------------------------------------------------------------------------------- |
|
|
73
|
+
| The error of SQLite | `new Declaration` fails when a statement does not run in an empty database. |
|
|
74
|
+
| `database is locked` | `apply` with no transaction waits for the busy timeout of the connection, then fails. |
|
|
75
|
+
| The error of a statement | `apply` fails, and the database stays as it was. |
|
|
76
|
+
|
|
77
|
+
## The same concepts in other systems
|
|
78
|
+
|
|
79
|
+
| System | What it does |
|
|
80
|
+
| ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- |
|
|
81
|
+
| Röthlisberger's SQLite migrator | It makes the declaration in memory and compares `sqlite_schema`. It changes a stale table with the 12 steps of SQLite and keeps the rows. |
|
|
82
|
+
| Airbyte destinations | Each sync compares the final table with the stream (`existingSchemaMatchesStreamConfig`), and a soft reset makes a stale table again. |
|
|
83
|
+
| Drizzle Kit `push`, Prisma `db push` | They compare a declaration in TypeScript or in the Prisma language with the database, and change the database. |
|
|
84
|
+
| Android Room | It keeps a version number for migrations, and a hash of the declaration that finds a number that a person forgot to raise. |
|
|
85
|
+
| Kubernetes controllers | Each loop compares the desired state with the state that exists, and changes what is different. |
|
|
86
|
+
|
|
87
|
+
## Documentation
|
|
88
|
+
|
|
89
|
+
- [0001 Compare the text that SQLite stores](./docs/adr/0001-compare-the-text-that-sqlite-stores.md)
|
|
90
|
+
- [0002 A stale object replaces the whole declaration](./docs/adr/0002-a-stale-object-replaces-the-whole-declaration.md)
|
|
91
|
+
|
|
92
|
+
## Development
|
|
93
|
+
|
|
94
|
+
This package is part of the [zukhruf](../../../README.md) workspace. Run the commands from the workspace root.
|
|
95
|
+
|
|
96
|
+
```sh
|
|
97
|
+
npm install
|
|
98
|
+
npx nx run sqlite-drift:test # builds, then runs the tests in src/
|
|
99
|
+
npx nx run sqlite-drift:typecheck # formats, lints, then type checks
|
|
100
|
+
npx nx run sqlite-drift:build # compiles src/ to dist/
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
src/
|
|
105
|
+
index.ts the exports
|
|
106
|
+
declaration.ts Declaration and Drift
|
|
107
|
+
declaration.test.ts the tests, on real SQLite files
|
|
108
|
+
```
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { DatabaseSync } from 'node:sqlite';
|
|
2
|
+
export type Drift = 'missing' | 'stale' | 'fits';
|
|
3
|
+
export declare class Declaration {
|
|
4
|
+
#private;
|
|
5
|
+
constructor(statements: readonly string[]);
|
|
6
|
+
drift(database: DatabaseSync): Drift;
|
|
7
|
+
apply(database: DatabaseSync): void;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=declaration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"declaration.d.ts","sourceRoot":"","sources":["../src/declaration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAI3C,MAAM,MAAM,KAAK,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AAajD,qBAAa,WAAW;;gBAGV,UAAU,EAAE,SAAS,MAAM,EAAE;IAezC,KAAK,CAAC,QAAQ,EAAE,YAAY,GAAG,KAAK;IAgBpC,KAAK,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI;CAiCpC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { DatabaseSync } from 'node:sqlite';
|
|
2
|
+
// The tables, indexes, views and triggers a caller owns in a SQLite database,
|
|
3
|
+
// by the CREATE statements that make them. SQLite keeps the text of each
|
|
4
|
+
// CREATE in sqlite_schema. A declaration makes its objects once in an empty
|
|
5
|
+
// database in memory, so the declared text and the stored text both come from
|
|
6
|
+
// SQLite, and they compare as they are.
|
|
7
|
+
export class Declaration {
|
|
8
|
+
#objects;
|
|
9
|
+
constructor(statements) {
|
|
10
|
+
using blank = new DatabaseSync(':memory:');
|
|
11
|
+
for (const statement of statements)
|
|
12
|
+
blank.exec(statement);
|
|
13
|
+
this.#objects = blank
|
|
14
|
+
.prepare('SELECT "type", "name", "sql" FROM sqlite_schema WHERE "sql" IS NOT NULL ORDER BY rowid')
|
|
15
|
+
.all()
|
|
16
|
+
.map(({ type, name, sql }) => ({
|
|
17
|
+
type: String(type),
|
|
18
|
+
name: String(name),
|
|
19
|
+
sql: String(sql),
|
|
20
|
+
}));
|
|
21
|
+
}
|
|
22
|
+
drift(database) {
|
|
23
|
+
const pairs = this.#objects.map((object) => ({
|
|
24
|
+
object,
|
|
25
|
+
found: stored(database, object.name),
|
|
26
|
+
}));
|
|
27
|
+
if (pairs.every(({ found }) => found === undefined))
|
|
28
|
+
return 'missing';
|
|
29
|
+
return pairs.every(({ object, found }) => found?.sql === object.sql)
|
|
30
|
+
? 'fits'
|
|
31
|
+
: 'stale';
|
|
32
|
+
}
|
|
33
|
+
// Creates the objects the database does not store. When any stored object
|
|
34
|
+
// differs from its declaration, replaces every object of the declaration,
|
|
35
|
+
// with its rows: a table can refer to another, and SQLite drops a table only
|
|
36
|
+
// after nothing refers to its rows. Works inside the caller's transaction,
|
|
37
|
+
// or in a write of its own. Objects the declaration does not name stay.
|
|
38
|
+
apply(database) {
|
|
39
|
+
if (this.drift(database) === 'fits')
|
|
40
|
+
return;
|
|
41
|
+
const ownsTransaction = !database.isTransaction;
|
|
42
|
+
database.exec(ownsTransaction ? 'BEGIN IMMEDIATE' : 'SAVEPOINT sqlite_drift');
|
|
43
|
+
try {
|
|
44
|
+
const stale = this.#objects.some((object) => {
|
|
45
|
+
const found = stored(database, object.name);
|
|
46
|
+
return found !== undefined && found.sql !== object.sql;
|
|
47
|
+
});
|
|
48
|
+
if (stale)
|
|
49
|
+
for (const object of this.#objects.toReversed()) {
|
|
50
|
+
const found = stored(database, object.name);
|
|
51
|
+
if (found !== undefined)
|
|
52
|
+
database.exec(`DROP ${found.type.toUpperCase()} ${quote(found.name)}`);
|
|
53
|
+
}
|
|
54
|
+
for (const object of this.#objects)
|
|
55
|
+
if (stored(database, object.name) === undefined)
|
|
56
|
+
database.exec(object.sql);
|
|
57
|
+
database.exec(ownsTransaction ? 'COMMIT' : 'RELEASE sqlite_drift');
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
if (!ownsTransaction) {
|
|
61
|
+
database.exec('ROLLBACK TO sqlite_drift');
|
|
62
|
+
database.exec('RELEASE sqlite_drift');
|
|
63
|
+
}
|
|
64
|
+
else if (database.isTransaction) {
|
|
65
|
+
database.exec('ROLLBACK');
|
|
66
|
+
}
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// SQLite takes names that differ only in ASCII case for one object.
|
|
72
|
+
function stored(database, name) {
|
|
73
|
+
const row = database
|
|
74
|
+
.prepare('SELECT "type", "name", "sql" FROM sqlite_schema WHERE lower("name") = lower(?)')
|
|
75
|
+
.get(name);
|
|
76
|
+
return row === undefined
|
|
77
|
+
? undefined
|
|
78
|
+
: { type: String(row.type), name: String(row.name), sql: String(row.sql) };
|
|
79
|
+
}
|
|
80
|
+
function quote(name) {
|
|
81
|
+
return `"${name.replaceAll('"', '""')}"`;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=declaration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"declaration.js","sourceRoot":"","sources":["../src/declaration.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,KAAK,KAAK,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAc,MAAM,kBAAkB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,44 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zukhruf/sqlite-drift",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.3.30",
|
|
4
|
+
"description": "Declarative schema management for SQLite. A declaration lists the CREATE statements of the tables, indexes, views and triggers that one caller owns. The package compares them with the text that SQLite stores, gives the drift (missing, fits or stale), and makes the database store each object as declared. No person keeps a version number.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/JanuaryLabs/zukhruf",
|
|
9
|
+
"directory": "packages/sqlite/drift"
|
|
10
|
+
},
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/JanuaryLabs/zukhruf/issues"
|
|
13
|
+
},
|
|
14
|
+
"homepage": "https://github.com/JanuaryLabs/zukhruf/tree/main/packages/sqlite/drift#readme",
|
|
15
|
+
"keywords": [
|
|
16
|
+
"sqlite",
|
|
17
|
+
"node-sqlite",
|
|
18
|
+
"schema",
|
|
19
|
+
"schema-drift",
|
|
20
|
+
"declarative-schema",
|
|
21
|
+
"migration",
|
|
22
|
+
"sqlite-schema",
|
|
23
|
+
"ddl"
|
|
24
|
+
],
|
|
25
|
+
"type": "module",
|
|
26
|
+
"exports": {
|
|
27
|
+
"./package.json": "./package.json",
|
|
28
|
+
".": {
|
|
29
|
+
"@zukhruf/source": "./src/index.ts",
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"import": "./dist/index.js",
|
|
32
|
+
"default": "./dist/index.js"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"files": [
|
|
36
|
+
"dist",
|
|
37
|
+
"!dist/spec/**",
|
|
38
|
+
"!**/*.tsbuildinfo",
|
|
39
|
+
"!**/*.test.*"
|
|
40
|
+
],
|
|
41
|
+
"publishConfig": {
|
|
42
|
+
"access": "public"
|
|
43
|
+
}
|
|
44
|
+
}
|