leoric 2.6.3 → 2.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/History.md +11 -0
- package/index.js +2 -1
- package/package.json +2 -1
- package/src/adapters/sequelize.js +6 -6
- package/src/bone.js +6 -7
- package/src/data_types.js +442 -428
- package/src/data_types.js.map +1 -0
- package/src/data_types.ts +608 -0
- package/src/decorators.js +29 -5
- package/src/decorators.js.map +1 -1
- package/src/decorators.ts +16 -9
- package/src/drivers/abstract/index.js +8 -8
- package/src/drivers/abstract/spellbook.js +10 -8
- package/src/drivers/mysql/data_types.js +1 -1
- package/src/drivers/mysql/index.js +2 -2
- package/src/drivers/postgres/data_types.js +1 -1
- package/src/drivers/sqlite/data_types.js +1 -1
- package/src/realm.js +9 -6
- package/types/index.d.ts +12 -16
- package/types/data_types.d.ts +0 -105
package/src/decorators.ts
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import Bone from './bone';
|
|
2
|
-
import DataType from './data_types';
|
|
2
|
+
import DataTypes, { DataType, AbstractDataType } from './data_types';
|
|
3
3
|
import { ASSOCIATE_METADATA_MAP } from './constants';
|
|
4
4
|
import 'reflect-metadata';
|
|
5
5
|
|
|
6
|
-
type
|
|
7
|
-
[Property in keyof T as Exclude<Property, "toSqlString">]: T[Property];
|
|
8
|
-
}
|
|
6
|
+
type Literal = null | undefined | boolean | number | bigint | string | Date | object | ArrayBuffer;
|
|
9
7
|
|
|
10
8
|
interface ColumnOption {
|
|
11
|
-
type?:
|
|
9
|
+
type?: AbstractDataType<DataType>;
|
|
12
10
|
name?: string;
|
|
13
|
-
defaultValue?:
|
|
11
|
+
defaultValue?: Literal;
|
|
14
12
|
allowNull?: boolean;
|
|
13
|
+
primaryKey?: boolean;
|
|
14
|
+
columnName?: string;
|
|
15
|
+
validate?: {
|
|
16
|
+
[key: string]: boolean | RegExp | Function | Array<Array<Literal>> | string;
|
|
17
|
+
}
|
|
15
18
|
}
|
|
16
19
|
|
|
17
20
|
function findType(tsType) {
|
|
@@ -20,7 +23,7 @@ function findType(tsType) {
|
|
|
20
23
|
DATE,
|
|
21
24
|
STRING,
|
|
22
25
|
BOOLEAN,
|
|
23
|
-
} =
|
|
26
|
+
} = DataTypes;
|
|
24
27
|
|
|
25
28
|
switch (tsType) {
|
|
26
29
|
case BigInt:
|
|
@@ -38,9 +41,13 @@ function findType(tsType) {
|
|
|
38
41
|
}
|
|
39
42
|
}
|
|
40
43
|
|
|
41
|
-
export function Column(options
|
|
44
|
+
export function Column(options?: ColumnOption | AbstractDataType<DataType>) {
|
|
42
45
|
return function(target: Bone, propertyKey: string) {
|
|
43
|
-
if (options
|
|
46
|
+
if (options == null) {
|
|
47
|
+
options = {};
|
|
48
|
+
}
|
|
49
|
+
// target refers to model prototype, an internal instance of `Bone {}`
|
|
50
|
+
if (options['prototype'] instanceof DataType) options = { type: options as AbstractDataType<DataType> };
|
|
44
51
|
|
|
45
52
|
if (!('type' in options)) {
|
|
46
53
|
const tsType = Reflect.getMetadata('design:type', target, propertyKey);
|
|
@@ -36,8 +36,8 @@ class AbstractDriver {
|
|
|
36
36
|
|
|
37
37
|
/**
|
|
38
38
|
* query with spell
|
|
39
|
-
* @param {Spell} spell
|
|
40
|
-
* @returns
|
|
39
|
+
* @param {Spell} spell
|
|
40
|
+
* @returns
|
|
41
41
|
*/
|
|
42
42
|
async cast(spell) {
|
|
43
43
|
const { sql, values } = this.format(spell);
|
|
@@ -47,9 +47,9 @@ class AbstractDriver {
|
|
|
47
47
|
|
|
48
48
|
/**
|
|
49
49
|
* raw query
|
|
50
|
-
* @param {object|string} query
|
|
51
|
-
* @param {object | array} values
|
|
52
|
-
* @param {object} opts
|
|
50
|
+
* @param {object|string} query
|
|
51
|
+
* @param {object | array} values
|
|
52
|
+
* @param {object} opts
|
|
53
53
|
*/
|
|
54
54
|
async query(query, values, opts) {
|
|
55
55
|
throw new Error('unimplemented!');
|
|
@@ -57,7 +57,7 @@ class AbstractDriver {
|
|
|
57
57
|
|
|
58
58
|
/**
|
|
59
59
|
* disconnect manually
|
|
60
|
-
* @param {Function} callback
|
|
60
|
+
* @param {Function} callback
|
|
61
61
|
*/
|
|
62
62
|
async disconnect(callback) {
|
|
63
63
|
debug('[disconnect] called');
|
|
@@ -69,8 +69,8 @@ class AbstractDriver {
|
|
|
69
69
|
|
|
70
70
|
/**
|
|
71
71
|
* use spellbook to format spell
|
|
72
|
-
* @param {Spell} spell
|
|
73
|
-
* @returns
|
|
72
|
+
* @param {Spell} spell
|
|
73
|
+
* @returns
|
|
74
74
|
*/
|
|
75
75
|
format(spell) {
|
|
76
76
|
return this.spellbook.format(spell);
|
|
@@ -163,11 +163,11 @@ class SpellBook {
|
|
|
163
163
|
const { shardingKey } = Model;
|
|
164
164
|
const { createdAt } = Model.timestamps;
|
|
165
165
|
const { escapeId } = Model.driver;
|
|
166
|
-
|
|
167
|
-
|
|
166
|
+
const columns = [];
|
|
167
|
+
const updateOnDuplicateColumns = [];
|
|
168
168
|
|
|
169
|
-
|
|
170
|
-
|
|
169
|
+
const values = [];
|
|
170
|
+
const placeholders = [];
|
|
171
171
|
if (Array.isArray(sets)) {
|
|
172
172
|
// merge records to get the big picture of involved columnAttributes
|
|
173
173
|
const involved = sets.reduce((result, entry) => {
|
|
@@ -318,7 +318,7 @@ class SpellBook {
|
|
|
318
318
|
spell.updateOnDuplicate = true;
|
|
319
319
|
}
|
|
320
320
|
|
|
321
|
-
|
|
321
|
+
const { sql, values } = this.formatInsert(spell);
|
|
322
322
|
return {
|
|
323
323
|
sql,
|
|
324
324
|
values,
|
|
@@ -347,7 +347,7 @@ class SpellBook {
|
|
|
347
347
|
* @param {Array} columns columns for value set
|
|
348
348
|
*/
|
|
349
349
|
formatUpdateOnDuplicate(spell, columns) {
|
|
350
|
-
const { updateOnDuplicate, uniqueKeys, Model } = spell;
|
|
350
|
+
const { updateOnDuplicate, uniqueKeys, Model, sets } = spell;
|
|
351
351
|
if (!updateOnDuplicate) return '';
|
|
352
352
|
const { columnAttributes, primaryColumn } = Model;
|
|
353
353
|
const { escapeId } = Model.driver;
|
|
@@ -358,25 +358,27 @@ class SpellBook {
|
|
|
358
358
|
actualUniqueKeys.push(escapeId(field));
|
|
359
359
|
}
|
|
360
360
|
} else {
|
|
361
|
+
const setFields = Object.keys(sets);
|
|
361
362
|
// conflict_target must be unique
|
|
362
363
|
// get all unique keys
|
|
363
364
|
if (columnAttributes) {
|
|
364
365
|
for (const key in columnAttributes) {
|
|
365
366
|
const att = columnAttributes[key];
|
|
366
367
|
// use the first unique key
|
|
367
|
-
if (att.unique) {
|
|
368
|
+
if (att.unique || (att.primaryKey && setFields.includes(att.name))) {
|
|
368
369
|
actualUniqueKeys.push(escapeId(att.columnName));
|
|
369
370
|
break;
|
|
370
371
|
}
|
|
371
372
|
}
|
|
372
373
|
}
|
|
374
|
+
|
|
373
375
|
if (!actualUniqueKeys.length) actualUniqueKeys.push(escapeId(primaryColumn));
|
|
374
376
|
// default use id as primary key
|
|
375
377
|
if (!actualUniqueKeys.length) actualUniqueKeys.push(escapeId('id'));
|
|
376
378
|
}
|
|
377
379
|
|
|
378
380
|
if (Array.isArray(updateOnDuplicate) && updateOnDuplicate.length) {
|
|
379
|
-
columns = updateOnDuplicate.map(column => (columnAttributes[column] && columnAttributes[column].columnName
|
|
381
|
+
columns = updateOnDuplicate.map(column => (columnAttributes[column] && columnAttributes[column].columnName)|| column);
|
|
380
382
|
} else if (!columns.length) {
|
|
381
383
|
columns = Object.values(columnAttributes).map(({ columnName }) => columnName);
|
|
382
384
|
}
|
|
@@ -18,7 +18,6 @@ class MysqlDriver extends AbstractDriver {
|
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* Create a connection pool
|
|
21
|
-
* @param {string} clientName
|
|
22
21
|
* @param {Object} opts
|
|
23
22
|
* @param {string} opts.host
|
|
24
23
|
* @param {string} opts.port
|
|
@@ -30,6 +29,7 @@ class MysqlDriver extends AbstractDriver {
|
|
|
30
29
|
* @param {number} opts.connectTimeout - The milliseconds before a timeout occurs during the initial connection to the MySQL server. (Default: `10000`)
|
|
31
30
|
* @param {string} opts.charset
|
|
32
31
|
* @param {boolean} opts.stringifyObjects - stringify object value in dataValues
|
|
32
|
+
* @param {string} opts.client
|
|
33
33
|
*/
|
|
34
34
|
constructor(opts = {}) {
|
|
35
35
|
super(opts);
|
|
@@ -54,7 +54,7 @@ class MysqlDriver extends AbstractDriver {
|
|
|
54
54
|
} = opts;
|
|
55
55
|
|
|
56
56
|
if (client !== 'mysql' && client !== 'mysql2') {
|
|
57
|
-
|
|
57
|
+
console.warn(`[leoric] mysql client "${client}" not tested`);
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
return require(client).createPool({
|
package/src/realm.js
CHANGED
|
@@ -102,11 +102,14 @@ const rReplacementKey = /\s:(\w+)\b/g;
|
|
|
102
102
|
|
|
103
103
|
class Realm {
|
|
104
104
|
constructor(opts = {}) {
|
|
105
|
-
|
|
106
|
-
dialect
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
105
|
+
const {
|
|
106
|
+
dialect = 'mysql',
|
|
107
|
+
dialectModulePath,
|
|
108
|
+
client = dialectModulePath,
|
|
109
|
+
database = opts.db || opts.storage,
|
|
110
|
+
driver: CustomDriver,
|
|
111
|
+
...restOpts
|
|
112
|
+
} = opts;
|
|
110
113
|
const Spine = createSpine(opts);
|
|
111
114
|
const models = {};
|
|
112
115
|
|
|
@@ -214,7 +217,7 @@ class Realm {
|
|
|
214
217
|
const { rows, ...restRes } = await this.driver.query(query, values, opts);
|
|
215
218
|
const results = [];
|
|
216
219
|
|
|
217
|
-
if (rows && rows.length && opts.model && opts.model
|
|
220
|
+
if (rows && rows.length && opts.model && isBone(opts.model)) {
|
|
218
221
|
const { attributeMap } = opts.model;
|
|
219
222
|
|
|
220
223
|
for (const data of rows) {
|
package/types/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import DataType from '
|
|
1
|
+
import DataTypes, { DataType, AbstractDataType, LENGTH_VARIANTS } from '../src/data_types';
|
|
2
2
|
import { Hint, IndexHint } from './hint';
|
|
3
3
|
|
|
4
|
-
export {
|
|
4
|
+
export { DataTypes };
|
|
5
|
+
export { LENGTH_VARIANTS as LENGTH_VARIANTS };
|
|
5
6
|
export * from '../src/decorators';
|
|
6
7
|
|
|
7
8
|
export type command = 'select' | 'insert' | 'bulkInsert' | 'update' | 'delete' | 'upsert';
|
|
@@ -12,11 +13,6 @@ export class Raw {
|
|
|
12
13
|
type: 'raw';
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
type DataTypes<T> = {
|
|
17
|
-
[Property in keyof T as Exclude<Property, "toSqlString">]: T[Property]
|
|
18
|
-
}
|
|
19
|
-
|
|
20
16
|
type RawQueryResult = typeof Bone | ResultSet | boolean | number;
|
|
21
17
|
|
|
22
18
|
interface ExprIdentifier {
|
|
@@ -188,10 +184,10 @@ declare type validator = Literal | Function | Array<Literal | Literal[]>;
|
|
|
188
184
|
|
|
189
185
|
export interface AttributeMeta extends ColumnMeta {
|
|
190
186
|
jsType?: Literal;
|
|
191
|
-
type: DataType
|
|
187
|
+
type: AbstractDataType<DataType>;
|
|
192
188
|
virtual?: boolean,
|
|
193
|
-
toSqlString
|
|
194
|
-
validate
|
|
189
|
+
toSqlString?: () => string;
|
|
190
|
+
validate?: {
|
|
195
191
|
[key: string]: validator;
|
|
196
192
|
}
|
|
197
193
|
}
|
|
@@ -347,14 +343,14 @@ declare class AbstractDriver {
|
|
|
347
343
|
* @param tabe table name
|
|
348
344
|
* @param attributes attributes
|
|
349
345
|
*/
|
|
350
|
-
createTable(tabe: string, attributes: { [key: string]:
|
|
346
|
+
createTable(tabe: string, attributes: { [key: string]: AbstractDataType<DataType> | AttributeMeta }): Promise<void>;
|
|
351
347
|
|
|
352
348
|
/**
|
|
353
349
|
* alter table
|
|
354
350
|
* @param tabe table name
|
|
355
351
|
* @param attributes alter attributes
|
|
356
352
|
*/
|
|
357
|
-
alterTable(tabe: string, attributes: { [key: string]:
|
|
353
|
+
alterTable(tabe: string, attributes: { [key: string]: AbstractDataType<DataType> | AttributeMeta }): Promise<void>;
|
|
358
354
|
|
|
359
355
|
/**
|
|
360
356
|
* describe table
|
|
@@ -463,7 +459,7 @@ export class Collection<T extends Bone> extends Array<T> {
|
|
|
463
459
|
}
|
|
464
460
|
|
|
465
461
|
export class Bone {
|
|
466
|
-
static DataTypes: typeof
|
|
462
|
+
static DataTypes: typeof DataTypes;
|
|
467
463
|
|
|
468
464
|
/**
|
|
469
465
|
* get the connection pool of the driver
|
|
@@ -503,7 +499,7 @@ export class Bone {
|
|
|
503
499
|
/**
|
|
504
500
|
* The attribute definitions of the model.
|
|
505
501
|
*/
|
|
506
|
-
static attributes: { [key: string]:
|
|
502
|
+
static attributes: { [key: string]: AbstractDataType<DataType> | AttributeMeta };
|
|
507
503
|
|
|
508
504
|
/**
|
|
509
505
|
* The schema info of current model.
|
|
@@ -881,7 +877,7 @@ interface RawQueryOptions {
|
|
|
881
877
|
|
|
882
878
|
export default class Realm {
|
|
883
879
|
Bone: typeof Bone;
|
|
884
|
-
DataTypes: typeof
|
|
880
|
+
DataTypes: typeof DataTypes;
|
|
885
881
|
driver: AbstractDriver;
|
|
886
882
|
models: Record<string, Bone>;
|
|
887
883
|
connected?: boolean;
|
|
@@ -898,7 +894,7 @@ export default class Realm {
|
|
|
898
894
|
|
|
899
895
|
define(
|
|
900
896
|
name: string,
|
|
901
|
-
attributes: Record<string,
|
|
897
|
+
attributes: Record<string, AbstractDataType<DataType> | AttributeMeta>,
|
|
902
898
|
options?: InitOptions,
|
|
903
899
|
descriptors?: Record<string, Function>,
|
|
904
900
|
): typeof Bone;
|
package/types/data_types.d.ts
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
type LENGTH_VARIANTS = 'tiny' | '' | 'medium' | 'long';
|
|
2
|
-
|
|
3
|
-
interface INVOKABLE<T> extends DataType {
|
|
4
|
-
(dataLength?: LENGTH_VARIANTS): T;
|
|
5
|
-
(dataLength?: number): T;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export default class DataType {
|
|
9
|
-
toSqlString(): string;
|
|
10
|
-
|
|
11
|
-
static STRING: INVOKABLE<STRING>;
|
|
12
|
-
static INTEGER: INTEGER & INVOKABLE<INTEGER>;
|
|
13
|
-
static BIGINT: BIGINT & INVOKABLE<BIGINT>;
|
|
14
|
-
static DECIMAL: DECIMAL & INVOKABLE<DECIMAL>;
|
|
15
|
-
static TEXT: INVOKABLE<TEXT>;
|
|
16
|
-
static BLOB: INVOKABLE<BLOB>;
|
|
17
|
-
static JSON: JSON;
|
|
18
|
-
static JSONB: JSONB;
|
|
19
|
-
static BINARY: BINARY & INVOKABLE<BINARY>;
|
|
20
|
-
static VARBINARY: VARBINARY & INVOKABLE<VARBINARY>;
|
|
21
|
-
static DATE: DATE & INVOKABLE<DATE>;
|
|
22
|
-
static DATEONLY: DATEONLY;
|
|
23
|
-
static BOOLEAN: BOOLEAN;
|
|
24
|
-
static VIRTUAL: VIRTUAL;
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
declare class STRING extends DataType {
|
|
29
|
-
dataType: 'varchar';
|
|
30
|
-
dataLength: number;
|
|
31
|
-
constructor(dataLength: number);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
declare class INTEGER extends DataType {
|
|
35
|
-
dataType: 'integer' | 'bigint' | 'decimal';
|
|
36
|
-
dataLength: number;
|
|
37
|
-
constructor(dataLength: number);
|
|
38
|
-
// avoid INTEGER.UNSIGNED.ZEROFILL.UNSIGNED.UNSIGNED
|
|
39
|
-
get UNSIGNED(): Omit<this, 'UNSIGNED' | 'ZEROFILL'>;
|
|
40
|
-
get ZEROFILL(): Omit<this, 'UNSIGNED' | 'ZEROFILL'>;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
declare class BIGINT extends INTEGER {
|
|
44
|
-
dataType: 'bigint';
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
declare class DECIMAL_INNER extends INTEGER {
|
|
48
|
-
dataType: 'decimal';
|
|
49
|
-
precision: number;
|
|
50
|
-
scale: number;
|
|
51
|
-
constructor(precision: number, scale: number);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
declare type DECIMAL = Omit<DECIMAL_INNER, 'dataLength'>;
|
|
55
|
-
|
|
56
|
-
declare class TEXT extends DataType {
|
|
57
|
-
dataType: 'text';
|
|
58
|
-
dataLength: LENGTH_VARIANTS;
|
|
59
|
-
constructor(dataLength: LENGTH_VARIANTS);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
declare class BLOB extends DataType {
|
|
63
|
-
dataType: 'blob';
|
|
64
|
-
dataLength: LENGTH_VARIANTS;
|
|
65
|
-
constructor(dataLength: LENGTH_VARIANTS)
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
declare class JSON extends DataType {
|
|
69
|
-
dataType: 'text' | 'json';
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
declare class JSONB extends JSON {
|
|
73
|
-
dataType: 'json';
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
declare class BINARY extends DataType {
|
|
77
|
-
dataType: 'binary';
|
|
78
|
-
dataLength: number;
|
|
79
|
-
constructor(dataLength: number);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
declare class VARBINARY extends DataType {
|
|
83
|
-
dataType: 'varbinary';
|
|
84
|
-
dataLength: number;
|
|
85
|
-
constructor(dataLength: number);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
declare class DATE extends DataType {
|
|
89
|
-
dataType: 'date';
|
|
90
|
-
precision: number;
|
|
91
|
-
timezone: boolean;
|
|
92
|
-
constructor(precision: number, timezone?: boolean)
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
declare class DATEONLY extends DataType {
|
|
96
|
-
dataType: 'dateonly';
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
declare class BOOLEAN extends DataType {
|
|
100
|
-
dataType: 'boolean'
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
declare class VIRTUAL extends DataType {
|
|
104
|
-
dataType: 'virtual'
|
|
105
|
-
}
|