@primate/mysql 0.5.0 → 0.7.0
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/lib/private/ColumnTypes.d.ts +2 -0
- package/lib/private/MySQL.d.ts +27 -13
- package/lib/private/MySQL.js +146 -31
- package/lib/private/typemap.js +36 -10
- package/package.json +15 -11
package/lib/private/MySQL.d.ts
CHANGED
|
@@ -1,28 +1,35 @@
|
|
|
1
|
-
import type { As, DataDict,
|
|
1
|
+
import type { As, DataDict, ExtractPlaceholders, Schema, Sort, SQLDB, With, CheckPlaceholders } from "@primate/core/db";
|
|
2
2
|
import type { Dict } from "@rcompat/type";
|
|
3
|
-
import type {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
host: import("pema").DefaultType<import("pema").StringType, "localhost">;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
import type { Pool } from "mysql2/promise";
|
|
4
|
+
import type { ObjectType, Parsed } from "pema";
|
|
5
|
+
declare const schema: ObjectType<import("pema").NormalizeSchemaObject<{
|
|
6
|
+
readonly host: import("pema").DefaultType<import("pema").StringType, "localhost">;
|
|
7
|
+
readonly port: import("pema").DefaultType<import("pema").UintType<"u32">, 3306>;
|
|
8
|
+
readonly database: import("pema").StringType;
|
|
9
|
+
readonly password: import("pema").OptionalType<import("pema").StringType>;
|
|
10
|
+
readonly username: import("pema").OptionalType<import("pema").StringType>;
|
|
11
|
+
readonly jsonStrings: import("pema").DefaultType<import("pema").BooleanType, true>;
|
|
12
|
+
}>, {
|
|
13
|
+
host: string;
|
|
14
|
+
port: number;
|
|
15
|
+
database: string;
|
|
16
|
+
password: string | undefined;
|
|
17
|
+
username: string | undefined;
|
|
18
|
+
jsonStrings: boolean;
|
|
10
19
|
}>;
|
|
11
|
-
export default class MySQL implements
|
|
20
|
+
export default class MySQL implements SQLDB<Pool> {
|
|
12
21
|
#private;
|
|
13
22
|
static config: typeof schema.input;
|
|
14
23
|
constructor(config?: typeof schema.input, options?: {
|
|
15
24
|
debug?: boolean;
|
|
16
25
|
});
|
|
26
|
+
get client(): Pool;
|
|
17
27
|
get explain(): Dict<{
|
|
18
28
|
query: string;
|
|
19
29
|
plans: string[];
|
|
20
30
|
}>;
|
|
21
31
|
close(): Promise<void>;
|
|
22
|
-
get schema():
|
|
23
|
-
create: (as: As, store: StoreSchema) => Promise<void>;
|
|
24
|
-
delete: (table: string) => Promise<void>;
|
|
25
|
-
};
|
|
32
|
+
get schema(): Schema;
|
|
26
33
|
create<O extends Dict>(as: As, record: Dict): Promise<O>;
|
|
27
34
|
read(as: As, args: {
|
|
28
35
|
count: true;
|
|
@@ -43,6 +50,13 @@ export default class MySQL implements DB {
|
|
|
43
50
|
delete(as: As, args: {
|
|
44
51
|
where: DataDict;
|
|
45
52
|
}): Promise<number>;
|
|
53
|
+
sql<Q extends string, I extends ObjectType<{
|
|
54
|
+
[K in ExtractPlaceholders<Q>]: Parsed<unknown>;
|
|
55
|
+
}> | undefined, O extends Parsed<unknown> | undefined>(options: {
|
|
56
|
+
input?: I extends ObjectType<any> ? CheckPlaceholders<I, Q> : I;
|
|
57
|
+
query: Q;
|
|
58
|
+
output?: O;
|
|
59
|
+
}): (args: I extends ObjectType<any> ? I["infer"] : void) => Promise<O extends Parsed<unknown> ? O["infer"] : void>;
|
|
46
60
|
}
|
|
47
61
|
export {};
|
|
48
62
|
//# sourceMappingURL=MySQL.d.ts.map
|
package/lib/private/MySQL.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import typemap from "#typemap";
|
|
2
|
-
import
|
|
3
|
-
import E from "@primate/core/db/
|
|
2
|
+
import base from "@primate/core/db";
|
|
3
|
+
import E from "@primate/core/db/errors";
|
|
4
4
|
import sql from "@primate/core/db/sql";
|
|
5
5
|
import assert from "@rcompat/assert";
|
|
6
6
|
import is from "@rcompat/is";
|
|
@@ -15,14 +15,14 @@ function is_bigint_key(k) {
|
|
|
15
15
|
return k === "u64" || k === "u128" || k === "i64" || k === "i128";
|
|
16
16
|
}
|
|
17
17
|
function order_by(types, sort, alias) {
|
|
18
|
-
if (sort
|
|
18
|
+
if (is.undefined(sort))
|
|
19
19
|
return "";
|
|
20
20
|
const entries = Object.entries(sort);
|
|
21
21
|
if (entries.length === 0)
|
|
22
22
|
return "";
|
|
23
23
|
const parts = entries.map(([k, dir]) => {
|
|
24
24
|
const quoted = sql.quote(k);
|
|
25
|
-
const base = alias ? `${alias}.${quoted}` : quoted;
|
|
25
|
+
const base = is.defined(alias) ? `${alias}.${quoted}` : quoted;
|
|
26
26
|
const expression = is_bigint_key(types[k]) ? bigint_cast(base) : base;
|
|
27
27
|
return `${expression} ${dir.toLowerCase() === "desc" ? "DESC" : "ASC"}`;
|
|
28
28
|
});
|
|
@@ -42,12 +42,43 @@ function unbind_value(key, value) {
|
|
|
42
42
|
function unbind(types, row) {
|
|
43
43
|
return sql.unbind(types, row, unbind_value);
|
|
44
44
|
}
|
|
45
|
+
function columns_to_types(data_t, column_t) {
|
|
46
|
+
const unsigned = column_t.includes("unsigned");
|
|
47
|
+
if (data_t === "varchar")
|
|
48
|
+
return ["string", "url"];
|
|
49
|
+
if (data_t === "text")
|
|
50
|
+
return ["string", "url", "time"];
|
|
51
|
+
if (data_t === "binary" && column_t.includes("(16)"))
|
|
52
|
+
return base.UUID_TYPES;
|
|
53
|
+
if (data_t === "smallint")
|
|
54
|
+
return unsigned ? ["u16"] : ["i16"];
|
|
55
|
+
if (data_t === "int")
|
|
56
|
+
return unsigned ? ["u32"] : ["i32"];
|
|
57
|
+
if (data_t === "bigint")
|
|
58
|
+
return unsigned ? ["u64"] : ["i64"];
|
|
59
|
+
if (data_t === "decimal")
|
|
60
|
+
return ["u128", "i128"];
|
|
61
|
+
if (data_t === "double")
|
|
62
|
+
return ["f32", "f64"];
|
|
63
|
+
if (data_t === "datetime")
|
|
64
|
+
return ["datetime"];
|
|
65
|
+
if (data_t === "tinyint" && column_t === "tinyint(1)")
|
|
66
|
+
return ["boolean"];
|
|
67
|
+
if (data_t === "tinyint")
|
|
68
|
+
return unsigned ? ["u8"] : ["i8", "boolean"];
|
|
69
|
+
if (data_t === "blob")
|
|
70
|
+
return ["blob"];
|
|
71
|
+
if (data_t === "json")
|
|
72
|
+
return ["json"];
|
|
73
|
+
return [];
|
|
74
|
+
}
|
|
45
75
|
const schema = p({
|
|
46
|
-
database: p.string,
|
|
47
76
|
host: p.string.default("localhost"),
|
|
48
|
-
password: p.string.optional(),
|
|
49
77
|
port: p.uint.port().default(3306),
|
|
78
|
+
database: p.string,
|
|
79
|
+
password: p.string.optional(),
|
|
50
80
|
username: p.string.optional(),
|
|
81
|
+
jsonStrings: p.boolean.default(true),
|
|
51
82
|
});
|
|
52
83
|
export default class MySQL {
|
|
53
84
|
static config;
|
|
@@ -66,12 +97,16 @@ export default class MySQL {
|
|
|
66
97
|
namedPlaceholders: true,
|
|
67
98
|
bigNumberStrings: true,
|
|
68
99
|
supportBigNumbers: true,
|
|
100
|
+
jsonStrings: parsed.jsonStrings,
|
|
69
101
|
});
|
|
70
102
|
this.#debug = options?.debug ?? false;
|
|
71
103
|
}
|
|
72
104
|
get #db() {
|
|
73
105
|
return this.#client ??= this.#factory();
|
|
74
106
|
}
|
|
107
|
+
get client() {
|
|
108
|
+
return this.#db;
|
|
109
|
+
}
|
|
75
110
|
async #sql(query, params) {
|
|
76
111
|
const [rows] = await this.#db.query(query, params);
|
|
77
112
|
return rows;
|
|
@@ -94,26 +129,63 @@ export default class MySQL {
|
|
|
94
129
|
}
|
|
95
130
|
get schema() {
|
|
96
131
|
return {
|
|
97
|
-
create: async (
|
|
132
|
+
create: async (table, pk, types) => {
|
|
98
133
|
const columns = [];
|
|
99
|
-
for (const [key, value] of Object.entries(
|
|
100
|
-
const type = get_column(value
|
|
101
|
-
if (key ===
|
|
102
|
-
const is_int =
|
|
103
|
-
const auto =
|
|
134
|
+
for (const [key, value] of Object.entries(types)) {
|
|
135
|
+
const type = get_column(value);
|
|
136
|
+
if (key === pk.name) {
|
|
137
|
+
const is_int = base.INT_TYPES.includes(value);
|
|
138
|
+
const auto = pk.generate && is_int ? " AUTO_INCREMENT" : "";
|
|
104
139
|
// 36 is UUID length
|
|
105
|
-
const pk_type = value
|
|
140
|
+
const pk_type = value === "string" ? "VARCHAR(36)" : type;
|
|
106
141
|
columns.push(`${sql.quote(key)} ${pk_type} PRIMARY KEY${auto}`);
|
|
107
142
|
}
|
|
108
143
|
else {
|
|
109
144
|
columns.push(`${sql.quote(key)} ${type}`);
|
|
110
145
|
}
|
|
111
146
|
}
|
|
112
|
-
await this.#sql(Q `CREATE TABLE IF NOT EXISTS ${
|
|
147
|
+
await this.#sql(Q `CREATE TABLE IF NOT EXISTS ${table} (${columns})`);
|
|
113
148
|
},
|
|
114
149
|
delete: async (table) => {
|
|
115
150
|
await this.#sql(Q `DROP TABLE IF EXISTS ${table}`);
|
|
116
151
|
},
|
|
152
|
+
introspect: async (table) => {
|
|
153
|
+
const rows = await this.#sql(`
|
|
154
|
+
SELECT COLUMN_NAME, DATA_TYPE, COLUMN_TYPE
|
|
155
|
+
FROM information_schema.COLUMNS
|
|
156
|
+
WHERE TABLE_SCHEMA = DATABASE()
|
|
157
|
+
AND TABLE_NAME = :name
|
|
158
|
+
`, { name: table });
|
|
159
|
+
if (rows.length === 0)
|
|
160
|
+
return null;
|
|
161
|
+
const result = {};
|
|
162
|
+
for (const row of rows) {
|
|
163
|
+
const candidates = columns_to_types(row.DATA_TYPE, row.COLUMN_TYPE);
|
|
164
|
+
if (candidates.length > 0)
|
|
165
|
+
result[row.COLUMN_NAME] = candidates;
|
|
166
|
+
}
|
|
167
|
+
return result;
|
|
168
|
+
},
|
|
169
|
+
alter: async (table, diff) => {
|
|
170
|
+
const existing = await this.schema.introspect(table);
|
|
171
|
+
if (existing === null)
|
|
172
|
+
throw E.table_not_found(table);
|
|
173
|
+
for (const [from, to] of diff.rename) {
|
|
174
|
+
await this.#sql(Q `
|
|
175
|
+
ALTER TABLE ${table}
|
|
176
|
+
RENAME COLUMN ${[sql.quote(from)]} TO ${[sql.quote(to)]}`);
|
|
177
|
+
}
|
|
178
|
+
const parts = [];
|
|
179
|
+
for (const field of diff.drop) {
|
|
180
|
+
parts.push(`DROP COLUMN ${sql.quote(field)}`);
|
|
181
|
+
}
|
|
182
|
+
for (const [field, type] of Object.entries(diff.add)) {
|
|
183
|
+
parts.push(`ADD COLUMN ${sql.quote(field)} ${get_column(type)}`);
|
|
184
|
+
}
|
|
185
|
+
if (parts.length > 0) {
|
|
186
|
+
await this.#sql(Q `ALTER TABLE ${table} ${[parts.join(", ")]}`);
|
|
187
|
+
}
|
|
188
|
+
},
|
|
117
189
|
};
|
|
118
190
|
}
|
|
119
191
|
async #where(as, where) {
|
|
@@ -141,7 +213,9 @@ export default class MySQL {
|
|
|
141
213
|
const numeric = is_bigint_key(datatype);
|
|
142
214
|
const lhs = numeric ? bigint_cast(quoted) : quoted;
|
|
143
215
|
const rhs = numeric ? bigint_cast(ph) : ph;
|
|
144
|
-
|
|
216
|
+
if (op !== "$in") {
|
|
217
|
+
binds[bind_key] = await bind_value(datatype, op_value);
|
|
218
|
+
}
|
|
145
219
|
switch (op) {
|
|
146
220
|
case "$like":
|
|
147
221
|
parts.push(`${quoted} LIKE BINARY ${ph}`);
|
|
@@ -162,6 +236,19 @@ export default class MySQL {
|
|
|
162
236
|
parts.push(`${lhs} ${sql_op} ${rhs}`);
|
|
163
237
|
break;
|
|
164
238
|
}
|
|
239
|
+
case "$in": {
|
|
240
|
+
const array = op_value;
|
|
241
|
+
const placeholders = [];
|
|
242
|
+
for (let i = 0; i < array.length; i++) {
|
|
243
|
+
const key = `${sql.bindKey(field, `in${i}`)}`;
|
|
244
|
+
binds[key] = await bind_value(datatype, array[i]);
|
|
245
|
+
const ph = `${BIND_BY}${key}`;
|
|
246
|
+
placeholders.push(is_bigint_key(datatype) ? bigint_cast(ph) : ph);
|
|
247
|
+
}
|
|
248
|
+
const lhs = is_bigint_key(datatype) ? bigint_cast(quoted) : quoted;
|
|
249
|
+
parts.push(`${lhs} IN (${placeholders.join(", ")})`);
|
|
250
|
+
break;
|
|
251
|
+
}
|
|
165
252
|
default:
|
|
166
253
|
throw E.operator_unknown(field, op);
|
|
167
254
|
}
|
|
@@ -193,9 +280,9 @@ export default class MySQL {
|
|
|
193
280
|
const pk = as.pk;
|
|
194
281
|
const type = as.types[pk];
|
|
195
282
|
const table = as.table;
|
|
196
|
-
if (type
|
|
197
|
-
return
|
|
198
|
-
if (
|
|
283
|
+
if (base.is_uuid_type(type))
|
|
284
|
+
return base.generate_uuid(type);
|
|
285
|
+
if (base.BIGINT_STRING_TYPES.includes(type)) {
|
|
199
286
|
const cast = bigint_cast(sql.quote(pk));
|
|
200
287
|
const q = `SELECT MAX(${cast}) AS v FROM ${sql.quote(table)}`;
|
|
201
288
|
const rows = await this.#sql(q);
|
|
@@ -235,7 +322,7 @@ export default class MySQL {
|
|
|
235
322
|
throw E.pk_required(pk);
|
|
236
323
|
const type = as.types[pk];
|
|
237
324
|
// integer types, use AUTO_INCREMENT
|
|
238
|
-
if (!
|
|
325
|
+
if (!base.BIGINT_STRING_TYPES.includes(type) && !base.is_uuid_type(type)) {
|
|
239
326
|
const [keys, values] = this.#create(record);
|
|
240
327
|
const query = keys.length > 0
|
|
241
328
|
? Q `INSERT INTO ${table} (${keys}) VALUES (${values})`
|
|
@@ -257,7 +344,7 @@ export default class MySQL {
|
|
|
257
344
|
this.#explain = {};
|
|
258
345
|
if (args.count === true)
|
|
259
346
|
return this.#count(as, args.where);
|
|
260
|
-
if (
|
|
347
|
+
if (base.withed(args)) {
|
|
261
348
|
return sql.joinable(as, args.with)
|
|
262
349
|
? this.#read_joined(as, args)
|
|
263
350
|
: this.#read_phased(as, args);
|
|
@@ -273,15 +360,16 @@ export default class MySQL {
|
|
|
273
360
|
return Number(rows[0]?.n ?? 0);
|
|
274
361
|
}
|
|
275
362
|
async #base_query(as, args) {
|
|
276
|
-
const SELECT = args.fields
|
|
363
|
+
const SELECT = is.undefined(args.fields)
|
|
277
364
|
? "*"
|
|
278
365
|
: args.fields.map(sql.quote).join(", ");
|
|
279
366
|
const [WHERE, binds] = await this.#where(as, args.where);
|
|
280
367
|
const ORDER_BY = order_by(as.types, args.sort);
|
|
281
|
-
const LIMIT =
|
|
368
|
+
const LIMIT = is.defined(args.limit) ? ` LIMIT ${args.limit}` : "";
|
|
369
|
+
const OFFSET = is.defined(args.offset) ? ` OFFSET ${args.offset}` : "";
|
|
282
370
|
const table = sql.quote(as.table);
|
|
283
371
|
return [
|
|
284
|
-
`SELECT ${SELECT} FROM ${table} ${WHERE}${ORDER_BY}${LIMIT}`,
|
|
372
|
+
`SELECT ${SELECT} FROM ${table} ${WHERE}${ORDER_BY}${LIMIT}${OFFSET}`,
|
|
285
373
|
binds,
|
|
286
374
|
];
|
|
287
375
|
}
|
|
@@ -292,9 +380,9 @@ export default class MySQL {
|
|
|
292
380
|
return rows.map(r => unbind(as.types, r));
|
|
293
381
|
}
|
|
294
382
|
async #read_phased(as, args) {
|
|
295
|
-
const fields =
|
|
383
|
+
const fields = base.expand(as, args.fields, args.with);
|
|
296
384
|
const rows = await this.#read(as, { ...args, fields });
|
|
297
|
-
const out = rows.map(row =>
|
|
385
|
+
const out = rows.map(row => base.project(row, args.fields));
|
|
298
386
|
for (const [table, relation] of Object.entries(args.with)) {
|
|
299
387
|
await this.#attach_relation(as, { rows, out, table, relation });
|
|
300
388
|
}
|
|
@@ -330,8 +418,8 @@ export default class MySQL {
|
|
|
330
418
|
}
|
|
331
419
|
const rows = grouped.get(join_value) ?? [];
|
|
332
420
|
args.out[i][args.table] = is_many
|
|
333
|
-
? rows.map(r =>
|
|
334
|
-
: rows[0] ?
|
|
421
|
+
? rows.map(r => base.project(r, relation.fields))
|
|
422
|
+
: rows[0] ? base.project(rows[0], relation.fields) : null;
|
|
335
423
|
}
|
|
336
424
|
}
|
|
337
425
|
async #load_related(args) {
|
|
@@ -357,7 +445,7 @@ export default class MySQL {
|
|
|
357
445
|
: [in_part];
|
|
358
446
|
const WHERE = `WHERE ${where_parts.join(" AND ")}`;
|
|
359
447
|
const all_columns = Object.keys(args.as.types);
|
|
360
|
-
const fields = args.fields
|
|
448
|
+
const fields = is.defined(args.fields) && is.uint(args.fields.length)
|
|
361
449
|
? args.fields
|
|
362
450
|
: all_columns;
|
|
363
451
|
const select_fields = [...new Set([...fields, args.by])];
|
|
@@ -370,7 +458,7 @@ export default class MySQL {
|
|
|
370
458
|
: ` ORDER BY ${base_order}`;
|
|
371
459
|
const table = sql.quote(args.as.table);
|
|
372
460
|
let query;
|
|
373
|
-
if (per_parent
|
|
461
|
+
if (is.defined(per_parent)) {
|
|
374
462
|
const partition = numeric ? cast : Q `${args.by}`;
|
|
375
463
|
const rn_order = user_order ? ` ORDER BY ${user_order}` : "";
|
|
376
464
|
query = `
|
|
@@ -416,13 +504,13 @@ export default class MySQL {
|
|
|
416
504
|
const tables = [as.table, ...Object.values(args.with).map(r => r.as.table)];
|
|
417
505
|
const aliases = sql.aliases(tables);
|
|
418
506
|
const alias = aliases[as.table];
|
|
419
|
-
const fields =
|
|
507
|
+
const fields = base.fields(args.fields, as.pk) ?? Object.keys(as.types);
|
|
420
508
|
const SELECT = [
|
|
421
509
|
...fields.map(f => `${alias}.${sql.quote(f)} AS ${alias}_${f}`),
|
|
422
510
|
...Object.values(args.with).flatMap(relation => {
|
|
423
511
|
const r_alias = aliases[relation.as.table];
|
|
424
512
|
const r_fields = relation.as.pk !== null
|
|
425
|
-
?
|
|
513
|
+
? base.fields(relation.fields, relation.as.pk)
|
|
426
514
|
: relation.fields;
|
|
427
515
|
return (r_fields ?? Object.keys(relation.as.types))
|
|
428
516
|
.map(f => `${r_alias}.${sql.quote(f)} AS ${r_alias}_${f}`);
|
|
@@ -457,5 +545,32 @@ export default class MySQL {
|
|
|
457
545
|
const result = await this.#execute(query, binds);
|
|
458
546
|
return result.affectedRows;
|
|
459
547
|
}
|
|
548
|
+
sql(options) {
|
|
549
|
+
if (is.defined(options.input)) {
|
|
550
|
+
const placeholders = new Set([...options.query.matchAll(/:(\w+)/g)].map(m => m[1]));
|
|
551
|
+
const input_keys = new Set(Object.keys(options.input.properties));
|
|
552
|
+
for (const key of input_keys) {
|
|
553
|
+
if (!placeholders.has(key))
|
|
554
|
+
throw E.sql_placeholder_missing(key);
|
|
555
|
+
}
|
|
556
|
+
for (const key of placeholders) {
|
|
557
|
+
if (!input_keys.has(key))
|
|
558
|
+
throw E.sql_input_missing(key);
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
return async (args) => {
|
|
562
|
+
const input = is.defined(options.input)
|
|
563
|
+
? options.input.parse(args)
|
|
564
|
+
: undefined;
|
|
565
|
+
const binds = is.defined(input)
|
|
566
|
+
? await this.#create_params(Object.fromEntries(Object.entries(options.input.properties)
|
|
567
|
+
.map(([k, v]) => [k, v.datatype])), input)
|
|
568
|
+
: {};
|
|
569
|
+
const rows = await this.#sql(options.query, binds);
|
|
570
|
+
return (is.defined(options.output)
|
|
571
|
+
? options.output.parse(rows)
|
|
572
|
+
: undefined);
|
|
573
|
+
};
|
|
574
|
+
}
|
|
460
575
|
}
|
|
461
576
|
//# sourceMappingURL=MySQL.js.map
|
package/lib/private/typemap.js
CHANGED
|
@@ -12,6 +12,18 @@ function number(column) {
|
|
|
12
12
|
unbind: (value) => Number(value),
|
|
13
13
|
};
|
|
14
14
|
}
|
|
15
|
+
function uuid_to_bin(uuid) {
|
|
16
|
+
return Uint8Array.fromHex(uuid.replace(/-/g, ""));
|
|
17
|
+
}
|
|
18
|
+
function bin_to_uuid(buf) {
|
|
19
|
+
const hex = buf.toHex();
|
|
20
|
+
const a = hex.slice(0, 8);
|
|
21
|
+
const b = hex.slice(8, 12);
|
|
22
|
+
const c = hex.slice(12, 16);
|
|
23
|
+
const d = hex.slice(16, 20);
|
|
24
|
+
const e = hex.slice(20);
|
|
25
|
+
return `${a}-${b}-${c}-${d}-${e}`;
|
|
26
|
+
}
|
|
15
27
|
const typemap = {
|
|
16
28
|
blob: {
|
|
17
29
|
async bind(value) {
|
|
@@ -55,16 +67,15 @@ const typemap = {
|
|
|
55
67
|
},
|
|
56
68
|
},
|
|
57
69
|
i8: number("TINYINT"),
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
},*/
|
|
70
|
+
json: {
|
|
71
|
+
bind(value) {
|
|
72
|
+
return JSON.stringify(value);
|
|
73
|
+
},
|
|
74
|
+
column: "JSON",
|
|
75
|
+
unbind(value) {
|
|
76
|
+
return JSON.parse(value);
|
|
77
|
+
},
|
|
78
|
+
},
|
|
68
79
|
string: identity("TEXT"),
|
|
69
80
|
time: identity("TEXT"),
|
|
70
81
|
u128: {
|
|
@@ -97,6 +108,21 @@ const typemap = {
|
|
|
97
108
|
return new URL(value);
|
|
98
109
|
},
|
|
99
110
|
},
|
|
111
|
+
uuid: {
|
|
112
|
+
bind: uuid_to_bin,
|
|
113
|
+
column: "BINARY(16)",
|
|
114
|
+
unbind: bin_to_uuid,
|
|
115
|
+
},
|
|
116
|
+
uuid_v4: {
|
|
117
|
+
bind: uuid_to_bin,
|
|
118
|
+
column: "BINARY(16)",
|
|
119
|
+
unbind: bin_to_uuid,
|
|
120
|
+
},
|
|
121
|
+
uuid_v7: {
|
|
122
|
+
bind: uuid_to_bin,
|
|
123
|
+
column: "BINARY(16)",
|
|
124
|
+
unbind: bin_to_uuid,
|
|
125
|
+
},
|
|
100
126
|
};
|
|
101
127
|
export default typemap;
|
|
102
128
|
//# sourceMappingURL=typemap.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@primate/mysql",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "MySQL databases for Primate",
|
|
5
5
|
"homepage": "https://primate.run/docs/database/mysql",
|
|
6
6
|
"bugs": "https://github.com/primate-run/primate/issues",
|
|
@@ -17,27 +17,27 @@
|
|
|
17
17
|
"!/**/*.spec.*"
|
|
18
18
|
],
|
|
19
19
|
"devDependencies": {
|
|
20
|
-
"@rcompat/type": "^0.
|
|
20
|
+
"@rcompat/type": "^0.17.0"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@rcompat/assert": "^0.
|
|
24
|
-
"@rcompat/is": "^0.
|
|
25
|
-
"mysql2": "^3.
|
|
26
|
-
"@primate/core": "^0.
|
|
27
|
-
"pema": "0.
|
|
23
|
+
"@rcompat/assert": "^0.13.0",
|
|
24
|
+
"@rcompat/is": "^0.11.0",
|
|
25
|
+
"mysql2": "^3.22.3",
|
|
26
|
+
"@primate/core": "^0.7.0",
|
|
27
|
+
"pema": "0.7.0"
|
|
28
28
|
},
|
|
29
29
|
"peerDependencies": {
|
|
30
|
-
"primate": "^0.
|
|
30
|
+
"primate": "^0.38.0"
|
|
31
31
|
},
|
|
32
32
|
"imports": {
|
|
33
33
|
"#*": {
|
|
34
|
-
"
|
|
34
|
+
"@primate/source": "./src/private/*.ts",
|
|
35
35
|
"default": "./lib/private/*.js"
|
|
36
36
|
}
|
|
37
37
|
},
|
|
38
38
|
"exports": {
|
|
39
39
|
".": {
|
|
40
|
-
"
|
|
40
|
+
"@primate/source": "./src/public/index.ts",
|
|
41
41
|
"default": "./lib/public/index.js"
|
|
42
42
|
}
|
|
43
43
|
},
|
|
@@ -45,6 +45,10 @@
|
|
|
45
45
|
"build": "npm run clean && tsc",
|
|
46
46
|
"clean": "rm -rf ./lib",
|
|
47
47
|
"lint": "eslint .",
|
|
48
|
-
"
|
|
48
|
+
"mysql": "scripts/mysql.sh",
|
|
49
|
+
"mariadb": "scripts/mariadb.sh",
|
|
50
|
+
"test:mysql": "npm run mysql && npx proby",
|
|
51
|
+
"test:mariadb": "npm run mariadb && npx proby",
|
|
52
|
+
"test": "npm run test:mysql"
|
|
49
53
|
}
|
|
50
54
|
}
|