tspace-mysql 1.5.0 → 1.5.2

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.
Files changed (53) hide show
  1. package/README.md +1856 -701
  2. package/build/cli/dump/db.js +3 -2
  3. package/build/cli/generate/make.js +17 -15
  4. package/build/cli/generate/modelDecorator.d.ts +1 -1
  5. package/build/cli/generate/modelDecorator.js +2 -3
  6. package/build/cli/index.js +45 -27
  7. package/build/cli/migrate/make.d.ts +1 -1
  8. package/build/cli/migrate/make.js +2 -2
  9. package/build/cli/migrations/make-db.d.ts +4 -0
  10. package/build/cli/migrations/make-db.js +58 -0
  11. package/build/cli/migrations/make.d.ts +2 -0
  12. package/build/cli/migrations/make.js +201 -0
  13. package/build/lib/Interface.d.ts +24 -5
  14. package/build/lib/connection/index.d.ts +5 -1
  15. package/build/lib/connection/index.js +65 -8
  16. package/build/lib/connection/options.js +2 -2
  17. package/build/lib/constants/index.js +13 -3
  18. package/build/lib/{tspace → core}/Abstracts/AbstractBuilder.d.ts +1 -1
  19. package/build/lib/{tspace → core}/Abstracts/AbstractModel.d.ts +15 -13
  20. package/build/lib/{tspace → core}/Blueprint.d.ts +14 -3
  21. package/build/lib/{tspace → core}/Blueprint.js +30 -4
  22. package/build/lib/{tspace → core}/Builder.d.ts +140 -44
  23. package/build/lib/{tspace → core}/Builder.js +772 -459
  24. package/build/lib/{tspace → core}/DB.d.ts +20 -4
  25. package/build/lib/{tspace → core}/DB.js +73 -39
  26. package/build/lib/{tspace → core}/Decorator.js +2 -2
  27. package/build/lib/{tspace → core/Handlers}/Logger.d.ts +3 -3
  28. package/build/lib/{tspace → core/Handlers}/Logger.js +4 -4
  29. package/build/lib/{tspace → core}/Handlers/Proxy.js +2 -2
  30. package/build/lib/{tspace → core}/Handlers/Relation.d.ts +2 -4
  31. package/build/lib/{tspace → core}/Handlers/Relation.js +69 -48
  32. package/build/lib/{tspace → core}/Handlers/State.d.ts +1 -1
  33. package/build/lib/{tspace → core}/Handlers/State.js +3 -3
  34. package/build/lib/{tspace → core}/Model.d.ts +358 -133
  35. package/build/lib/{tspace → core}/Model.js +1316 -558
  36. package/build/lib/core/Schema.d.ts +137 -0
  37. package/build/lib/{tspace → core}/Schema.js +147 -52
  38. package/build/lib/core/Type.d.ts +6 -0
  39. package/build/lib/core/Type.js +2 -0
  40. package/build/lib/{tspace → core}/index.d.ts +2 -1
  41. package/build/lib/{tspace → core}/index.js +3 -2
  42. package/build/lib/index.d.ts +2 -2
  43. package/build/lib/index.js +2 -2
  44. package/build/lib/utils/index.d.ts +1 -0
  45. package/build/lib/utils/index.js +17 -7
  46. package/package.json +6 -4
  47. package/build/lib/tspace/Schema.d.ts +0 -70
  48. /package/build/lib/{tspace → core}/Abstracts/AbstractBuilder.js +0 -0
  49. /package/build/lib/{tspace → core}/Abstracts/AbstractDB.d.ts +0 -0
  50. /package/build/lib/{tspace → core}/Abstracts/AbstractDB.js +0 -0
  51. /package/build/lib/{tspace → core}/Abstracts/AbstractModel.js +0 -0
  52. /package/build/lib/{tspace → core}/Decorator.d.ts +0 -0
  53. /package/build/lib/{tspace → core}/Handlers/Proxy.d.ts +0 -0
@@ -29,15 +29,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
29
29
  exports.Pool = exports.loadOptionsEnvironment = exports.PoolConnection = void 0;
30
30
  const fs_1 = __importDefault(require("fs"));
31
31
  const path_1 = __importDefault(require("path"));
32
+ const mysql2_1 = require("mysql2");
33
+ const events_1 = require("events");
32
34
  const options_1 = __importStar(require("./options"));
33
35
  Object.defineProperty(exports, "loadOptionsEnvironment", { enumerable: true, get: function () { return options_1.loadOptionsEnvironment; } });
34
- const mysql2_1 = require("mysql2");
35
- class PoolConnection {
36
+ class PoolConnection extends events_1.EventEmitter {
36
37
  /**
37
38
  *
38
39
  * @Init a options connection pool
39
40
  */
40
41
  constructor(options) {
42
+ super();
41
43
  this.OPTIONS = this._loadOptions();
42
44
  if (options) {
43
45
  this.OPTIONS = new Map(Object.entries(Object.assign(Object.assign({}, Object.fromEntries(this.OPTIONS)), JSON.parse(JSON.stringify(options)))));
@@ -53,21 +55,35 @@ class PoolConnection {
53
55
  connection() {
54
56
  const pool = (0, mysql2_1.createPool)(Object.fromEntries(this.OPTIONS));
55
57
  pool.getConnection((err, _) => {
56
- if (err == null || !err)
58
+ if (err == null || !err) {
59
+ this.emit('CONNECTION', pool);
57
60
  return;
61
+ }
58
62
  const message = this._messageError.bind(this);
59
63
  process.nextTick(() => {
60
- console.log(message(err === null || err === void 0 ? void 0 : err.message));
64
+ console.log(message(err.message == null || err.message === '' ? err.code : err.message));
61
65
  if (options_1.default.CONNECTION_ERROR)
62
66
  return process.exit();
63
67
  });
64
68
  });
69
+ pool.on('release', (connection) => {
70
+ this.emit('RELEASE', connection);
71
+ });
65
72
  return {
73
+ on: (event, data) => {
74
+ return this.on(event, data);
75
+ },
66
76
  query: (sql) => {
67
77
  return new Promise((resolve, reject) => {
78
+ const start = Date.now();
68
79
  pool.query(sql, (err, results) => {
69
80
  if (err)
70
81
  return reject(err);
82
+ this._detectEventQuery({
83
+ start,
84
+ sql,
85
+ results
86
+ });
71
87
  return resolve(results);
72
88
  });
73
89
  });
@@ -78,11 +94,13 @@ class PoolConnection {
78
94
  if (err)
79
95
  return reject(err);
80
96
  const query = (sql) => {
97
+ const start = Date.now();
81
98
  return new Promise((resolve, reject) => {
82
- connection.query(sql, (err, result) => {
99
+ connection.query(sql, (err, results) => {
83
100
  if (err)
84
101
  return reject(err);
85
- return resolve(result);
102
+ this._detectEventQuery({ start, sql, results });
103
+ return resolve(results);
86
104
  });
87
105
  });
88
106
  };
@@ -90,6 +108,9 @@ class PoolConnection {
90
108
  const commit = () => query('COMMIT');
91
109
  const rollback = () => query('ROLLBACK');
92
110
  return resolve({
111
+ on: (event, data) => {
112
+ return this.on(event, data);
113
+ },
93
114
  query,
94
115
  startTransaction,
95
116
  commit,
@@ -100,6 +121,42 @@ class PoolConnection {
100
121
  }
101
122
  };
102
123
  }
124
+ _detectEventQuery({ start, sql, results }) {
125
+ const duration = Date.now() - start;
126
+ if (duration > 1000 * 5) {
127
+ console.log(`\n\x1b[1m\x1b[31mWARING:\x1b[0m \x1b[1m\x1b[30mSlow query detected: Execution time: ${duration} ms\x1b[0m \n\x1b[33m${sql};\x1b[0m`);
128
+ this.emit('SLOW_QUERY', {
129
+ sql,
130
+ results,
131
+ execution: duration
132
+ });
133
+ }
134
+ this.emit('QUERY', {
135
+ sql,
136
+ results,
137
+ execution: duration
138
+ });
139
+ this.emit(this._detectQueryType(sql), {
140
+ sql,
141
+ results,
142
+ execution: duration
143
+ });
144
+ }
145
+ _detectQueryType(query) {
146
+ const selectRegex = /^SELECT\b/i;
147
+ const updateRegex = /^UPDATE\b/i;
148
+ const insertRegex = /^INSERT\b/i;
149
+ const deleteRegex = /^DELETE\b/i;
150
+ if (selectRegex.test(query))
151
+ return 'SELECT';
152
+ if (updateRegex.test(query))
153
+ return 'UPDATE';
154
+ if (insertRegex.test(query))
155
+ return 'INSERT';
156
+ if (deleteRegex.test(query))
157
+ return 'DELETE';
158
+ return 'UNKNOWN';
159
+ }
103
160
  _defaultOptions() {
104
161
  return new Map(Object.entries({
105
162
  connectionLimit: Number.isNaN(Number(options_1.default.CONNECTION_LIMIT)) ? 30 : Number(options_1.default.CONNECTION_LIMIT),
@@ -197,7 +254,7 @@ class PoolConnection {
197
254
  }
198
255
  return data;
199
256
  }
200
- _messageError(err) {
257
+ _messageError(message) {
201
258
  return `
202
259
  \x1b[1m\x1b[31m
203
260
  Connection lost to database ! \x1b[0m
@@ -209,7 +266,7 @@ class PoolConnection {
209
266
  PASSWORD : ${this.OPTIONS.get('password')} \x1b[0m
210
267
  -------------------------------
211
268
  \x1b[1m\x1b[31mError Message
212
- : ${err !== null && err !== void 0 ? err : ''} \x1b[0m
269
+ : ${message !== null && message !== void 0 ? message : ''} \x1b[0m
213
270
  `;
214
271
  }
215
272
  }
@@ -23,7 +23,7 @@ const ENV = process.env;
23
23
  const env = {
24
24
  HOST: ENV.DB_HOST || ENV.TSPACE_HOST,
25
25
  PORT: ENV.DB_PORT || ENV.TSPACE_PORT || 3306,
26
- USERNAME: ENV.DB_USERNAME || ENV.TSPACE_USERNAME,
26
+ USERNAME: ENV.DB_USERNAME || ENV.TSPACE_USERNAME || ENV.DB_USER,
27
27
  PASSWORD: ENV.DB_PASSWORD || ENV.TSPACE_PASSWORD || '',
28
28
  DATABASE: ENV.DB_DATABASE || ENV.TSPACE_DATABASE,
29
29
  CONNECTION_LIMIT: ENV.DB_CONNECTION_LIMIT || ENV.TSPACE_CONNECTION_LIMIT || 30,
@@ -38,7 +38,7 @@ const env = {
38
38
  MULTIPLE_STATEMENTS: ENV.MULTIPLE_STATEMENTS || ENV.TSPACE_MULTIPLE_STATEMENTS || false
39
39
  };
40
40
  for (const [key, value] of Object.entries(env)) {
41
- if (value == null)
41
+ if (value == null || key == null)
42
42
  continue;
43
43
  if (typeof value === 'string' && ['true', 'false'].some(v => value.toLowerCase() === v)) {
44
44
  env[key] = JSON.parse(value.toLowerCase());
@@ -47,7 +47,9 @@ const CONSTANTS = Object.freeze({
47
47
  NOT: 'NOT',
48
48
  DUPLICATE: 'DUPLICATE',
49
49
  KEY: 'KEY',
50
- RAW: '$RAW',
50
+ RAW: '$RAW:',
51
+ OP: '$OP:',
52
+ IGNORE: '$IGNORE',
51
53
  WHEN: 'WHEN',
52
54
  THEN: 'THEN',
53
55
  ELSE: 'ELSE',
@@ -74,6 +76,7 @@ const CONSTANTS = Object.freeze({
74
76
  ON_DELETE: 'ON DELETE',
75
77
  ON_UPDATE: 'ON UPDATE',
76
78
  ADD: 'ADD',
79
+ CHANGE: 'CHANGE',
77
80
  ADD_CONSTRAINT: 'ADD CONSTRAINT',
78
81
  AFTER: 'AFTER',
79
82
  ALTER_TABLE: 'ALTER TABLE',
@@ -121,9 +124,11 @@ const CONSTANTS = Object.freeze({
121
124
  UUID: false,
122
125
  PAGE: 1,
123
126
  PER_PAGE: 1,
124
- HOOKS: []
127
+ HOOKS: [],
128
+ RETURN_TYPE: null
125
129
  },
126
130
  MODEL: {
131
+ MODEL_NAME: 'MODEL',
127
132
  PRIMARY_KEY: 'id',
128
133
  VOID: false,
129
134
  SELECT: [],
@@ -169,13 +174,18 @@ const CONSTANTS = Object.freeze({
169
174
  CREATED_AT: 'created_at',
170
175
  UPDATED_AT: 'updated_at'
171
176
  },
177
+ LOGGER: false,
178
+ LOGGER_OPTIONS: null,
179
+ TABLE_LOGGER: '$loggers',
172
180
  VALIDATE_SCHEMA: false,
173
181
  VALIDATE_SCHEMA_DEFINED: null,
174
182
  FUNCTION_RELATION: false,
175
183
  SCHEMA_TABLE: null,
176
184
  RETRY: 0,
177
185
  OBSERVER: null,
178
- DATA: null
186
+ DATA: null,
187
+ BEFORE_CREATING_TABLE: null,
188
+ RETURN_TYPE: null
179
189
  }
180
190
  });
181
191
  exports.CONSTANTS = CONSTANTS;
@@ -55,7 +55,7 @@ declare abstract class AbstractBuilder {
55
55
  abstract rightJoin(pk: string, fk: string): this;
56
56
  abstract leftJoin(pk: string, fk: string): this;
57
57
  abstract crossJoin(pk: string, fk: string): this;
58
- abstract orderBy(column: string, order: string): this;
58
+ abstract orderBy(column: string, order: 'ASC' | 'DESC'): this;
59
59
  abstract orderByRaw(column: string, order: string): this;
60
60
  abstract latest(...columns: string[]): this;
61
61
  abstract latestRaw(...columns: string[]): this;
@@ -2,7 +2,8 @@ import { Pattern, Relation, RelationQuery, ValidateSchema } from '../../Interfac
2
2
  import { Blueprint } from '../Blueprint';
3
3
  import { Builder } from '../Builder';
4
4
  import { RelationHandler } from '../Handlers/Relation';
5
- declare abstract class AbstractModel extends Builder {
5
+ import { Model } from '../Model';
6
+ declare abstract class AbstractModel<T, R> extends Builder {
6
7
  protected $relation: RelationHandler | undefined;
7
8
  protected $schema: Record<string, Blueprint> | undefined;
8
9
  protected $validateSchema: ValidateSchema | undefined;
@@ -27,6 +28,7 @@ declare abstract class AbstractModel extends Builder {
27
28
  updated: Function;
28
29
  deleted: Function;
29
30
  }) | undefined;
31
+ protected abstract column<K extends keyof T>(key: K): K;
30
32
  protected abstract useUUID(): this;
31
33
  protected abstract usePrimaryKey(primaryKey: string): this;
32
34
  protected abstract useRegistry(): this;
@@ -47,7 +49,7 @@ declare abstract class AbstractModel extends Builder {
47
49
  protected abstract hasMany({ name, model, localKey, foreignKey, freezeTable, as }: Relation): this;
48
50
  protected abstract belongsTo({ name, model, localKey, foreignKey, freezeTable, as }: Relation): this;
49
51
  protected abstract belongsToMany({ name, model, localKey, foreignKey, freezeTable, as }: Relation): this;
50
- protected abstract buildMethodRelation(name: string, callback?: Function): this;
52
+ protected abstract buildMethodRelation<K extends keyof R>(name: K, callback?: Function): this;
51
53
  protected abstract hasOneBuilder({ name, model, localKey, foreignKey, freezeTable, as }: RelationQuery, callback: Function): this;
52
54
  protected abstract hasManyBuilder({ name, model, localKey, foreignKey, freezeTable, as }: RelationQuery, callback: Function): this;
53
55
  protected abstract belongsToBuilder({ name, model, localKey, foreignKey, freezeTable, as }: RelationQuery, callback: Function): this;
@@ -58,17 +60,17 @@ declare abstract class AbstractModel extends Builder {
58
60
  abstract onlyTrashed(): this;
59
61
  abstract trashed(): this;
60
62
  abstract restore(): Promise<any[]>;
61
- abstract with(...nameRelations: string[]): this;
62
- abstract withQuery(nameRelations: string, callback: Function): this;
63
- abstract withExists(...nameRelations: string[]): this;
64
- abstract withTrashed(...nameRelations: string[]): this;
65
- abstract withAll(...nameRelations: string[]): this;
66
- abstract has(...nameRelations: string[]): this;
67
- abstract relations(...nameRelations: string[]): this;
68
- abstract relationQuery(nameRelations: string, callback: Function): this;
69
- abstract relationsExists(...nameRelations: string[]): this;
70
- abstract relationsAll(...nameRelations: string[]): this;
71
- abstract relationsTrashed(...nameRelations: string[]): this;
63
+ abstract with<K extends keyof R>(...nameRelations: K[]): this;
64
+ abstract withQuery<K extends keyof R, TModel extends Model>(nameRelations: K, callback: (query: TModel) => TModel): this;
65
+ abstract withExists<K extends keyof R>(...nameRelations: K[]): this;
66
+ abstract withTrashed<K extends keyof R>(...nameRelations: K[]): this;
67
+ abstract withAll<K extends keyof R>(...nameRelations: K[]): this;
68
+ abstract has<K extends keyof R>(...nameRelations: K[]): this;
69
+ abstract relations<K extends keyof R>(...nameRelations: K[]): this;
70
+ abstract relationQuery<K extends keyof R, TModel extends Model>(nameRelations: K, callback: (query: TModel) => TModel): this;
71
+ abstract relationsExists<K extends keyof R>(...nameRelations: K[]): this;
72
+ abstract relationsAll<K extends keyof R>(...nameRelations: K[]): this;
73
+ abstract relationsTrashed<K extends keyof R>(...nameRelations: K[]): this;
72
74
  }
73
75
  export { AbstractModel };
74
76
  export default AbstractModel;
@@ -18,6 +18,7 @@ declare class Blueprint {
18
18
  private _type;
19
19
  private _attributes;
20
20
  private _foreignKey;
21
+ private _column;
21
22
  private _valueType;
22
23
  /**
23
24
  * Assign type 'int' in table
@@ -101,19 +102,16 @@ declare class Blueprint {
101
102
  mediumtext(): this;
102
103
  /**
103
104
  * Assign type 'TINYTEXT' in table
104
- * @param {number} length [length = 1] length of string
105
105
  * @return {this} this
106
106
  */
107
107
  tinyText(): this;
108
108
  /**
109
109
  * Assign type 'TINYTEXT' in table
110
- * @param {number} length [length = 1] length of string
111
110
  * @return {this} this
112
111
  */
113
112
  tinytext(): this;
114
113
  /**
115
114
  * Assign type 'TEXT' in table
116
- * @param {number} length [length = 1] length of string
117
115
  * @return {this} this
118
116
  */
119
117
  text(): this;
@@ -163,6 +161,11 @@ declare class Blueprint {
163
161
  * @return {this} this
164
162
  */
165
163
  notNull(): this;
164
+ /**
165
+ * Assign attributes 'NOT NULL' in table
166
+ * @return {this} this
167
+ */
168
+ notnull(): this;
166
169
  /**
167
170
  * Assign attributes 'PRIMARY KEY' in table
168
171
  * @return {this} this
@@ -174,6 +177,12 @@ declare class Blueprint {
174
177
  * @return {this} this
175
178
  */
176
179
  default(value: string | number): this;
180
+ /**
181
+ * Assign attributes 'defaultValue' in table
182
+ * @param {string | number} value default value
183
+ * @return {this} this
184
+ */
185
+ defaultValue(value: string | number): this;
177
186
  /**
178
187
  * Assign attributes 'default currentTimestamp' in table
179
188
  * @return {this} this
@@ -210,6 +219,8 @@ declare class Blueprint {
210
219
  onDelete?: 'CASCADE' | 'NO ACTION' | 'RESTRICT' | 'SET NULL';
211
220
  onUpdate?: 'CASCADE' | 'NO ACTION' | 'RESTRICT' | 'SET NULL';
212
221
  }): this;
222
+ bindColumn(column: string): this;
223
+ get column(): string | null;
213
224
  get type(): string;
214
225
  get attributes(): string[];
215
226
  get foreignKey(): Record<string, any> | null;
@@ -21,6 +21,7 @@ class Blueprint {
21
21
  this._type = 'INT';
22
22
  this._attributes = [];
23
23
  this._foreignKey = null;
24
+ this._column = null;
24
25
  this._valueType = String;
25
26
  }
26
27
  /**
@@ -110,6 +111,8 @@ class Blueprint {
110
111
  varchar(length = 191) {
111
112
  if (length > 255)
112
113
  length = 255;
114
+ if (length <= 0)
115
+ length = 1;
113
116
  this._addAssignType(`VARCHAR(${length})`);
114
117
  return this;
115
118
  }
@@ -164,7 +167,6 @@ class Blueprint {
164
167
  }
165
168
  /**
166
169
  * Assign type 'TINYTEXT' in table
167
- * @param {number} length [length = 1] length of string
168
170
  * @return {this} this
169
171
  */
170
172
  tinyText() {
@@ -173,7 +175,6 @@ class Blueprint {
173
175
  }
174
176
  /**
175
177
  * Assign type 'TINYTEXT' in table
176
- * @param {number} length [length = 1] length of string
177
178
  * @return {this} this
178
179
  */
179
180
  tinytext() {
@@ -182,7 +183,6 @@ class Blueprint {
182
183
  }
183
184
  /**
184
185
  * Assign type 'TEXT' in table
185
- * @param {number} length [length = 1] length of string
186
186
  * @return {this} this
187
187
  */
188
188
  text() {
@@ -266,6 +266,14 @@ class Blueprint {
266
266
  this._addAssignAttribute(`NOT NULL`);
267
267
  return this;
268
268
  }
269
+ /**
270
+ * Assign attributes 'NOT NULL' in table
271
+ * @return {this} this
272
+ */
273
+ notnull() {
274
+ this._addAssignAttribute(`NOT NULL`);
275
+ return this;
276
+ }
269
277
  /**
270
278
  * Assign attributes 'PRIMARY KEY' in table
271
279
  * @return {this} this
@@ -283,6 +291,15 @@ class Blueprint {
283
291
  this._addAssignAttribute(`DEFAULT '${value}'`);
284
292
  return this;
285
293
  }
294
+ /**
295
+ * Assign attributes 'defaultValue' in table
296
+ * @param {string | number} value default value
297
+ * @return {this} this
298
+ */
299
+ defaultValue(value) {
300
+ this._addAssignAttribute(`DEFAULT '${value}'`);
301
+ return this;
302
+ }
286
303
  /**
287
304
  * Assign attributes 'default currentTimestamp' in table
288
305
  * @return {this} this
@@ -326,14 +343,23 @@ class Blueprint {
326
343
  * @return {this} this
327
344
  */
328
345
  foreign({ references, on, onDelete, onUpdate }) {
346
+ if (on == null)
347
+ return this;
329
348
  this._foreignKey = {
330
349
  references: references == null ? 'id' : references,
331
- on: typeof on === 'string' ? on : new on(),
350
+ on,
332
351
  onDelete: onDelete == null ? 'CASCADE' : onDelete,
333
352
  onUpdate: onUpdate == null ? 'CASCADE' : onUpdate
334
353
  };
335
354
  return this;
336
355
  }
356
+ bindColumn(column) {
357
+ this._column = column;
358
+ return this;
359
+ }
360
+ get column() {
361
+ return this._column;
362
+ }
337
363
  get type() {
338
364
  return this._type;
339
365
  }