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/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 DataTypes<T> = {
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?: DataTypes<DataType>;
9
+ type?: AbstractDataType<DataType>;
12
10
  name?: string;
13
- defaultValue?: null | boolean | number | string | Date | JSON;
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
- } = DataType;
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: ColumnOption | DataTypes<DataType> = {}) {
44
+ export function Column(options?: ColumnOption | AbstractDataType<DataType>) {
42
45
  return function(target: Bone, propertyKey: string) {
43
- if (options['prototype'] instanceof DataType) options = { type: 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
- let columns = [];
167
- let updateOnDuplicateColumns = [];
166
+ const columns = [];
167
+ const updateOnDuplicateColumns = [];
168
168
 
169
- let values = [];
170
- let placeholders = [];
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
- let { sql, values } = this.formatInsert(spell);
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 )|| column);
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
  }
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- const DataTypes = require('../../data_types');
3
+ const { DataTypes } = require('../../data_types');
4
4
 
5
5
  class Mysql_BOOLEAN extends DataTypes.BOOLEAN {
6
6
  constructor() {
@@ -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
- throw new Error(`Unsupported mysql client ${client}`);
57
+ console.warn(`[leoric] mysql client "${client}" not tested`);
58
58
  }
59
59
 
60
60
  return require(client).createPool({
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- const DataTypes = require('../../data_types');
3
+ const { DataTypes } = require('../../data_types');
4
4
  const util = require('util');
5
5
  const Raw = require('../../raw');
6
6
 
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- const DataTypes = require('../../data_types');
3
+ const { DataTypes } = require('../../data_types');
4
4
 
5
5
  class Sqlite_DATE extends DataTypes.DATE {
6
6
  constructor(precision, timezone) {
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
- let { client, dialect, database, driver: CustomDriver, ...restOpts } = {
106
- dialect: 'mysql',
107
- database: opts.db || opts.storage,
108
- ...opts
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.prototype instanceof this.Bone) {
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 './data_types';
1
+ import DataTypes, { DataType, AbstractDataType, LENGTH_VARIANTS } from '../src/data_types';
2
2
  import { Hint, IndexHint } from './hint';
3
3
 
4
- export { DataType as DataTypes };
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: () => string;
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]: DataTypes<DataType> | AttributeMeta }): Promise<void>;
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]: DataTypes<DataType> | AttributeMeta }): Promise<void>;
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 DataType;
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]: DataTypes<DataType> | AttributeMeta };
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 DataType;
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, DataTypes<DataType> | AttributeMeta>,
897
+ attributes: Record<string, AbstractDataType<DataType> | AttributeMeta>,
902
898
  options?: InitOptions,
903
899
  descriptors?: Record<string, Function>,
904
900
  ): typeof Bone;
@@ -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
- }