@adminiumjs/adapter-mysql 0.1.0-rc.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 +661 -0
- package/dist/errors.d.ts +11 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +94 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +57 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +250 -0
- package/dist/index.js.map +1 -0
- package/dist/introspect.d.ts +92 -0
- package/dist/introspect.d.ts.map +1 -0
- package/dist/introspect.js +620 -0
- package/dist/introspect.js.map +1 -0
- package/dist/query-engine.d.ts +10 -0
- package/dist/query-engine.d.ts.map +1 -0
- package/dist/query-engine.js +59 -0
- package/dist/query-engine.js.map +1 -0
- package/dist/serialization.d.ts +30 -0
- package/dist/serialization.d.ts.map +1 -0
- package/dist/serialization.js +59 -0
- package/dist/serialization.js.map +1 -0
- package/dist/stats.d.ts +21 -0
- package/dist/stats.d.ts.map +1 -0
- package/dist/stats.js +142 -0
- package/dist/stats.js.map +1 -0
- package/dist/type-map.d.ts +50 -0
- package/dist/type-map.d.ts.map +1 -0
- package/dist/type-map.js +193 -0
- package/dist/type-map.js.map +1 -0
- package/package.json +30 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-engine.d.ts","sourceRoot":"","sources":["../src/query-engine.ts"],"names":[],"mappings":"AAYA,OAAO,EAEL,KAAK,oBAAoB,EACzB,KAAK,WAAW,EACjB,MAAM,0BAA0B,CAAC;AAUlC;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,oBAAoB,GAAG,MAAM,GAAG,WAAW,CAmCpF"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `createQueryEngine()` — the Kysely dialect factory for the pooled data
|
|
3
|
+
* connection (05-introspection-engine.md §3 `QueryEngine`, 08-server-api.md
|
|
4
|
+
* §3.7 "query port").
|
|
5
|
+
*
|
|
6
|
+
* `@adminium/engine` does not depend on `kysely`, so `QueryEngine.dialect`
|
|
7
|
+
* is typed opaquely there; `@adminium/server` casts it to `kysely.Dialect`
|
|
8
|
+
* at the composition boundary. This package owns the concrete dependency.
|
|
9
|
+
*/
|
|
10
|
+
import { MysqlDialect } from 'kysely';
|
|
11
|
+
import mysql from 'mysql2';
|
|
12
|
+
import { AdapterError, } from '@adminium/engine/adapter';
|
|
13
|
+
import { MYSQL_MAX_IDENTIFIER_LENGTH, mysqlSerializers, quoteIdentifier, } from './serialization.js';
|
|
14
|
+
const DEFAULT_DATA_POOL_MAX = 10;
|
|
15
|
+
/**
|
|
16
|
+
* Build the CRUD query port for a data-role connection. Accepts a DSN string
|
|
17
|
+
* or the role-branded config (which must carry a `dsn`). Kysely's
|
|
18
|
+
* `MysqlDialect` consumes the callback-flavored mysql2 pool; connections are
|
|
19
|
+
* only opened on first query, and `destroy()` tears the pool down
|
|
20
|
+
* idempotently.
|
|
21
|
+
*/
|
|
22
|
+
export function createQueryEngine(config) {
|
|
23
|
+
const dsn = typeof config === 'string' ? config : config.dsn;
|
|
24
|
+
if (dsn === undefined || dsn.length === 0) {
|
|
25
|
+
throw new AdapterError('UNKNOWN', 'mysql query engine requires a DSN', {
|
|
26
|
+
hint: 'pass a mysql:// connection string (TLS options honored from the ssl params)',
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
const poolMax = typeof config === 'string' ? undefined : config.poolMax;
|
|
30
|
+
const pool = mysql.createPool({
|
|
31
|
+
uri: dsn,
|
|
32
|
+
connectionLimit: poolMax ?? DEFAULT_DATA_POOL_MAX,
|
|
33
|
+
});
|
|
34
|
+
// Structural cast: kysely ships its own minimal `MysqlPool` interface to
|
|
35
|
+
// avoid a dependency on mysql2 — the runtime shape of a mysql2 callback
|
|
36
|
+
// pool matches it exactly (kysely's own docs pass one here), and the
|
|
37
|
+
// dialect crosses the `QueryEngine` boundary as `unknown` anyway.
|
|
38
|
+
const kyselyPool = pool;
|
|
39
|
+
let destroyed = false;
|
|
40
|
+
return {
|
|
41
|
+
dialect: new MysqlDialect({ pool: kyselyPool }),
|
|
42
|
+
identifiers: { quote: quoteIdentifier, maxLength: MYSQL_MAX_IDENTIFIER_LENGTH },
|
|
43
|
+
serializers: mysqlSerializers,
|
|
44
|
+
async destroy() {
|
|
45
|
+
if (destroyed)
|
|
46
|
+
return;
|
|
47
|
+
destroyed = true;
|
|
48
|
+
await new Promise((resolve, reject) => {
|
|
49
|
+
pool.end((error) => {
|
|
50
|
+
if (error === undefined || error === null)
|
|
51
|
+
resolve();
|
|
52
|
+
else
|
|
53
|
+
reject(error);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=query-engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-engine.js","sourceRoot":"","sources":["../src/query-engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,YAAY,EAA2B,MAAM,QAAQ,CAAC;AAC/D,OAAO,KAAK,MAAM,QAAQ,CAAC;AAE3B,OAAO,EACL,YAAY,GAGb,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,2BAA2B,EAC3B,gBAAgB,EAChB,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,qBAAqB,GAAG,EAAE,CAAC;AAEjC;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAqC;IACrE,MAAM,GAAG,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;IAC7D,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1C,MAAM,IAAI,YAAY,CAAC,SAAS,EAAE,mCAAmC,EAAE;YACrE,IAAI,EAAE,6EAA6E;SACpF,CAAC,CAAC;IACL,CAAC;IACD,MAAM,OAAO,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;IACxE,MAAM,IAAI,GAAG,KAAK,CAAC,UAAU,CAAC;QAC5B,GAAG,EAAE,GAAG;QACR,eAAe,EAAE,OAAO,IAAI,qBAAqB;KAClD,CAAC,CAAC;IAEH,yEAAyE;IACzE,wEAAwE;IACxE,qEAAqE;IACrE,kEAAkE;IAClE,MAAM,UAAU,GAAG,IAA6C,CAAC;IAEjE,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,OAAO;QACL,OAAO,EAAE,IAAI,YAAY,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;QAC/C,WAAW,EAAE,EAAE,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,2BAA2B,EAAE;QAC/E,WAAW,EAAE,gBAAgB;QAC7B,KAAK,CAAC,OAAO;YACX,IAAI,SAAS;gBAAE,OAAO;YACtB,SAAS,GAAG,IAAI,CAAC;YACjB,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC1C,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;oBACjB,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI;wBAAE,OAAO,EAAE,CAAC;;wBAChD,MAAM,CAAC,KAAK,CAAC,CAAC;gBACrB,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Identifier quoting + per-LogicalType value serialization for the MySQL
|
|
3
|
+
* data connection — 05-introspection-engine.md §3 (`QueryEngine`) and
|
|
4
|
+
* 08-server-api.md §3.7. Pure module (no `mysql2`/`kysely` import) so the
|
|
5
|
+
* policy is unit-testable offline. Mirrors the postgres reference adapter.
|
|
6
|
+
*
|
|
7
|
+
* Serialization policy (05 §3 `TypeSerializer` contract):
|
|
8
|
+
* - `bigint` and `decimal` travel as STRINGS end to end — unsigned bigint
|
|
9
|
+
* exceeds Number.MAX_SAFE_INTEGER and JS numbers would silently lose
|
|
10
|
+
* precision (05 §4.2 flags this in QueryResult column meta).
|
|
11
|
+
* - `timestamp` (datetime) and `timestamptz` (timestamp) serialize to
|
|
12
|
+
* ISO-8601 UTC; `date` keeps its SQL text form (`YYYY-MM-DD`).
|
|
13
|
+
* - `boolean` maps tinyint(1)'s 0/1 wire form to real booleans.
|
|
14
|
+
* - `json` values pass through as parsed objects (mysql2 parses the JSON
|
|
15
|
+
* type); `toDb` stringifies so a single parameter binds.
|
|
16
|
+
* - BINARY POLICY: `binary` columns are EXCLUDED from CRUD v1 — no
|
|
17
|
+
* serializer is registered for `'binary'` (same as postgres bytea).
|
|
18
|
+
*/
|
|
19
|
+
import type { LogicalType, TypeSerializer } from '@adminium/engine/adapter';
|
|
20
|
+
/** MySQL truncates identifiers at 64 characters. */
|
|
21
|
+
export declare const MYSQL_MAX_IDENTIFIER_LENGTH = 64;
|
|
22
|
+
/**
|
|
23
|
+
* Backtick-quote an identifier, escaping embedded backticks. Identifiers are
|
|
24
|
+
* snapshot-validated before they ever reach this point (no raw SQL escape
|
|
25
|
+
* hatch — 05 §3); quoting is defense in depth, not sanitization.
|
|
26
|
+
*/
|
|
27
|
+
export declare function quoteIdentifier(identifier: string): string;
|
|
28
|
+
/** Per-LogicalType converters handed to the CRUD layer via `QueryEngine`. */
|
|
29
|
+
export declare const mysqlSerializers: Partial<Record<LogicalType, TypeSerializer>>;
|
|
30
|
+
//# sourceMappingURL=serialization.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serialization.d.ts","sourceRoot":"","sources":["../src/serialization.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE5E,oDAAoD;AACpD,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAE9C;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE1D;AA8BD,6EAA6E;AAC7E,eAAO,MAAM,gBAAgB,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,CAkBzE,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/** MySQL truncates identifiers at 64 characters. */
|
|
2
|
+
export const MYSQL_MAX_IDENTIFIER_LENGTH = 64;
|
|
3
|
+
/**
|
|
4
|
+
* Backtick-quote an identifier, escaping embedded backticks. Identifiers are
|
|
5
|
+
* snapshot-validated before they ever reach this point (no raw SQL escape
|
|
6
|
+
* hatch — 05 §3); quoting is defense in depth, not sanitization.
|
|
7
|
+
*/
|
|
8
|
+
export function quoteIdentifier(identifier) {
|
|
9
|
+
return `\`${identifier.replaceAll('`', '``')}\``;
|
|
10
|
+
}
|
|
11
|
+
function toIsoUtc(value) {
|
|
12
|
+
if (value instanceof Date)
|
|
13
|
+
return value.toISOString();
|
|
14
|
+
return value;
|
|
15
|
+
}
|
|
16
|
+
/** `YYYY-MM-DD` from a driver-parsed Date (local calendar date, not UTC). */
|
|
17
|
+
function toIsoDate(value) {
|
|
18
|
+
if (value instanceof Date) {
|
|
19
|
+
const month = String(value.getMonth() + 1).padStart(2, '0');
|
|
20
|
+
const day = String(value.getDate()).padStart(2, '0');
|
|
21
|
+
return `${value.getFullYear()}-${month}-${day}`;
|
|
22
|
+
}
|
|
23
|
+
return value;
|
|
24
|
+
}
|
|
25
|
+
function numericToDb(value) {
|
|
26
|
+
if (typeof value === 'bigint' || typeof value === 'number')
|
|
27
|
+
return value.toString();
|
|
28
|
+
return value;
|
|
29
|
+
}
|
|
30
|
+
const lossless = {
|
|
31
|
+
toDb: numericToDb,
|
|
32
|
+
fromDb: (value) => {
|
|
33
|
+
if (typeof value === 'number' || typeof value === 'bigint')
|
|
34
|
+
return value.toString();
|
|
35
|
+
return value;
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
/** Per-LogicalType converters handed to the CRUD layer via `QueryEngine`. */
|
|
39
|
+
export const mysqlSerializers = {
|
|
40
|
+
bigint: lossless,
|
|
41
|
+
decimal: lossless,
|
|
42
|
+
boolean: {
|
|
43
|
+
toDb: (value) => (typeof value === 'boolean' ? (value ? 1 : 0) : value),
|
|
44
|
+
fromDb: (value) => {
|
|
45
|
+
if (value === 1 || value === 0)
|
|
46
|
+
return value === 1;
|
|
47
|
+
return value;
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
timestamp: { toDb: (value) => value, fromDb: toIsoUtc },
|
|
51
|
+
timestamptz: { toDb: (value) => value, fromDb: toIsoUtc },
|
|
52
|
+
date: { toDb: (value) => value, fromDb: toIsoDate },
|
|
53
|
+
json: {
|
|
54
|
+
toDb: (value) => (typeof value === 'string' ? value : JSON.stringify(value)),
|
|
55
|
+
fromDb: (value) => value,
|
|
56
|
+
},
|
|
57
|
+
// NOTE: no 'binary' entry on purpose — blobs are excluded from CRUD v1.
|
|
58
|
+
};
|
|
59
|
+
//# sourceMappingURL=serialization.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serialization.js","sourceRoot":"","sources":["../src/serialization.ts"],"names":[],"mappings":"AAoBA,oDAAoD;AACpD,MAAM,CAAC,MAAM,2BAA2B,GAAG,EAAE,CAAC;AAE9C;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,UAAkB;IAChD,OAAO,KAAK,UAAU,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC;AACnD,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,IAAI,KAAK,YAAY,IAAI;QAAE,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC;IACtD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,6EAA6E;AAC7E,SAAS,SAAS,CAAC,KAAc;IAC/B,IAAI,KAAK,YAAY,IAAI,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAC5D,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACrD,OAAO,GAAG,KAAK,CAAC,WAAW,EAAE,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC;IAClD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,WAAW,CAAC,KAAc;IACjC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;IACpF,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,QAAQ,GAAmB;IAC/B,IAAI,EAAE,WAAW;IACjB,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;QAChB,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;QACpF,OAAO,KAAK,CAAC;IACf,CAAC;CACF,CAAC;AAEF,6EAA6E;AAC7E,MAAM,CAAC,MAAM,gBAAgB,GAAiD;IAC5E,MAAM,EAAE,QAAQ;IAChB,OAAO,EAAE,QAAQ;IACjB,OAAO,EAAE;QACP,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QACvE,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;YAChB,IAAI,KAAK,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC;gBAAE,OAAO,KAAK,KAAK,CAAC,CAAC;YACnD,OAAO,KAAK,CAAC;QACf,CAAC;KACF;IACD,SAAS,EAAE,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE;IACvD,WAAW,EAAE,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE;IACzD,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE;IACnD,IAAI,EAAE;QACJ,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAC5E,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK;KACzB;IACD,wEAAwE;CACzE,CAAC"}
|
package/dist/stats.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MySQL table-statistics collector — 06-llm-assist.md §4.2.
|
|
3
|
+
*
|
|
4
|
+
* Cheap-first strategy (sample-free by default): row-count from
|
|
5
|
+
* `information_schema.TABLES.TABLE_ROWS` (the InnoDB estimate) with an exact
|
|
6
|
+
* `COUNT(*)` fallback for small/stale tables. MySQL exposes no cheap
|
|
7
|
+
* per-column statistics catalog, so null-fraction and distinct-count come from
|
|
8
|
+
* a single bounded full-scan of aggregates (`SUM(col IS NULL)`,
|
|
9
|
+
* `COUNT(DISTINCT col)`) — aggregates only, never a cell value — and tables
|
|
10
|
+
* above `maxScanRows` degrade to `null` rather than a wrong number. Concrete
|
|
11
|
+
* values appear ONLY under the sampling opt-in, and NEVER for PII-suspected or
|
|
12
|
+
* secret columns.
|
|
13
|
+
*
|
|
14
|
+
* Executor-agnostic (like introspect.ts): takes a `sql → rows` runner so the
|
|
15
|
+
* logic is unit-testable without the `mysql2` driver.
|
|
16
|
+
*/
|
|
17
|
+
import type { CollectStatsOptions, StatsResult, TableRef } from '@adminium/engine/adapter';
|
|
18
|
+
/** Any `sql → rows` runner (the mysql2 data pool in production). */
|
|
19
|
+
export type StatsExecutor = (sql: string) => Promise<Record<string, unknown>[]>;
|
|
20
|
+
export declare function collectMysqlStats(exec: StatsExecutor, table: TableRef, opts?: CollectStatsOptions): Promise<StatsResult>;
|
|
21
|
+
//# sourceMappingURL=stats.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../src/stats.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EACV,mBAAmB,EAGnB,WAAW,EAEX,QAAQ,EACT,MAAM,0BAA0B,CAAC;AAUlC,oEAAoE;AACpE,MAAM,MAAM,aAAa,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;AAoDhF,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,aAAa,EACnB,KAAK,EAAE,QAAQ,EACf,IAAI,GAAE,mBAAwB,GAC7B,OAAO,CAAC,WAAW,CAAC,CAsGtB"}
|
package/dist/stats.js
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { STATS_DEFAULT_SAMPLE_VALUES, STATS_EXACT_COUNT_THRESHOLD, STATS_MAX_SCAN_ROWS, STATS_SAMPLE_VALUE_MAX_CHARS, } from '@adminium/engine/adapter';
|
|
2
|
+
import { quoteIdentifier } from './serialization.js';
|
|
3
|
+
/** Ordered logical types eligible for min/max under sampling opt-in. */
|
|
4
|
+
const ORDERED_TYPES = new Set([
|
|
5
|
+
'integer',
|
|
6
|
+
'bigint',
|
|
7
|
+
'decimal',
|
|
8
|
+
'float',
|
|
9
|
+
'date',
|
|
10
|
+
'time',
|
|
11
|
+
'timestamp',
|
|
12
|
+
'timestamptz',
|
|
13
|
+
]);
|
|
14
|
+
function num(value) {
|
|
15
|
+
if (value === null || value === undefined)
|
|
16
|
+
return null;
|
|
17
|
+
const n = Number(value);
|
|
18
|
+
return Number.isFinite(n) ? n : null;
|
|
19
|
+
}
|
|
20
|
+
function literal(value) {
|
|
21
|
+
return `'${value.replaceAll("'", "''")}'`;
|
|
22
|
+
}
|
|
23
|
+
function toScalar(value) {
|
|
24
|
+
if (value === null || value === undefined)
|
|
25
|
+
return null;
|
|
26
|
+
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
|
|
27
|
+
return value;
|
|
28
|
+
}
|
|
29
|
+
if (typeof value === 'bigint')
|
|
30
|
+
return value.toString();
|
|
31
|
+
if (value instanceof Date)
|
|
32
|
+
return value.toISOString();
|
|
33
|
+
if (value instanceof Uint8Array)
|
|
34
|
+
return '[binary]';
|
|
35
|
+
return String(value);
|
|
36
|
+
}
|
|
37
|
+
function truncate(value) {
|
|
38
|
+
if (typeof value === 'string' && value.length > STATS_SAMPLE_VALUE_MAX_CHARS) {
|
|
39
|
+
return value.slice(0, STATS_SAMPLE_VALUE_MAX_CHARS);
|
|
40
|
+
}
|
|
41
|
+
return value;
|
|
42
|
+
}
|
|
43
|
+
/** One batched full-scan: `COUNT(*)` + per-column null count + distinct count. */
|
|
44
|
+
function buildNullDistinctScan(qualified, columns) {
|
|
45
|
+
const parts = columns.map((name, k) => {
|
|
46
|
+
const q = quoteIdentifier(name);
|
|
47
|
+
return `sum(${q} IS NULL) AS nf_${k}, count(DISTINCT ${q}) AS dc_${k}`;
|
|
48
|
+
});
|
|
49
|
+
const cols = parts.length > 0 ? `, ${parts.join(', ')}` : '';
|
|
50
|
+
return `SELECT count(*) AS row_total${cols} FROM ${qualified}`;
|
|
51
|
+
}
|
|
52
|
+
export async function collectMysqlStats(exec, table, opts = {}) {
|
|
53
|
+
const name = table.name;
|
|
54
|
+
// MySQL has no schema layer — the pool is bound to one database. Qualify with
|
|
55
|
+
// the explicit schema when present, else the current database.
|
|
56
|
+
const qualified = table.schema !== null
|
|
57
|
+
? `${quoteIdentifier(table.schema)}.${quoteIdentifier(name)}`
|
|
58
|
+
: quoteIdentifier(name);
|
|
59
|
+
const schemaExpr = table.schema !== null ? literal(table.schema) : 'DATABASE()';
|
|
60
|
+
const columns = opts.columns ?? [];
|
|
61
|
+
const sampling = opts.sampling ?? null;
|
|
62
|
+
const maxScanRows = opts.maxScanRows ?? STATS_MAX_SCAN_ROWS;
|
|
63
|
+
const warnings = [];
|
|
64
|
+
// 1. Row-count estimate from information_schema, exact COUNT for small tables.
|
|
65
|
+
const infoRows = await exec(`SELECT TABLE_ROWS AS table_rows
|
|
66
|
+
FROM information_schema.TABLES
|
|
67
|
+
WHERE TABLE_SCHEMA = ${schemaExpr} AND TABLE_NAME = ${literal(name)}
|
|
68
|
+
LIMIT 1`);
|
|
69
|
+
const tableRows = num(infoRows[0]?.['table_rows']);
|
|
70
|
+
let rowCountEstimate;
|
|
71
|
+
let rowCountExact;
|
|
72
|
+
if (tableRows !== null && tableRows >= STATS_EXACT_COUNT_THRESHOLD) {
|
|
73
|
+
rowCountEstimate = Math.round(tableRows);
|
|
74
|
+
rowCountExact = false;
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
const countRows = await exec(`SELECT count(*) AS n FROM ${qualified}`);
|
|
78
|
+
rowCountEstimate = num(countRows[0]?.['n']);
|
|
79
|
+
rowCountExact = rowCountEstimate !== null;
|
|
80
|
+
}
|
|
81
|
+
// 2. Per-column null-fraction + distinct-count via one bounded full-scan.
|
|
82
|
+
const colStats = columns.map((c) => ({
|
|
83
|
+
column: c.name,
|
|
84
|
+
nullFraction: null,
|
|
85
|
+
distinctCount: null,
|
|
86
|
+
}));
|
|
87
|
+
if (columns.length > 0) {
|
|
88
|
+
const scannable = rowCountEstimate !== null && rowCountEstimate <= maxScanRows;
|
|
89
|
+
if (scannable) {
|
|
90
|
+
const scanRows = await exec(buildNullDistinctScan(qualified, columns.map((c) => c.name)));
|
|
91
|
+
const row = scanRows[0] ?? {};
|
|
92
|
+
const total = num(row['row_total']);
|
|
93
|
+
columns.forEach((_c, k) => {
|
|
94
|
+
const nulls = num(row[`nf_${k}`]);
|
|
95
|
+
colStats[k].nullFraction =
|
|
96
|
+
total === null || total === 0 ? (total === 0 ? 0 : null) : nulls === null ? null : nulls / total;
|
|
97
|
+
colStats[k].distinctCount = num(row[`dc_${k}`]);
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
warnings.push(`null-fraction/distinct-count skipped for ${columns.length} column(s): table exceeds maxScanRows`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// 3. Sampling opt-in — most-common values + ordered min/max; never PII/secret.
|
|
105
|
+
let sampled = false;
|
|
106
|
+
if (sampling !== null) {
|
|
107
|
+
const maxValues = sampling.maxValuesPerColumn > 0
|
|
108
|
+
? Math.floor(sampling.maxValuesPerColumn)
|
|
109
|
+
: STATS_DEFAULT_SAMPLE_VALUES;
|
|
110
|
+
for (let i = 0; i < columns.length; i += 1) {
|
|
111
|
+
const c = columns[i];
|
|
112
|
+
if (c.piiSuspected === true || c.secret === true)
|
|
113
|
+
continue; // NEVER sample PII/secret.
|
|
114
|
+
const q = quoteIdentifier(c.name);
|
|
115
|
+
if (ORDERED_TYPES.has(c.logicalType)) {
|
|
116
|
+
const mm = await exec(`SELECT min(${q}) AS lo, max(${q}) AS hi FROM ${qualified}`);
|
|
117
|
+
colStats[i].min = toScalar(mm[0]?.['lo']);
|
|
118
|
+
colStats[i].max = toScalar(mm[0]?.['hi']);
|
|
119
|
+
sampled = true;
|
|
120
|
+
}
|
|
121
|
+
const mcv = await exec(`SELECT ${q} AS v, count(*) AS c
|
|
122
|
+
FROM ${qualified}
|
|
123
|
+
WHERE ${q} IS NOT NULL
|
|
124
|
+
GROUP BY ${q}
|
|
125
|
+
ORDER BY count(*) DESC, ${q}
|
|
126
|
+
LIMIT ${maxValues}`);
|
|
127
|
+
colStats[i].sampleValues = mcv.map((r) => truncate(toScalar(r['v'])));
|
|
128
|
+
sampled = true;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
const result = {
|
|
132
|
+
table: { schema: table.schema, name },
|
|
133
|
+
rowCountEstimate,
|
|
134
|
+
rowCountExact,
|
|
135
|
+
columns: colStats,
|
|
136
|
+
sampled,
|
|
137
|
+
};
|
|
138
|
+
if (warnings.length > 0)
|
|
139
|
+
result.warnings = warnings;
|
|
140
|
+
return result;
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=stats.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stats.js","sourceRoot":"","sources":["../src/stats.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MySQL/MariaDB COLUMN_TYPE → portable LogicalType mapping —
|
|
3
|
+
* 05-introspection-engine.md §2.2 ("canonical table — extend, never fork"),
|
|
4
|
+
* MySQL/MariaDB column, plus the §4.2 type notes.
|
|
5
|
+
*
|
|
6
|
+
* Input is the verbatim `information_schema.COLUMNS.COLUMN_TYPE` string
|
|
7
|
+
* (e.g. `varchar(120)`, `int unsigned`, `tinyint(1)`, `enum('a','b')`) so the
|
|
8
|
+
* mapping is pure and unit-testable offline — no driver, no server.
|
|
9
|
+
*
|
|
10
|
+
* DOCUMENTED POLICY (05 §4.2): `tinyint(1)` maps to `boolean` (the mysql2 /
|
|
11
|
+
* classic connector convention — MySQL has no native boolean and `BOOLEAN`
|
|
12
|
+
* DDL compiles to `tinyint(1)`). Any other tinyint width is an integer.
|
|
13
|
+
* `set(...)` degrades to `text` (the assembler emits a warning). `year` maps
|
|
14
|
+
* to `integer` with a warning. `datetime` (no zone) → `timestamp`;
|
|
15
|
+
* `timestamp` (UTC-normalized by the server) → `timestamptz`.
|
|
16
|
+
*/
|
|
17
|
+
import type { ColumnDefault, LogicalType } from '@adminium/engine/adapter';
|
|
18
|
+
export interface MappedMysqlType {
|
|
19
|
+
logicalType: LogicalType;
|
|
20
|
+
maxLength: number | null;
|
|
21
|
+
numericPrecision: number | null;
|
|
22
|
+
numericScale: number | null;
|
|
23
|
+
/** `unsigned` modifier present on a numeric type. */
|
|
24
|
+
unsigned: boolean;
|
|
25
|
+
/** Non-fatal mapping caveat the assembler turns into a ModelWarning. */
|
|
26
|
+
warning: 'unsigned-overflow' | 'year-as-integer' | 'set-as-text' | null;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Parse the quoted value list of `enum('a','b')` / `set('a','b')`. MySQL
|
|
30
|
+
* escapes embedded quotes by doubling (`''`) and the odd dump uses `\'` —
|
|
31
|
+
* both are unescaped. Returns null when `columnType` is not an enum/set.
|
|
32
|
+
*/
|
|
33
|
+
export declare function parseEnumValues(columnType: string): string[] | null;
|
|
34
|
+
/**
|
|
35
|
+
* Map a verbatim MySQL/MariaDB COLUMN_TYPE to its portable shape.
|
|
36
|
+
* Unmappable types become `'unknown'` with the verbatim `dbType` preserved
|
|
37
|
+
* by the caller (rendered read-only as text — 05 §2.2).
|
|
38
|
+
*/
|
|
39
|
+
export declare function mapMysqlType(columnType: string): MappedMysqlType;
|
|
40
|
+
/**
|
|
41
|
+
* Classify a column default — 05 §4.2: `EXTRA` carries `auto_increment`,
|
|
42
|
+
* generated-column markers, and MySQL 8 `DEFAULT_GENERATED` expression
|
|
43
|
+
* defaults; `COLUMN_DEFAULT` carries the value text (MariaDB quotes string
|
|
44
|
+
* literals, MySQL 8 does not — both spellings are accepted).
|
|
45
|
+
*
|
|
46
|
+
* @param defaultValue `information_schema.COLUMNS.COLUMN_DEFAULT` (nullable).
|
|
47
|
+
* @param extra `information_schema.COLUMNS.EXTRA` (may be '').
|
|
48
|
+
*/
|
|
49
|
+
export declare function classifyMysqlDefault(defaultValue: string | null, extra: string): ColumnDefault;
|
|
50
|
+
//# sourceMappingURL=type-map.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"type-map.d.ts","sourceRoot":"","sources":["../src/type-map.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE3E,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,WAAW,CAAC;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,qDAAqD;IACrD,QAAQ,EAAE,OAAO,CAAC;IAClB,wEAAwE;IACxE,OAAO,EAAE,mBAAmB,GAAG,iBAAiB,GAAG,aAAa,GAAG,IAAI,CAAC;CACzE;AAmFD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAQnE;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,eAAe,CAiEhE;AAMD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,aAAa,CAa9F"}
|
package/dist/type-map.js
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/** Base type name (modifiers and attributes stripped) → LogicalType. */
|
|
2
|
+
const BASE_TYPE_MAP = {
|
|
3
|
+
// integers (tinyint(1) special-cased in mapMysqlType)
|
|
4
|
+
tinyint: 'integer',
|
|
5
|
+
smallint: 'integer',
|
|
6
|
+
mediumint: 'integer',
|
|
7
|
+
int: 'integer',
|
|
8
|
+
integer: 'integer',
|
|
9
|
+
bigint: 'bigint',
|
|
10
|
+
// exact + approximate numerics
|
|
11
|
+
decimal: 'decimal',
|
|
12
|
+
numeric: 'decimal',
|
|
13
|
+
dec: 'decimal',
|
|
14
|
+
fixed: 'decimal',
|
|
15
|
+
float: 'float',
|
|
16
|
+
double: 'float',
|
|
17
|
+
'double precision': 'float',
|
|
18
|
+
real: 'float',
|
|
19
|
+
// text family
|
|
20
|
+
char: 'varchar',
|
|
21
|
+
varchar: 'varchar',
|
|
22
|
+
tinytext: 'text',
|
|
23
|
+
text: 'text',
|
|
24
|
+
mediumtext: 'text',
|
|
25
|
+
longtext: 'text',
|
|
26
|
+
// binary family
|
|
27
|
+
binary: 'binary',
|
|
28
|
+
varbinary: 'binary',
|
|
29
|
+
tinyblob: 'binary',
|
|
30
|
+
blob: 'binary',
|
|
31
|
+
mediumblob: 'binary',
|
|
32
|
+
longblob: 'binary',
|
|
33
|
+
// date/time
|
|
34
|
+
date: 'date',
|
|
35
|
+
time: 'time',
|
|
36
|
+
datetime: 'timestamp',
|
|
37
|
+
timestamp: 'timestamptz',
|
|
38
|
+
year: 'integer',
|
|
39
|
+
// structured / misc
|
|
40
|
+
json: 'json',
|
|
41
|
+
// MariaDB ≥ 10.7 native types
|
|
42
|
+
uuid: 'uuid',
|
|
43
|
+
inet4: 'inet',
|
|
44
|
+
inet6: 'inet',
|
|
45
|
+
// spatial (flag; rendered read-only as text in v1 — 05 §2.2)
|
|
46
|
+
geometry: 'geometry',
|
|
47
|
+
point: 'geometry',
|
|
48
|
+
linestring: 'geometry',
|
|
49
|
+
polygon: 'geometry',
|
|
50
|
+
multipoint: 'geometry',
|
|
51
|
+
multilinestring: 'geometry',
|
|
52
|
+
multipolygon: 'geometry',
|
|
53
|
+
geometrycollection: 'geometry',
|
|
54
|
+
geomcollection: 'geometry',
|
|
55
|
+
};
|
|
56
|
+
/** Binary-float precision constants (same convention as the pg adapter). */
|
|
57
|
+
const FLOAT_PRECISION = 24;
|
|
58
|
+
const DOUBLE_PRECISION = 53;
|
|
59
|
+
/** Strip `(…)` modifiers and trailing attributes (`unsigned`, `zerofill`). */
|
|
60
|
+
function baseTypeName(columnType) {
|
|
61
|
+
return columnType
|
|
62
|
+
.trim()
|
|
63
|
+
.toLowerCase()
|
|
64
|
+
.replace(/\([^)]*\)/, '')
|
|
65
|
+
.replace(/\b(unsigned|zerofill|signed)\b/g, '')
|
|
66
|
+
.replace(/\s+/g, ' ')
|
|
67
|
+
.trim();
|
|
68
|
+
}
|
|
69
|
+
/** Extract `(n)` / `(p,s)` modifier numbers, when present. */
|
|
70
|
+
function modifiers(columnType) {
|
|
71
|
+
const match = /\(([\d\s,]+)\)/.exec(columnType);
|
|
72
|
+
if (match?.[1] === undefined)
|
|
73
|
+
return [];
|
|
74
|
+
return match[1]
|
|
75
|
+
.split(',')
|
|
76
|
+
.map((part) => Number.parseInt(part.trim(), 10))
|
|
77
|
+
.filter((n) => Number.isFinite(n));
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Parse the quoted value list of `enum('a','b')` / `set('a','b')`. MySQL
|
|
81
|
+
* escapes embedded quotes by doubling (`''`) and the odd dump uses `\'` —
|
|
82
|
+
* both are unescaped. Returns null when `columnType` is not an enum/set.
|
|
83
|
+
*/
|
|
84
|
+
export function parseEnumValues(columnType) {
|
|
85
|
+
const match = /^\s*(enum|set)\s*\((.*)\)\s*$/is.exec(columnType);
|
|
86
|
+
if (match?.[2] === undefined)
|
|
87
|
+
return null;
|
|
88
|
+
const values = [];
|
|
89
|
+
for (const literal of match[2].matchAll(/'((?:[^'\\]|\\.|'')*)'/g)) {
|
|
90
|
+
values.push((literal[1] ?? '').replaceAll("''", "'").replaceAll("\\'", "'"));
|
|
91
|
+
}
|
|
92
|
+
return values;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Map a verbatim MySQL/MariaDB COLUMN_TYPE to its portable shape.
|
|
96
|
+
* Unmappable types become `'unknown'` with the verbatim `dbType` preserved
|
|
97
|
+
* by the caller (rendered read-only as text — 05 §2.2).
|
|
98
|
+
*/
|
|
99
|
+
export function mapMysqlType(columnType) {
|
|
100
|
+
const lowered = columnType.trim().toLowerCase();
|
|
101
|
+
const unsigned = /\bunsigned\b/.test(lowered);
|
|
102
|
+
// enum(...) / set(...) carry their value list inside the parens — handle
|
|
103
|
+
// before modifier stripping. set(...) degrades to text (05 §4.2).
|
|
104
|
+
if (lowered.startsWith('enum(') || lowered.startsWith('enum (')) {
|
|
105
|
+
return {
|
|
106
|
+
logicalType: 'enum',
|
|
107
|
+
maxLength: null,
|
|
108
|
+
numericPrecision: null,
|
|
109
|
+
numericScale: null,
|
|
110
|
+
unsigned: false,
|
|
111
|
+
warning: null,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
if (lowered.startsWith('set(') || lowered.startsWith('set (')) {
|
|
115
|
+
return {
|
|
116
|
+
logicalType: 'text',
|
|
117
|
+
maxLength: null,
|
|
118
|
+
numericPrecision: null,
|
|
119
|
+
numericScale: null,
|
|
120
|
+
unsigned: false,
|
|
121
|
+
warning: 'set-as-text',
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
const base = baseTypeName(lowered);
|
|
125
|
+
const mods = modifiers(lowered);
|
|
126
|
+
// tinyint(1) → boolean (documented policy above); bit(1) reads as boolean too.
|
|
127
|
+
if ((base === 'tinyint' && mods[0] === 1) || (base === 'bit' && (mods[0] ?? 1) === 1)) {
|
|
128
|
+
return {
|
|
129
|
+
logicalType: 'boolean',
|
|
130
|
+
maxLength: null,
|
|
131
|
+
numericPrecision: null,
|
|
132
|
+
numericScale: null,
|
|
133
|
+
unsigned,
|
|
134
|
+
warning: null,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
const logicalType = BASE_TYPE_MAP[base] ?? 'unknown';
|
|
138
|
+
let maxLength = null;
|
|
139
|
+
let numericPrecision = null;
|
|
140
|
+
let numericScale = null;
|
|
141
|
+
let warning = null;
|
|
142
|
+
if (logicalType === 'varchar' || logicalType === 'text' || logicalType === 'binary') {
|
|
143
|
+
maxLength = mods[0] ?? null;
|
|
144
|
+
}
|
|
145
|
+
else if (logicalType === 'decimal') {
|
|
146
|
+
numericPrecision = mods[0] ?? null;
|
|
147
|
+
numericScale = mods[1] ?? null;
|
|
148
|
+
}
|
|
149
|
+
else if (logicalType === 'float') {
|
|
150
|
+
numericPrecision = base === 'float' ? FLOAT_PRECISION : DOUBLE_PRECISION;
|
|
151
|
+
}
|
|
152
|
+
if (base === 'year')
|
|
153
|
+
warning = 'year-as-integer';
|
|
154
|
+
// `int unsigned` (and up) exceeds int4 range — flagged per 05 §4.2.
|
|
155
|
+
else if (unsigned && (base === 'int' || base === 'integer' || base === 'bigint')) {
|
|
156
|
+
warning = 'unsigned-overflow';
|
|
157
|
+
}
|
|
158
|
+
return { logicalType, maxLength, numericPrecision, numericScale, unsigned, warning };
|
|
159
|
+
}
|
|
160
|
+
const NOW_DEFAULT = /^(current_timestamp(\(\d*\))?|now\(\d*\))$/i;
|
|
161
|
+
const UUID_DEFAULT = /^uuid\(\)$/i;
|
|
162
|
+
const LITERAL_DEFAULT = /^('(?:[^']|'')*'|-?\d+(\.\d+)?|true|false|b'[01]+')$/i;
|
|
163
|
+
/**
|
|
164
|
+
* Classify a column default — 05 §4.2: `EXTRA` carries `auto_increment`,
|
|
165
|
+
* generated-column markers, and MySQL 8 `DEFAULT_GENERATED` expression
|
|
166
|
+
* defaults; `COLUMN_DEFAULT` carries the value text (MariaDB quotes string
|
|
167
|
+
* literals, MySQL 8 does not — both spellings are accepted).
|
|
168
|
+
*
|
|
169
|
+
* @param defaultValue `information_schema.COLUMNS.COLUMN_DEFAULT` (nullable).
|
|
170
|
+
* @param extra `information_schema.COLUMNS.EXTRA` (may be '').
|
|
171
|
+
*/
|
|
172
|
+
export function classifyMysqlDefault(defaultValue, extra) {
|
|
173
|
+
const extraLowered = extra.toLowerCase();
|
|
174
|
+
if (extraLowered.includes('auto_increment'))
|
|
175
|
+
return { kind: 'autoincrement' };
|
|
176
|
+
if (defaultValue === null || /^null$/i.test(defaultValue))
|
|
177
|
+
return null;
|
|
178
|
+
const text = defaultValue.trim();
|
|
179
|
+
if (NOW_DEFAULT.test(text))
|
|
180
|
+
return { kind: 'now' };
|
|
181
|
+
if (UUID_DEFAULT.test(text))
|
|
182
|
+
return { kind: 'uuid' };
|
|
183
|
+
// MySQL 8 marks expression defaults with DEFAULT_GENERATED in EXTRA.
|
|
184
|
+
if (extraLowered.includes('default_generated'))
|
|
185
|
+
return { kind: 'expression', text };
|
|
186
|
+
if (LITERAL_DEFAULT.test(text))
|
|
187
|
+
return { kind: 'literal', text };
|
|
188
|
+
// MySQL 8 strips quotes from string literals — a bare word is a literal.
|
|
189
|
+
if (/^[^()]*$/.test(text))
|
|
190
|
+
return { kind: 'literal', text };
|
|
191
|
+
return { kind: 'expression', text };
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=type-map.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"type-map.js","sourceRoot":"","sources":["../src/type-map.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@adminiumjs/adapter-mysql",
|
|
3
|
+
"version": "0.1.0-rc.1",
|
|
4
|
+
"license": "AGPL-3.0-only",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/MoSofi/Adminium.git",
|
|
8
|
+
"directory": "packages/adapter-mysql"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://adminium.dev",
|
|
11
|
+
"bugs": "https://github.com/MoSofi/Adminium/issues",
|
|
12
|
+
"type": "module",
|
|
13
|
+
"description": "MySQL/MariaDB adapter",
|
|
14
|
+
"main": "./dist/index.js",
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"default": "./dist/index.js"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@adminium/engine": "npm:@adminiumjs/engine@0.1.0-rc.1",
|
|
24
|
+
"kysely": "^0.28.2",
|
|
25
|
+
"mysql2": "^3.15.3"
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"dist"
|
|
29
|
+
]
|
|
30
|
+
}
|