tspace-mysql 1.4.6 → 1.4.7

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.
@@ -37,7 +37,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
37
37
  Object.defineProperty(exports, "__esModule", { value: true });
38
38
  exports.Schema = void 0;
39
39
  const Builder_1 = require("./Builder");
40
- const Model_1 = require("./Model");
41
40
  const fs_1 = __importDefault(require("fs"));
42
41
  const path_1 = __importDefault(require("path"));
43
42
  class Schema extends Builder_1.Builder {
@@ -60,7 +59,7 @@ class Schema extends Builder_1.Builder {
60
59
  `${table} (${columns === null || columns === void 0 ? void 0 : columns.join(',')})`,
61
60
  `ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8`
62
61
  ].join(' ');
63
- yield this.rawQuery(sql);
62
+ yield this.query(sql);
64
63
  console.log(`Migrats : '${table}' created successfully`);
65
64
  return;
66
65
  }
@@ -88,9 +87,11 @@ class Schema extends Builder_1.Builder {
88
87
  }
89
88
  /**
90
89
  *
91
- * Sync will check for create or update table or columns with useSchema in your model.
90
+ * The 'Sync' method is used to check for create or update table or columns with your schema in your model.
91
+ *
92
+ * The schema can define with method 'useSchema'
92
93
  * @param {string} pathFolders directory to models
93
- * @property {boolean} options.force - forec to always check columns is exists
94
+ * @property {boolean} options.force - forec always check all columns if not exists will be created
94
95
  * @property {boolean} options.log - show log execution with sql statements
95
96
  * @property {boolean} options.delay - wait for execution
96
97
  * @example
@@ -127,7 +128,7 @@ class Schema extends Builder_1.Builder {
127
128
  * this.useSchema ({
128
129
  * id : new Blueprint().int().notNull().primary().autoIncrement(),
129
130
  * uuid : new Blueprint().varchar(50).null(),
130
- * user_id : new Blueprint().int().notNull(),
131
+ * user_id : new Blueprint().int().notNull().foreign({ references : 'id' , on : User , onDelete : 'CASCADE' , onUpdate : 'CASCADE' }),,
131
132
  * title : new Blueprint().varchar(255).null(),
132
133
  * created_at : new Blueprint().timestamp().null(),
133
134
  * updated_at : new Blueprint().timestamp().null(),
@@ -138,65 +139,138 @@ class Schema extends Builder_1.Builder {
138
139
  *
139
140
  * await Schema.sync(`app/Models` , { force : true })
140
141
  */
141
- static sync(pathFolders, { force = false, log = false, delay = 3000 } = {}) {
142
+ static sync(pathFolders, { force = false, log = false, foreign = false, delay = 1500 } = {}) {
142
143
  return __awaiter(this, void 0, void 0, function* () {
143
144
  const directories = fs_1.default.readdirSync(pathFolders, { withFileTypes: true });
144
- const files = yield Promise.all(directories.map((directory) => {
145
+ const files = (yield Promise.all(directories.map((directory) => {
145
146
  const newDir = path_1.default.resolve(String(pathFolders), directory.name);
146
147
  if (directory.isDirectory() && directory.name.toLocaleLowerCase().includes('migrations'))
147
148
  return null;
148
149
  return directory.isDirectory() ? Schema.sync(newDir, { force, log, delay }) : newDir;
149
- }));
150
+ })));
150
151
  const pathModels = [].concat(...files).filter(d => d != null || d === '');
151
152
  yield new Promise(r => setTimeout(r, delay));
152
- const promises = pathModels.map((pathModel) => Schema._syncExecute({ pathModel, force, log }));
153
- yield Promise.all(promises);
153
+ const models = yield Promise.all(pathModels.map((pathModel) => Schema._import(pathModel)).filter(d => d != null));
154
+ if (!models.length)
155
+ return;
156
+ yield Schema._syncExecute({ models, force, log, foreign });
154
157
  return;
155
158
  });
156
159
  }
157
- static _syncExecute({ pathModel, force, log }) {
160
+ static _import(pathModel) {
161
+ return __awaiter(this, void 0, void 0, function* () {
162
+ try {
163
+ const loadModel = yield Promise.resolve(`${pathModel}`).then(s => __importStar(require(s))).catch(_ => { });
164
+ const model = new loadModel.default();
165
+ return model;
166
+ }
167
+ catch (err) {
168
+ console.log(`Check your 'Model' from path : '${pathModel}' is not instance of Model`);
169
+ return null;
170
+ }
171
+ });
172
+ }
173
+ static _syncExecute({ models, force, log, foreign }) {
158
174
  var _a, _b, _c, _d;
159
175
  return __awaiter(this, void 0, void 0, function* () {
160
- const loadModel = yield Promise.resolve(`${pathModel}`).then(s => __importStar(require(s)));
161
- if (!loadModel.hasOwnProperty('default') && !(loadModel instanceof Model_1.Model))
162
- return;
163
- const model = new loadModel.default();
164
- const schemaModel = yield model.getSchemaModel();
165
- if (!schemaModel)
166
- return;
167
- const checkTableIsExists = Boolean((yield new Builder_1.Builder().rawQuery(`SHOW TABLES LIKE '${model.getTableName()}';`)).length);
168
- if (!checkTableIsExists) {
169
- const sql = new Schema().createTable(model.getTableName(), schemaModel);
170
- yield new Builder_1.Builder().debug(log).rawQuery(sql);
171
- return;
176
+ const checkTables = yield new Builder_1.Builder().query('SHOW TABLES');
177
+ const existsTables = checkTables.map((c) => Object.values(c)[0]);
178
+ // console.log(checkTables)
179
+ for (const model of models) {
180
+ if (model == null)
181
+ continue;
182
+ const schemaModel = model.getSchemaModel();
183
+ if (!schemaModel)
184
+ continue;
185
+ const checkTableIsExists = existsTables.some((table) => table === model.getTableName());
186
+ if (!checkTableIsExists) {
187
+ const sql = new Schema().createTable(`\`${model.getTableName()}\``, schemaModel);
188
+ yield new Builder_1.Builder().debug(log).query(sql);
189
+ yield this._syncForeignKey({
190
+ schemaModel,
191
+ model,
192
+ log
193
+ });
194
+ continue;
195
+ }
196
+ if (foreign) {
197
+ yield this._syncForeignKey({
198
+ schemaModel,
199
+ model,
200
+ log
201
+ });
202
+ }
203
+ if (!force)
204
+ continue;
205
+ const schemaTable = yield model.getSchema();
206
+ const schemaTableKeys = schemaTable.map((k) => k.Field);
207
+ const schemaModelKeys = Object.keys(schemaModel);
208
+ const missingColumns = schemaModelKeys.filter(schemaModelKey => !schemaTableKeys.includes(schemaModelKey));
209
+ if (!missingColumns.length)
210
+ continue;
211
+ const entries = Object.entries(schemaModel);
212
+ for (const column of missingColumns) {
213
+ const indexWithColumn = entries.findIndex(([key]) => key === column);
214
+ const findAfterIndex = indexWithColumn ? entries[indexWithColumn - 1][0] : null;
215
+ const type = (_b = (_a = schemaModel[column]) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : null;
216
+ const attributes = (_d = (_c = schemaModel[column]) === null || _c === void 0 ? void 0 : _c.attributes) !== null && _d !== void 0 ? _d : null;
217
+ if (findAfterIndex == null || type == null || attributes == null)
218
+ continue;
219
+ const sql = [
220
+ 'ALTER TABLE',
221
+ `\`${model.getTableName()}\``,
222
+ 'ADD',
223
+ `\`${column}\` ${type} ${attributes.join(' ')}`,
224
+ 'AFTER',
225
+ `\`${findAfterIndex}\``
226
+ ].join(' ');
227
+ yield new Builder_1.Builder().debug(log).query(sql);
228
+ }
229
+ yield this._syncForeignKey({
230
+ schemaModel,
231
+ model,
232
+ log
233
+ });
172
234
  }
173
- if (!force)
174
- return;
175
- const schemaTable = yield model.getSchema();
176
- const schemaTableKeys = schemaTable.map((k) => k.Field);
177
- const schemaModelKeys = Object.keys(schemaModel);
178
- const missingColumns = schemaModelKeys.filter(schemaModelKey => !schemaTableKeys.includes(schemaModelKey));
179
- if (!missingColumns.length)
180
- return;
181
- const entries = Object.entries(schemaModel);
182
- for (const column of missingColumns) {
183
- const indexWithColumn = entries.findIndex(([key]) => key === column);
184
- const findAfterIndex = indexWithColumn ? entries[indexWithColumn - 1][0] : null;
185
- const type = (_b = (_a = schemaModel[column]) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : null;
186
- const attributes = (_d = (_c = schemaModel[column]) === null || _c === void 0 ? void 0 : _c.attributes) !== null && _d !== void 0 ? _d : null;
187
- if (findAfterIndex == null || type == null || attributes == null)
235
+ return;
236
+ });
237
+ }
238
+ static _syncForeignKey({ schemaModel, model, log }) {
239
+ var _a;
240
+ return __awaiter(this, void 0, void 0, function* () {
241
+ for (const key in schemaModel) {
242
+ if (((_a = schemaModel[key]) === null || _a === void 0 ? void 0 : _a.foreignKey) == null)
188
243
  continue;
244
+ const foreign = schemaModel[key].foreignKey;
245
+ const table = typeof foreign.on === "string" ? foreign.on : foreign.on.getTableName();
189
246
  const sql = [
190
- 'ALTER TABLE',
247
+ "ALTER TABLE",
191
248
  `\`${model.getTableName()}\``,
192
- 'ADD',
193
- `\`${column}\` ${type} ${attributes.join(' ')}`,
194
- 'AFTER',
195
- `\`${findAfterIndex}\``
249
+ "ADD CONSTRAINT",
250
+ `\`${model.getTableName()}(${key})_${table}(${foreign.references})\``,
251
+ `FOREIGN KEY(\`${key}\`)`,
252
+ `REFERENCES \`${table}\`(\`${foreign.references}\`)`,
253
+ `ON DELETE ${foreign.onDelete} ON UPDATE ${foreign.onUpdate}`
196
254
  ].join(' ');
197
- yield new Builder_1.Builder().debug(log).rawQuery(sql);
255
+ try {
256
+ yield new Builder_1.Builder().debug(log).query(sql);
257
+ }
258
+ catch (e) {
259
+ if (typeof foreign.on === "string") {
260
+ console.log(e);
261
+ continue;
262
+ }
263
+ if (String(e.message).includes("Duplicate foreign key constraint"))
264
+ continue;
265
+ const schemaModelOn = yield foreign.on.getSchemaModel();
266
+ if (!schemaModelOn)
267
+ continue;
268
+ const tableSql = new Schema().createTable(`\`${table}\``, schemaModelOn);
269
+ yield new Builder_1.Builder().debug(log).query(tableSql).catch(e => console.log(e));
270
+ yield new Builder_1.Builder().debug(log).query(sql).catch(e => console.log(e));
271
+ continue;
272
+ }
198
273
  }
199
- return;
200
274
  });
201
275
  }
202
276
  }
@@ -39,6 +39,10 @@ class StateHandler {
39
39
  this.STATE.currentState.set('WHERE', '');
40
40
  this.STATE.currentState.set('LIMIT', '');
41
41
  this.STATE.currentState.set('OFFSET', '');
42
+ this.STATE.currentState.set('SELECT', []);
43
+ this.STATE.currentState.set('GROUP_BY', '');
44
+ this.STATE.currentState.set('HAVING', '');
45
+ this.STATE.currentState.set('JOIN', '');
42
46
  this.STATE.currentState.set('SAVE', '');
43
47
  return;
44
48
  }
@@ -1,13 +1,16 @@
1
1
  declare const utils: {
2
+ typeOf: (data: any) => string;
3
+ isDate: (data: any) => boolean;
2
4
  consoleDebug: (debug?: string) => void;
3
5
  faker: (value: string) => string | number | boolean;
4
6
  columnRelation: (name: string) => string;
5
- timestamp: () => string;
7
+ timestamp: (dateString?: string) => string;
6
8
  date: () => string;
7
9
  escape: (str: any) => any;
8
10
  isSubQuery: (subQuery: string) => boolean;
9
11
  generateUUID: () => string;
10
12
  covertBooleanToNumber: (data: any) => any;
13
+ covertDataToDateIfDate: (data: Record<string, any>) => void;
11
14
  snakeCase: (data: any) => any;
12
15
  camelCase: (data: any) => any;
13
16
  randomString: (length?: number) => string;
@@ -10,8 +10,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.utils = void 0;
13
- const timestamp = () => {
14
- const d = new Date();
13
+ const typeOf = (data) => Object.prototype.toString.apply(data).slice(8, -1).toLocaleLowerCase();
14
+ const isDate = (data) => {
15
+ if (typeOf(data) === 'date')
16
+ return true;
17
+ return false;
18
+ };
19
+ const timestamp = (dateString) => {
20
+ const d = dateString == null ? new Date() : new Date(dateString);
15
21
  const year = d.getFullYear();
16
22
  const month = `0${(d.getMonth() + 1)}`.slice(-2);
17
23
  const date = `0${(d.getDate())}`.slice(-2);
@@ -75,6 +81,15 @@ const covertBooleanToNumber = (data) => {
75
81
  return +data;
76
82
  return data;
77
83
  };
84
+ const covertDataToDateIfDate = (data) => {
85
+ for (const key in data) {
86
+ const d = data[key];
87
+ if (!isDate(d))
88
+ continue;
89
+ data[key] = timestamp(d);
90
+ }
91
+ return;
92
+ };
78
93
  const snakeCase = (data) => {
79
94
  try {
80
95
  if (typeof (data) !== "object")
@@ -120,7 +135,9 @@ const camelCase = (data) => {
120
135
  const consoleDebug = (debug) => {
121
136
  if (debug == null)
122
137
  return;
123
- console.log(`\n\x1b[33m${debug.replace(/(\r\n|\n|\r|\t)/gm, "").trim()};\x1b[0m`);
138
+ if (typeof debug !== "string")
139
+ return;
140
+ console.log(`\n\x1b[33m${debug === null || debug === void 0 ? void 0 : debug.replace(/(\r\n|\n|\r|\t)/gm, "").trim()};\x1b[0m`);
124
141
  };
125
142
  const randomString = (length = 100) => {
126
143
  let str = '';
@@ -152,6 +169,12 @@ const faker = (value) => {
152
169
  return Number((Math.random() * 100).toFixed(2));
153
170
  if (!value.search('double'))
154
171
  return Number((Math.random() * 100).toFixed(2));
172
+ if (!value.search('json')) {
173
+ return JSON.stringify({
174
+ id: Number(Math.floor(Math.random() * 1000)),
175
+ name: randomString(50)
176
+ });
177
+ }
155
178
  if (!value.search('varchar')) {
156
179
  const regex = /\d+/g;
157
180
  const limit = Number((_b = (_a = value === null || value === void 0 ? void 0 : value.match(regex)) === null || _a === void 0 ? void 0 : _a.pop()) !== null && _b !== void 0 ? _b : 255);
@@ -165,6 +188,8 @@ const hookHandle = (hooks, result) => __awaiter(void 0, void 0, void 0, function
165
188
  return;
166
189
  });
167
190
  const utils = {
191
+ typeOf,
192
+ isDate,
168
193
  consoleDebug,
169
194
  faker,
170
195
  columnRelation,
@@ -174,6 +199,7 @@ const utils = {
174
199
  isSubQuery,
175
200
  generateUUID,
176
201
  covertBooleanToNumber,
202
+ covertDataToDateIfDate,
177
203
  snakeCase,
178
204
  camelCase,
179
205
  randomString,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tspace-mysql",
3
- "version": "1.4.6",
3
+ "version": "1.4.7",
4
4
  "description": "mysql query builder object relational mapping",
5
5
  "main": "dist/lib/index.js",
6
6
  "types": "dist/lib/index.d.ts",