@voltro/database 0.78.0 → 0.79.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/CHANGELOG.md +113 -0
- package/dist/index.d.ts +30 -12
- package/dist/index.js +463 -463
- package/dist/{replaceInProgress-B1ZgTEI5.js → replaceInProgress-BmSjNTp0.js} +214 -206
- package/dist/sql.d.ts +261 -6
- package/dist/sql.js +1275 -1031
- package/package.json +2 -2
package/dist/sql.d.ts
CHANGED
|
@@ -603,6 +603,12 @@ declare interface ChangeStreamGap {
|
|
|
603
603
|
readonly downForMs?: number;
|
|
604
604
|
}
|
|
605
605
|
|
|
606
|
+
/** A live table's columns that carry a character set, with it. */
|
|
607
|
+
export declare const charsetColumnsOf: (table: TableSnapshot) => ReadonlyArray<{
|
|
608
|
+
readonly column: string;
|
|
609
|
+
readonly charset: string;
|
|
610
|
+
}>;
|
|
611
|
+
|
|
606
612
|
/** Partition into ≤`n`-sized chunks (disjoint, complete). Exported for the
|
|
607
613
|
* batching regression test — the introspection's correctness reduces to this
|
|
608
614
|
* producing a complete, non-overlapping partition of the table list. */
|
|
@@ -1685,6 +1691,25 @@ export declare interface ColumnSnapshot {
|
|
|
1685
1691
|
* blocks a masking export until classified.
|
|
1686
1692
|
*/
|
|
1687
1693
|
readonly safe?: boolean;
|
|
1694
|
+
/**
|
|
1695
|
+
* The character set a STRING column is stored in — MySQL / MariaDB only, and
|
|
1696
|
+
* only on columns the engine gives one (text, varchar, enum; never json,
|
|
1697
|
+
* which is `utf8mb4` on MariaDB and charset-less on MySQL by construction,
|
|
1698
|
+
* and never a number, a date or bytes).
|
|
1699
|
+
*
|
|
1700
|
+
* Live side: what `information_schema.columns.character_set_name` reports.
|
|
1701
|
+
* Declared side: the store's declared charset (`store: { dialect, charset }`
|
|
1702
|
+
* in `app.config.ts`), stamped on every string column — ABSENT when the app
|
|
1703
|
+
* declares none. The planner compares it only when BOTH sides carry one, so
|
|
1704
|
+
* an undeclared app never plans a conversion; and the fingerprint never
|
|
1705
|
+
* hashes it, because a live reading against an absent declaration would part
|
|
1706
|
+
* every table's two hashes forever. `storeCharset.ts` carries the reason.
|
|
1707
|
+
*
|
|
1708
|
+
* A `string`, not `MysqlCharset`: the reader reports whatever the column is
|
|
1709
|
+
* in (`latin1` is real), and a conversion FROM it is exactly what the
|
|
1710
|
+
* declaration is for. Only the declared side is limited to the two.
|
|
1711
|
+
*/
|
|
1712
|
+
readonly charset?: string;
|
|
1688
1713
|
/**
|
|
1689
1714
|
* Type PARAMETERS for the three `ColumnType`s whose DDL is not determined by
|
|
1690
1715
|
* the type tag alone — `vector(n)`, `array(of)`, `enum(name, values)`.
|
|
@@ -1724,10 +1749,39 @@ export declare interface ColumnSnapshot {
|
|
|
1724
1749
|
};
|
|
1725
1750
|
}
|
|
1726
1751
|
|
|
1752
|
+
/**
|
|
1753
|
+
* Does the declared column render a STRING type on the mysql family — the
|
|
1754
|
+
* columns a declared charset is stamped on? Mirrors `sqlType(_, 'mariadb')`:
|
|
1755
|
+
* text (LONGTEXT / VARCHAR / TEXT), enum (`ENUM(...)`), a typeid/ulid `id`
|
|
1756
|
+
* (VARCHAR(64)) and a text-stored `reference` (VARCHAR(64)). A numeric id or
|
|
1757
|
+
* reference is BIGINT; json / array are JSON; bytes is LONGBLOB — none carry a
|
|
1758
|
+
* character set. `raw` is the user's own DDL, which the framework does not
|
|
1759
|
+
* read, so it is left alone on both sides.
|
|
1760
|
+
*/
|
|
1761
|
+
export declare const columnTakesCharset: (col: Pick<ColumnSnapshot, "type" | "idScheme" | "idStorage" | "referenceStorage">) => boolean;
|
|
1762
|
+
|
|
1727
1763
|
declare type ColumnType = 'id' | 'text' | 'integer' | 'real' | 'decimal' | 'bigint' | 'boolean' | 'timestamp' | 'date' | 'json' | 'bytes' | 'reference' | 'vector' | 'enum' | 'array' | 'interval' | 'raw';
|
|
1728
1764
|
|
|
1729
1765
|
declare type ColumnType_2 = 'id' | 'text' | 'integer' | 'real' | 'decimal' | 'bigint' | 'boolean' | 'timestamp' | 'date' | 'json' | 'bytes' | 'reference' | 'vector' | 'enum' | 'array' | 'interval' | 'raw';
|
|
1730
1766
|
|
|
1767
|
+
/** A live foreign key a charset conversion has to carry across the rewrite. */
|
|
1768
|
+
export declare interface ConvertCharsetForeignKey {
|
|
1769
|
+
/** Catalog name of the constraint. */
|
|
1770
|
+
readonly name: string;
|
|
1771
|
+
/** The child (referencing) side. */
|
|
1772
|
+
readonly table: string;
|
|
1773
|
+
readonly column: string;
|
|
1774
|
+
readonly targetTable: string;
|
|
1775
|
+
readonly targetColumn: string;
|
|
1776
|
+
readonly onDelete?: 'cascade' | 'restrict' | 'setNull' | 'noAction';
|
|
1777
|
+
readonly onUpdate?: 'cascade' | 'restrict' | 'setNull' | 'noAction';
|
|
1778
|
+
/** Which operation re-creates it after the rewrite: this table's, or the
|
|
1779
|
+
* other endpoint's (`'peer'` — that table converts in the same plan and
|
|
1780
|
+
* sorts after this one). Dropping is done by whichever runs first; both
|
|
1781
|
+
* tolerate an already-absent constraint. */
|
|
1782
|
+
readonly restore: 'here' | 'peer';
|
|
1783
|
+
}
|
|
1784
|
+
|
|
1731
1785
|
/** The tables a plan CREATEs — the set every same-plan operation is checked against. */
|
|
1732
1786
|
export declare const createdTablesOf: (operations: ReadonlyArray<PlannedOperation>) => ReadonlySet<string>;
|
|
1733
1787
|
|
|
@@ -2260,13 +2314,24 @@ declare interface DataStore {
|
|
|
2260
2314
|
storedTables?(): ReadonlyArray<StoredTableShape>;
|
|
2261
2315
|
}
|
|
2262
2316
|
|
|
2317
|
+
export declare const declaredSnapshot: (tables: ReadonlyArray<TableLike>, dialect?: DialectId, options?: DeclaredSnapshotOptions) => SchemaSnapshot;
|
|
2318
|
+
|
|
2263
2319
|
/**
|
|
2264
2320
|
* Build a `SchemaSnapshot` from an array of `TableLike` declarations.
|
|
2265
2321
|
* Caller is responsible for passing the FULL set of tables (user-
|
|
2266
2322
|
* declared + framework). The fingerprint over this snapshot is what the
|
|
2267
2323
|
* boot-time prod check compares against `_voltro_migration_plans`.
|
|
2268
2324
|
*/
|
|
2269
|
-
export declare
|
|
2325
|
+
export declare interface DeclaredSnapshotOptions {
|
|
2326
|
+
/**
|
|
2327
|
+
* The store's declared character set (`store: { dialect, charset }`) —
|
|
2328
|
+
* stamped on every string column so the planner can compare it with what the
|
|
2329
|
+
* database reports. MySQL / MariaDB only: on any other dialect a charset is a
|
|
2330
|
+
* configuration error and is refused here rather than ignored, so a
|
|
2331
|
+
* declaration that cannot take effect never reads as one that did.
|
|
2332
|
+
*/
|
|
2333
|
+
readonly charset?: MysqlCharset | undefined;
|
|
2334
|
+
}
|
|
2270
2335
|
|
|
2271
2336
|
/** The NOTIFY channel a schema emits on when none is configured. */
|
|
2272
2337
|
export declare const DEFAULT_CDC_CHANNEL = "framework_changes";
|
|
@@ -2325,6 +2390,9 @@ export declare const describeOutcome: (outcome: BootMigrationOutcome, dialectId:
|
|
|
2325
2390
|
/** `bf_links`, `bf_links.ticket_key` — the spelling a message uses. */
|
|
2326
2391
|
export declare const describeProbe: (probe: SchemaProbe) => string;
|
|
2327
2392
|
|
|
2393
|
+
/** One line per finding, for the CLI and the doctor. */
|
|
2394
|
+
export declare const describeStoreCharsetFinding: (f: StoreCharsetFinding) => string;
|
|
2395
|
+
|
|
2328
2396
|
/**
|
|
2329
2397
|
* Parse `VOLTRO_DESTRUCTIVE_OK`.
|
|
2330
2398
|
*
|
|
@@ -2535,6 +2603,32 @@ export declare const emitAddIndexMysql: (op: Extract<MigrationOperation, {
|
|
|
2535
2603
|
kind: "add-index";
|
|
2536
2604
|
}>, declared: ReadonlyArray<TableLike>, engine?: MysqlEngine) => string;
|
|
2537
2605
|
|
|
2606
|
+
/**
|
|
2607
|
+
* The statements of a `convert-charset` operation, in order:
|
|
2608
|
+
*
|
|
2609
|
+
* 1. drop every foreign key that touches the table (either end) — the
|
|
2610
|
+
* engines refuse to change the charset of a column a constraint holds;
|
|
2611
|
+
* 2. ONE `ALTER TABLE` that MODIFYs each declared string column to its
|
|
2612
|
+
* declared definition plus `CHARACTER SET`, and sets the table default —
|
|
2613
|
+
* a single rewrite, not one per column, and never the json columns;
|
|
2614
|
+
* 3. re-create the constraints this operation owns (`restore: 'here'`); the
|
|
2615
|
+
* ones between two converting tables come back with the later table.
|
|
2616
|
+
*
|
|
2617
|
+
* Every column is rendered from the DECLARATION (`emitModifyColumnMysql` is
|
|
2618
|
+
* the same renderer the type and nullability operations use), because MODIFY
|
|
2619
|
+
* redefines the column and the declaration is the shape the plan converges
|
|
2620
|
+
* to. A generated column keeps its expression — MODIFY without it would drop
|
|
2621
|
+
* the generation — and a column keeps its column-level CHECK (`checks`, read
|
|
2622
|
+
* by `columnLevelChecksMysql`) for the same reason.
|
|
2623
|
+
*/
|
|
2624
|
+
export declare const emitConvertCharsetMysql: (op: Extract<MigrationOperation, {
|
|
2625
|
+
kind: "convert-charset";
|
|
2626
|
+
}>, declared: ReadonlyArray<TableLike>, checks?: ReadonlyMap<string, string>) => {
|
|
2627
|
+
readonly drops: ReadonlyArray<string>;
|
|
2628
|
+
readonly rewrite: string;
|
|
2629
|
+
readonly restores: ReadonlyArray<string>;
|
|
2630
|
+
};
|
|
2631
|
+
|
|
2538
2632
|
export declare const emitCreateTableMssql: (op: Extract<MigrationOperation, {
|
|
2539
2633
|
kind: "create-table";
|
|
2540
2634
|
}>) => ReadonlyArray<string>;
|
|
@@ -2613,7 +2707,7 @@ cdcChannel?: string) => string;
|
|
|
2613
2707
|
* containers are a deliberate non-goal (each tenant namespace is
|
|
2614
2708
|
* self-contained for its own tables).
|
|
2615
2709
|
*/
|
|
2616
|
-
export declare const emitNamespacedSchemaSql: (tables: ReadonlyArray<AnyTable>, dialect: DialectId, namespace: string, sqliteFile?: string) => string;
|
|
2710
|
+
export declare const emitNamespacedSchemaSql: (tables: ReadonlyArray<AnyTable>, dialect: DialectId, namespace: string, sqliteFile?: string, options?: SchemaEmitOptions) => string;
|
|
2617
2711
|
|
|
2618
2712
|
/**
|
|
2619
2713
|
* DDL that creates a tenant's namespace CONTAINER, per dialect:
|
|
@@ -2629,12 +2723,17 @@ export declare const emitNamespacedSchemaSql: (tables: ReadonlyArray<AnyTable>,
|
|
|
2629
2723
|
* errors if the alias is already attached, which the migrator treats as
|
|
2630
2724
|
* "already provisioned".
|
|
2631
2725
|
*/
|
|
2632
|
-
export declare const emitNamespaceProvisionDdl: (namespace: string, dialect: DialectId, sqliteFile?: string
|
|
2726
|
+
export declare const emitNamespaceProvisionDdl: (namespace: string, dialect: DialectId, sqliteFile?: string,
|
|
2727
|
+
/** The declared store charset (mysql family) — the new database's default,
|
|
2728
|
+
* so its tables inherit the declaration rather than the server default.
|
|
2729
|
+
* `IF NOT EXISTS` leaves an existing database's default alone (measured on
|
|
2730
|
+
* both engines); the tables' own column charsets still land. */
|
|
2731
|
+
charset?: MysqlCharset) => string;
|
|
2633
2732
|
|
|
2634
2733
|
export declare const emitSchemaSql: (entities: ReadonlyArray<AnyTable | AnyView>, dialect: DialectId,
|
|
2635
2734
|
/** NOTIFY channel for the reactive triggers. Must match the store's
|
|
2636
2735
|
* `cdcChannel`, or writes emit where nothing is listening. */
|
|
2637
|
-
cdcChannel?: string) => string;
|
|
2736
|
+
cdcChannel?: string, options?: SchemaEmitOptions) => string;
|
|
2638
2737
|
|
|
2639
2738
|
declare type EmptyMerge = unknown;
|
|
2640
2739
|
|
|
@@ -3315,6 +3414,8 @@ export declare const isAlreadySatisfied: (err: unknown, rules: ReadonlyArray<Alr
|
|
|
3315
3414
|
/** Type-guard for the discovery walker. */
|
|
3316
3415
|
export declare const isFileMigration: (value: unknown) => value is FileMigration;
|
|
3317
3416
|
|
|
3417
|
+
export declare const isMysqlCharset: (value: unknown) => value is MysqlCharset;
|
|
3418
|
+
|
|
3318
3419
|
/** Type guard — narrows an unknown value to a {@link RawSqlFragment}. */
|
|
3319
3420
|
export declare const isRawSqlFragment: (value: unknown) => value is RawSqlFragment;
|
|
3320
3421
|
|
|
@@ -3487,6 +3588,16 @@ export declare interface MigrationLockScope {
|
|
|
3487
3588
|
readonly schema?: string | undefined;
|
|
3488
3589
|
}
|
|
3489
3590
|
|
|
3591
|
+
/**
|
|
3592
|
+
* How a migration file becomes a module. The default imports the file itself;
|
|
3593
|
+
* a caller that holds the app's modules already — `voltro serve` from its
|
|
3594
|
+
* precompiled bundle — passes its own, so a boot that only ASKS what is pending
|
|
3595
|
+
* does not import each file's source and, through it, a second copy of this
|
|
3596
|
+
* package's whole migration graph. Measured on a boot with two migrations:
|
|
3597
|
+
* ~290 ms of held event loop, after the port was already answering probes.
|
|
3598
|
+
*/
|
|
3599
|
+
export declare type MigrationModuleImporter = (file: string) => Promise<Record<string, unknown>>;
|
|
3600
|
+
|
|
3490
3601
|
/**
|
|
3491
3602
|
* A migration context was built without a SQL client — over the in-memory
|
|
3492
3603
|
* store, the shape a unit test uses — and the body reached a surface that
|
|
@@ -3643,6 +3754,30 @@ export declare type MigrationOperation = {
|
|
|
3643
3754
|
readonly validation: 'value' | 'container';
|
|
3644
3755
|
readonly previousValidation: 'value' | 'container' | 'unverified' | 'absent';
|
|
3645
3756
|
readonly dropConstraints: ReadonlyArray<string>;
|
|
3757
|
+
}
|
|
3758
|
+
/**
|
|
3759
|
+
* Bring every string column of ONE table to the declared character set —
|
|
3760
|
+
* MySQL / MariaDB only. A table REWRITE: each named column is `MODIFY`ed to
|
|
3761
|
+
* its declared definition plus `CHARACTER SET`, and the table's default is
|
|
3762
|
+
* set so a later `ADD COLUMN` inherits it. json columns are never in
|
|
3763
|
+
* `columns` (their charset is the engine's, not the declaration's).
|
|
3764
|
+
*
|
|
3765
|
+
* `foreignKeys` are the constraints that touch this table — either end —
|
|
3766
|
+
* because neither engine changes the character set of a column a foreign
|
|
3767
|
+
* key holds (MariaDB 1832/1833, MySQL 3780). Each is dropped before the
|
|
3768
|
+
* rewrite and re-created after it; `restore` says which endpoint's operation
|
|
3769
|
+
* re-creates it, so a constraint between two converting tables comes back
|
|
3770
|
+
* only once both sides are at the target (the later of the two, by name).
|
|
3771
|
+
*/
|
|
3772
|
+
| {
|
|
3773
|
+
readonly kind: 'convert-charset';
|
|
3774
|
+
readonly table: string;
|
|
3775
|
+
readonly charset: MysqlCharset;
|
|
3776
|
+
/** The string columns to rewrite, in declaration order. */
|
|
3777
|
+
readonly columns: ReadonlyArray<string>;
|
|
3778
|
+
/** The character sets those columns are in today (for the plan line). */
|
|
3779
|
+
readonly from: ReadonlyArray<string>;
|
|
3780
|
+
readonly foreignKeys: ReadonlyArray<ConvertCharsetForeignKey>;
|
|
3646
3781
|
};
|
|
3647
3782
|
|
|
3648
3783
|
/**
|
|
@@ -3881,6 +4016,16 @@ declare interface MixinIndex {
|
|
|
3881
4016
|
readonly kindOptions?: IndexKindOptions;
|
|
3882
4017
|
}
|
|
3883
4018
|
|
|
4019
|
+
export declare const MYSQL_CHARSETS: ReadonlyArray<MysqlCharset>;
|
|
4020
|
+
|
|
4021
|
+
/**
|
|
4022
|
+
* The character sets a store can declare for its string columns on MySQL /
|
|
4023
|
+
* MariaDB. `utf8mb4` holds every Unicode scalar; `utf8mb3` (the engines' old
|
|
4024
|
+
* `utf8`) stops at three bytes and refuses emoji and most supplementary-plane
|
|
4025
|
+
* characters with errno 1366.
|
|
4026
|
+
*/
|
|
4027
|
+
export declare type MysqlCharset = 'utf8mb3' | 'utf8mb4';
|
|
4028
|
+
|
|
3884
4029
|
/** Which engine a `mysql`-dialect connection is actually talking to. */
|
|
3885
4030
|
export declare type MysqlEngine = 'mysql' | 'mariadb';
|
|
3886
4031
|
|
|
@@ -3903,6 +4048,11 @@ export declare type MysqlEngine = 'mysql' | 'mariadb';
|
|
|
3903
4048
|
*/
|
|
3904
4049
|
export declare const mysqlIndexPrefixFor: (col: ColumnSnapshot | undefined) => number | undefined;
|
|
3905
4050
|
|
|
4051
|
+
export declare interface NamespaceCharsetReport {
|
|
4052
|
+
readonly namespace: string;
|
|
4053
|
+
readonly findings: ReadonlyArray<StoreCharsetFinding>;
|
|
4054
|
+
}
|
|
4055
|
+
|
|
3906
4056
|
/**
|
|
3907
4057
|
* Type-narrowing migration marker. Tells the planner that this column
|
|
3908
4058
|
* previously had type `from` and is now being narrowed/converted to its
|
|
@@ -4066,7 +4216,9 @@ export declare const parseEnumCheck: (clause: string) => {
|
|
|
4066
4216
|
*/
|
|
4067
4217
|
export declare const pendingFileMigrationIds: (sql: SqlClient.SqlClient, projectRoot: string,
|
|
4068
4218
|
/** Absent: BOTH phases — a gate that asks "is anything pending at all". */
|
|
4069
|
-
phase?: MigrationPhase
|
|
4219
|
+
phase?: MigrationPhase,
|
|
4220
|
+
/** How each file is imported — see {@link MigrationModuleImporter}. */
|
|
4221
|
+
importModule?: MigrationModuleImporter) => Effect.Effect<ReadonlyArray<string>, unknown>;
|
|
4070
4222
|
|
|
4071
4223
|
/**
|
|
4072
4224
|
* What `runFileBasedMigrations` would execute next, with the one fact a deploy
|
|
@@ -4128,6 +4280,16 @@ export declare interface PlanInput {
|
|
|
4128
4280
|
* CLI populates it from `VOLTRO_DB_IGNORE_TABLES` (comma-separated names).
|
|
4129
4281
|
*/
|
|
4130
4282
|
readonly ignoreTables?: ReadonlyArray<string>;
|
|
4283
|
+
/**
|
|
4284
|
+
* The store's declared character set — `store: { dialect, charset }` in
|
|
4285
|
+
* `app.config.ts`. MySQL / MariaDB only; `declaredSnapshot` refuses it for
|
|
4286
|
+
* any other dialect. Declared, every table the app declares is CREATED with
|
|
4287
|
+
* it and, when a live table's string columns are stored otherwise, CONVERTED
|
|
4288
|
+
* to it (`convert-charset`, a table rewrite that carries the table's foreign
|
|
4289
|
+
* keys across). Absent, nothing is planned about character sets — see
|
|
4290
|
+
* `storeCharset.ts` for why that is the default and what is reported instead.
|
|
4291
|
+
*/
|
|
4292
|
+
readonly charset?: MysqlCharset | undefined;
|
|
4131
4293
|
}
|
|
4132
4294
|
|
|
4133
4295
|
/**
|
|
@@ -5280,6 +5442,9 @@ export declare interface RunPlannedMigrationsCtx {
|
|
|
5280
5442
|
/** How long a soft-drop snapshot may sit before the boot warns about it
|
|
5281
5443
|
* (`database.softDropRetentionDays`; default 7). */
|
|
5282
5444
|
readonly softDropRetentionDays?: number;
|
|
5445
|
+
/** The store's declared character set (`store: { dialect, charset }`),
|
|
5446
|
+
* MySQL / MariaDB only — threaded into every plan this boot computes. */
|
|
5447
|
+
readonly charset?: MysqlCharset | undefined;
|
|
5283
5448
|
}
|
|
5284
5449
|
|
|
5285
5450
|
/**
|
|
@@ -5295,6 +5460,9 @@ export declare interface RunPlannedMigrationsCtx {
|
|
|
5295
5460
|
*/
|
|
5296
5461
|
export declare const runSchemaOp: (sql: SqlClient.SqlClient, op: MigrationSchemaOp, live: SchemaSnapshot) => Effect.Effect<void, SqlError_2>;
|
|
5297
5462
|
|
|
5463
|
+
/** Runs one Effect over the connection — the shape `ManagedRuntime.runPromise` and a store's `run` share. */
|
|
5464
|
+
export declare type RunSql = <A>(effect: Effect.Effect<A, SqlError_2, SqlClient.SqlClient>) => Promise<A>;
|
|
5465
|
+
|
|
5298
5466
|
/**
|
|
5299
5467
|
* Effect that applies the emitted DDL to the provided SqlClient. Splits
|
|
5300
5468
|
* on `;` only outside dollar-quoted blocks (the postgres NOTIFY trigger
|
|
@@ -5320,11 +5488,22 @@ export declare const runSchemaOp: (sql: SqlClient.SqlClient, op: MigrationSchema
|
|
|
5320
5488
|
* absent → `DB_SCHEMA` from the environment, the same configuration the
|
|
5321
5489
|
* connection's `search_path` pin reads.
|
|
5322
5490
|
*/
|
|
5323
|
-
export declare interface SchemaApplyOptions {
|
|
5491
|
+
export declare interface SchemaApplyOptions extends SchemaEmitOptions {
|
|
5324
5492
|
readonly retryFilter?: (error: unknown) => RetryDecision;
|
|
5325
5493
|
readonly lockSchema?: string;
|
|
5326
5494
|
}
|
|
5327
5495
|
|
|
5496
|
+
export declare interface SchemaEmitOptions {
|
|
5497
|
+
/**
|
|
5498
|
+
* The store's declared character set — MySQL / MariaDB only. Every CREATE
|
|
5499
|
+
* TABLE carries it as the table default, so the bring-up path creates the
|
|
5500
|
+
* same tables the planner's `create-table` does. Refused for any other
|
|
5501
|
+
* dialect (a declaration that cannot take effect must not read as one that
|
|
5502
|
+
* did).
|
|
5503
|
+
*/
|
|
5504
|
+
readonly charset?: MysqlCharset | undefined;
|
|
5505
|
+
}
|
|
5506
|
+
|
|
5328
5507
|
/** What a schema operation on the migration context found to do. */
|
|
5329
5508
|
export declare type SchemaOpOutcome = 'applied' | 'already-absent' | 'already-present';
|
|
5330
5509
|
|
|
@@ -5518,6 +5697,57 @@ export declare interface SquashResult {
|
|
|
5518
5697
|
readonly snapshotId: string;
|
|
5519
5698
|
}
|
|
5520
5699
|
|
|
5700
|
+
/** The declared snapshot's tables with the store charset stamped on every string column. */
|
|
5701
|
+
export declare const stampDeclaredCharset: (tables: ReadonlyArray<TableSnapshot>, charset: MysqlCharset) => ReadonlyArray<TableSnapshot>;
|
|
5702
|
+
|
|
5703
|
+
/**
|
|
5704
|
+
* What to do about the findings, once. Names the real config field and the
|
|
5705
|
+
* command that applies it; nothing here is an env var.
|
|
5706
|
+
*/
|
|
5707
|
+
export declare const STORE_CHARSET_REMEDY: string;
|
|
5708
|
+
|
|
5709
|
+
/**
|
|
5710
|
+
* One table the store's character set is wrong about.
|
|
5711
|
+
*
|
|
5712
|
+
* - `disagrees-with-declaration` — the app declares a charset and these
|
|
5713
|
+
* columns are stored in another one. The plan carries the conversion; the
|
|
5714
|
+
* doctor names it for the operator who has not run `voltro db plan`.
|
|
5715
|
+
* - `json-outruns-text` — no declaration, and the table has a json column
|
|
5716
|
+
* (which holds every Unicode character on both engines) next to string
|
|
5717
|
+
* columns that do not. The reported symptom, as a line.
|
|
5718
|
+
* - `mixed` — no declaration, no json, and the table's string columns are not
|
|
5719
|
+
* all in one charset: a column converted by hand, or a column added under a
|
|
5720
|
+
* different database default. Two columns of one declaration disagree about
|
|
5721
|
+
* what a string is.
|
|
5722
|
+
*/
|
|
5723
|
+
export declare interface StoreCharsetFinding {
|
|
5724
|
+
readonly table: string;
|
|
5725
|
+
readonly kind: 'disagrees-with-declaration' | 'json-outruns-text' | 'mixed';
|
|
5726
|
+
/** The columns that are not where they should be, with the charset they are in. */
|
|
5727
|
+
readonly columns: ReadonlyArray<{
|
|
5728
|
+
readonly column: string;
|
|
5729
|
+
readonly charset: string;
|
|
5730
|
+
}>;
|
|
5731
|
+
/** What the finding measures against: the declaration, or `utf8mb4` for json. */
|
|
5732
|
+
readonly expected: string;
|
|
5733
|
+
}
|
|
5734
|
+
|
|
5735
|
+
/**
|
|
5736
|
+
* The tables whose string columns cannot hold what they should. Pure — over a
|
|
5737
|
+
* live snapshot the caller has already read — so `voltro db plan`, `voltro
|
|
5738
|
+
* doctor` and a test can ask the same question of the same reading.
|
|
5739
|
+
*
|
|
5740
|
+
* Zero findings on a healthy database is the contract: a `utf8mb4` database
|
|
5741
|
+
* with no declaration reports nothing, and so does any database whose every
|
|
5742
|
+
* string column matches its declaration. Measured against both engines in
|
|
5743
|
+
* `storeCharset.integration.test.ts`.
|
|
5744
|
+
*/
|
|
5745
|
+
export declare const storeCharsetFindings: (input: {
|
|
5746
|
+
readonly live: SchemaSnapshot;
|
|
5747
|
+
readonly dialect: DialectId;
|
|
5748
|
+
readonly charset?: MysqlCharset | undefined;
|
|
5749
|
+
}) => ReadonlyArray<StoreCharsetFinding>;
|
|
5750
|
+
|
|
5521
5751
|
/** One table as a store that has no catalog can describe it. See {@link DataStore.storedTables}. */
|
|
5522
5752
|
declare interface StoredTableShape {
|
|
5523
5753
|
/** The table's name, unqualified by any namespace the reporting view is bound to. */
|
|
@@ -6159,6 +6389,20 @@ declare interface TableUnique {
|
|
|
6159
6389
|
};
|
|
6160
6390
|
}
|
|
6161
6391
|
|
|
6392
|
+
/**
|
|
6393
|
+
* The tenant databases whose string columns are stored otherwise than the
|
|
6394
|
+
* declaration — or, undeclared, otherwise than their json columns. Only the
|
|
6395
|
+
* charset facts are read (type kind, charset), which is all the question
|
|
6396
|
+
* needs; a full introspection per tenant would be a catalog scan per tenant.
|
|
6397
|
+
*
|
|
6398
|
+
* Empty on a server with no tenant database, and empty when every tenant
|
|
6399
|
+
* agrees. Namespaces come out sorted.
|
|
6400
|
+
*/
|
|
6401
|
+
export declare const tenantNamespaceCharsetFindings: (run: RunSql, options: {
|
|
6402
|
+
readonly charset?: MysqlCharset | undefined;
|
|
6403
|
+
readonly dialect?: "mysql" | "mariadb";
|
|
6404
|
+
}) => Promise<ReadonlyArray<NamespaceCharsetReport>>;
|
|
6405
|
+
|
|
6162
6406
|
/**
|
|
6163
6407
|
* A `transactional` migration whose body committed the transaction from
|
|
6164
6408
|
* inside — DDL on the MySQL family, or an explicit COMMIT. The body's work
|
|
@@ -6288,6 +6532,17 @@ export declare const VOLTRO_MIGRATION_LOCK_KEY = 6322741009312437n;
|
|
|
6288
6532
|
/** Index-free for the same reason `_voltro_migration_ops` is: at most a row or two, ever. */
|
|
6289
6533
|
export declare const _voltroDeploysTable: TableLike;
|
|
6290
6534
|
|
|
6535
|
+
/**
|
|
6536
|
+
* Walk for migration files. Recursive; skips common build dirs.
|
|
6537
|
+
* Returns absolute paths sorted by basename (= timestamp-ordered
|
|
6538
|
+
* because the convention puts the timestamp at the start).
|
|
6539
|
+
*
|
|
6540
|
+
* Exported for `voltro build`, which must bundle exactly the files this walk
|
|
6541
|
+
* finds: every one `voltro serve` loads that is not in the bundle is imported
|
|
6542
|
+
* from source instead.
|
|
6543
|
+
*/
|
|
6544
|
+
export declare const walkMigrationFiles: (root: string) => Promise<ReadonlyArray<string>>;
|
|
6545
|
+
|
|
6291
6546
|
/**
|
|
6292
6547
|
* One aggregate column in a `SELECT` projection — `COUNT(*)`,
|
|
6293
6548
|
* `SUM(amount) AS total`, etc. Built via the `count() / sum() /
|