@iamkirbki/database-handler-core 4.1.6 → 4.3.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/dist/abstract/Model.d.ts +24 -19
- package/dist/abstract/Model.d.ts.map +1 -1
- package/dist/abstract/Model.js +110 -25
- package/dist/base/Query.d.ts +15 -9
- package/dist/base/Query.d.ts.map +1 -1
- package/dist/base/Query.js +28 -12
- package/dist/base/Record.d.ts +5 -4
- package/dist/base/Record.d.ts.map +1 -1
- package/dist/base/Record.js +35 -13
- package/dist/base/Table.d.ts +7 -5
- package/dist/base/Table.d.ts.map +1 -1
- package/dist/base/Table.js +64 -29
- package/dist/helpers/QueryStatementBuilder.d.ts +11 -10
- package/dist/helpers/QueryStatementBuilder.d.ts.map +1 -1
- package/dist/helpers/QueryStatementBuilder.js +37 -14
- package/dist/interfaces/IDatabaseAdapter.d.ts +1 -0
- package/dist/interfaces/IDatabaseAdapter.d.ts.map +1 -1
- package/dist/runtime/Repository.d.ts +15 -8
- package/dist/runtime/Repository.d.ts.map +1 -1
- package/dist/runtime/Repository.js +90 -31
- package/dist/types/model.d.ts +12 -6
- package/dist/types/model.d.ts.map +1 -1
- package/dist/types/query.d.ts +7 -7
- package/dist/types/query.d.ts.map +1 -1
- package/dist/types/table.d.ts +4 -3
- package/dist/types/table.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/base/Table.js
CHANGED
|
@@ -12,13 +12,14 @@ import { Record, Query } from "../index.js";
|
|
|
12
12
|
/** Table class for interacting with a database table */
|
|
13
13
|
export default class Table {
|
|
14
14
|
/** Private constructor - use Table.create() */
|
|
15
|
-
constructor(name) {
|
|
15
|
+
constructor(name, customAdapter) {
|
|
16
16
|
this._name = name;
|
|
17
|
+
this._customAdapter = customAdapter;
|
|
17
18
|
}
|
|
18
19
|
/** Get raw column information */
|
|
19
20
|
TableColumnInformation() {
|
|
20
21
|
return __awaiter(this, void 0, void 0, function* () {
|
|
21
|
-
return Query.
|
|
22
|
+
return Query.TableColumnInformation(this._name, this._customAdapter);
|
|
22
23
|
});
|
|
23
24
|
}
|
|
24
25
|
/** Get readable, formatted column information */
|
|
@@ -37,7 +38,11 @@ export default class Table {
|
|
|
37
38
|
Drop() {
|
|
38
39
|
return __awaiter(this, void 0, void 0, function* () {
|
|
39
40
|
const queryStr = `DROP TABLE IF EXISTS "${this._name}";`;
|
|
40
|
-
const query = new Query(
|
|
41
|
+
const query = new Query({
|
|
42
|
+
tableName: this._name,
|
|
43
|
+
query: queryStr,
|
|
44
|
+
adapterName: this._customAdapter
|
|
45
|
+
});
|
|
41
46
|
yield query.Run();
|
|
42
47
|
});
|
|
43
48
|
}
|
|
@@ -51,9 +56,14 @@ export default class Table {
|
|
|
51
56
|
limit: options === null || options === void 0 ? void 0 : options.limit,
|
|
52
57
|
offset: options === null || options === void 0 ? void 0 : options.offset,
|
|
53
58
|
});
|
|
54
|
-
|
|
59
|
+
let params = {};
|
|
55
60
|
if ((options === null || options === void 0 ? void 0 : options.where) && Object.keys(options.where).length > 0)
|
|
56
|
-
|
|
61
|
+
params = options.where;
|
|
62
|
+
const query = new Query({
|
|
63
|
+
tableName: this._name,
|
|
64
|
+
query: queryStr,
|
|
65
|
+
parameters: params
|
|
66
|
+
});
|
|
57
67
|
const results = yield query.All();
|
|
58
68
|
return results;
|
|
59
69
|
});
|
|
@@ -73,15 +83,27 @@ export default class Table {
|
|
|
73
83
|
/** Get the total count of records */
|
|
74
84
|
RecordsCount() {
|
|
75
85
|
return __awaiter(this, void 0, void 0, function* () {
|
|
76
|
-
const query = new Query(
|
|
86
|
+
const query = new Query({
|
|
87
|
+
tableName: this._name,
|
|
88
|
+
query: `SELECT COUNT(*) as count FROM "${this._name}"`
|
|
89
|
+
});
|
|
77
90
|
const count = yield query.Count();
|
|
78
91
|
return count || 0;
|
|
79
92
|
});
|
|
80
93
|
}
|
|
94
|
+
exists() {
|
|
95
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
96
|
+
const query = new Query({
|
|
97
|
+
tableName: this._name,
|
|
98
|
+
adapterName: this._customAdapter
|
|
99
|
+
});
|
|
100
|
+
return yield query.DoesTableExist();
|
|
101
|
+
});
|
|
102
|
+
}
|
|
81
103
|
/** Insert a record into the table */
|
|
82
104
|
Insert(values) {
|
|
83
105
|
return __awaiter(this, void 0, void 0, function* () {
|
|
84
|
-
const record = new Record(
|
|
106
|
+
const record = new Record(this._name, values);
|
|
85
107
|
yield record.Insert();
|
|
86
108
|
return record;
|
|
87
109
|
});
|
|
@@ -89,38 +111,51 @@ export default class Table {
|
|
|
89
111
|
/** Perform JOIN operations with other tables */
|
|
90
112
|
Join(Joins, options) {
|
|
91
113
|
return __awaiter(this, void 0, void 0, function* () {
|
|
92
|
-
const queryString = QueryStatementBuilder.BuildJoin(this._name, Joins, options);
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
114
|
+
const queryString = yield QueryStatementBuilder.BuildJoin(this._name, Joins, options);
|
|
115
|
+
let params = {};
|
|
116
|
+
if (options === null || options === void 0 ? void 0 : options.where)
|
|
117
|
+
params = options.where;
|
|
118
|
+
const query = new Query({
|
|
119
|
+
tableName: this._name,
|
|
120
|
+
query: queryString,
|
|
121
|
+
parameters: params
|
|
122
|
+
});
|
|
98
123
|
const joinedTables = Array.isArray(Joins) ? Joins.map(j => j.fromTable) : [Joins.fromTable];
|
|
124
|
+
if (options) {
|
|
125
|
+
options.select = joinedTables.map(table => `${table}.*`).join(', ');
|
|
126
|
+
}
|
|
99
127
|
const records = yield query.All();
|
|
100
|
-
|
|
128
|
+
const splitTables = yield this.splitJoinValues(records, joinedTables);
|
|
129
|
+
return splitTables;
|
|
101
130
|
});
|
|
102
131
|
}
|
|
103
132
|
splitJoinValues(records, joinedTables) {
|
|
104
133
|
return __awaiter(this, void 0, void 0, function* () {
|
|
105
|
-
const thisRecordColumns = (yield this.TableColumnInformation()).map(col => col.name);
|
|
106
|
-
const tableColumnsMap = new Map();
|
|
107
|
-
for (const tableName of joinedTables) {
|
|
108
|
-
const columns = (yield Query.tableColumnInformation(tableName)).map(col => col.name);
|
|
109
|
-
tableColumnsMap.set(tableName, columns);
|
|
110
|
-
}
|
|
111
134
|
return records.map(record => {
|
|
112
135
|
if (!record.values)
|
|
113
136
|
return record;
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
137
|
+
const mainTableData = {};
|
|
138
|
+
const joinedTableData = {};
|
|
139
|
+
for (const tableName of joinedTables) {
|
|
140
|
+
joinedTableData[tableName] = {};
|
|
141
|
+
}
|
|
142
|
+
for (const [aliasedKey, value] of Object.entries(record.values)) {
|
|
143
|
+
if (aliasedKey.includes('__')) {
|
|
144
|
+
const [tableName, columnName] = aliasedKey.split('__');
|
|
145
|
+
if (tableName === this._name) {
|
|
146
|
+
mainTableData[columnName] = value;
|
|
147
|
+
}
|
|
148
|
+
else if (joinedTables.includes(tableName)) {
|
|
149
|
+
joinedTableData[tableName][columnName] = value;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
mainTableData[aliasedKey] = value;
|
|
154
|
+
}
|
|
122
155
|
}
|
|
123
|
-
|
|
156
|
+
// Combine main table data with nested joined table data
|
|
157
|
+
const combinedData = Object.assign(Object.assign({}, mainTableData), joinedTableData);
|
|
158
|
+
return new Record(this._name, combinedData);
|
|
124
159
|
});
|
|
125
160
|
});
|
|
126
161
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DefaultQueryParameters, ExtraQueryParameters, QueryWhereCondition, Join, QueryIsEqualParameter } from "../types/index.js";
|
|
2
2
|
/** Utility class for building SQL query strings */
|
|
3
3
|
export default class QueryStatementBuilder {
|
|
4
4
|
/**
|
|
@@ -25,7 +25,7 @@ export default class QueryStatementBuilder {
|
|
|
25
25
|
* // "SELECT id, name, email FROM users WHERE status = @status AND age = @age ORDER BY created_at DESC LIMIT 10 OFFSET 20"
|
|
26
26
|
* ```
|
|
27
27
|
*/
|
|
28
|
-
static BuildSelect(tableName: string, options?:
|
|
28
|
+
static BuildSelect(tableName: string, options?: DefaultQueryParameters & ExtraQueryParameters): string;
|
|
29
29
|
/**
|
|
30
30
|
* Build an INSERT SQL statement with named parameter placeholders
|
|
31
31
|
*
|
|
@@ -45,7 +45,7 @@ export default class QueryStatementBuilder {
|
|
|
45
45
|
* // Note: The actual values will be bound separately using the Parameters object
|
|
46
46
|
* ```
|
|
47
47
|
*/
|
|
48
|
-
static BuildInsert(tableName: string, record:
|
|
48
|
+
static BuildInsert(tableName: string, record: QueryIsEqualParameter): string;
|
|
49
49
|
/**
|
|
50
50
|
* Build an UPDATE SQL statement with SET clause and WHERE conditions
|
|
51
51
|
*
|
|
@@ -72,7 +72,7 @@ export default class QueryStatementBuilder {
|
|
|
72
72
|
* // "UPDATE users SET status = @status WHERE status = @status AND last_login = @last_login"
|
|
73
73
|
* ```
|
|
74
74
|
*/
|
|
75
|
-
static BuildUpdate(tableName: string, record:
|
|
75
|
+
static BuildUpdate(tableName: string, record: QueryWhereCondition, where: QueryWhereCondition): string;
|
|
76
76
|
/**
|
|
77
77
|
* Build a DELETE SQL statement with WHERE conditions
|
|
78
78
|
*
|
|
@@ -93,7 +93,7 @@ export default class QueryStatementBuilder {
|
|
|
93
93
|
* // "DELETE FROM users WHERE status = @status AND last_login = @last_login"
|
|
94
94
|
* ```
|
|
95
95
|
*/
|
|
96
|
-
static BuildDelete(tableName: string, where:
|
|
96
|
+
static BuildDelete(tableName: string, where: QueryWhereCondition): string;
|
|
97
97
|
/**
|
|
98
98
|
* Build a COUNT SQL statement to count rows, optionally with WHERE conditions
|
|
99
99
|
*
|
|
@@ -115,7 +115,7 @@ export default class QueryStatementBuilder {
|
|
|
115
115
|
* // "SELECT COUNT(*) as count FROM users WHERE status = @status AND age = @age"
|
|
116
116
|
* ```
|
|
117
117
|
*/
|
|
118
|
-
static BuildCount(tableName: string, where?:
|
|
118
|
+
static BuildCount(tableName: string, where?: QueryWhereCondition): string;
|
|
119
119
|
/**
|
|
120
120
|
* Build a WHERE clause from parameter conditions (helper method)
|
|
121
121
|
*
|
|
@@ -144,7 +144,7 @@ export default class QueryStatementBuilder {
|
|
|
144
144
|
* // ""
|
|
145
145
|
* ```
|
|
146
146
|
*/
|
|
147
|
-
static BuildWhere(where?:
|
|
147
|
+
static BuildWhere(where?: QueryWhereCondition): string;
|
|
148
148
|
private static buildWhereWithOperators;
|
|
149
149
|
private static buildWhereSimple;
|
|
150
150
|
/**
|
|
@@ -191,7 +191,8 @@ export default class QueryStatementBuilder {
|
|
|
191
191
|
* );
|
|
192
192
|
* ```
|
|
193
193
|
*/
|
|
194
|
-
static BuildJoin(fromTableName: string, joins: Join | Join[], options?:
|
|
194
|
+
static BuildJoin(fromTableName: string, joins: Join | Join[], options?: DefaultQueryParameters & ExtraQueryParameters): Promise<string>;
|
|
195
|
+
static BuildJoinSelect(fromTableName: string, joins: Join | Join[]): Promise<string>;
|
|
195
196
|
/**
|
|
196
197
|
* Build JOIN clause(s) recursively (helper method)
|
|
197
198
|
*
|
|
@@ -264,7 +265,7 @@ export default class QueryStatementBuilder {
|
|
|
264
265
|
* // "ON users.id = orders.user_id AND users.company_id = orders.company_id"
|
|
265
266
|
* ```
|
|
266
267
|
*/
|
|
267
|
-
static BuildJoinOnPart(tableName: string, joinTableName: string, on:
|
|
268
|
+
static BuildJoinOnPart(tableName: string, joinTableName: string, on: QueryIsEqualParameter | QueryIsEqualParameter[]): string;
|
|
268
269
|
/**
|
|
269
270
|
* Build query options clause (ORDER BY, LIMIT, OFFSET) (helper method)
|
|
270
271
|
*
|
|
@@ -298,6 +299,6 @@ export default class QueryStatementBuilder {
|
|
|
298
299
|
* // "LIMIT 25 OFFSET 50"
|
|
299
300
|
* ```
|
|
300
301
|
*/
|
|
301
|
-
static BuildQueryOptions(options:
|
|
302
|
+
static BuildQueryOptions(options: ExtraQueryParameters): string;
|
|
302
303
|
}
|
|
303
304
|
//# sourceMappingURL=QueryStatementBuilder.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QueryStatementBuilder.d.ts","sourceRoot":"","sources":["../../src/helpers/QueryStatementBuilder.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"QueryStatementBuilder.d.ts","sourceRoot":"","sources":["../../src/helpers/QueryStatementBuilder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,IAAI,EAA6B,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAEjK,mDAAmD;AACnD,MAAM,CAAC,OAAO,OAAO,qBAAqB;IACtC;;;;;;;;;;;;;;;;;;;;;;;OAuBG;WACW,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,sBAAsB,GAAG,oBAAoB,GAAG,MAAM;IAW7G;;;;;;;;;;;;;;;;;;OAkBG;WACW,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,qBAAqB,GAAG,MAAM;IAYnF;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;WACW,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,mBAAmB,EAAE,KAAK,EAAE,mBAAmB,GAAG,MAAM;IAW7G;;;;;;;;;;;;;;;;;;;OAmBG;WACW,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,mBAAmB,GAAG,MAAM;IAShF;;;;;;;;;;;;;;;;;;;;OAoBG;WACW,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,mBAAmB,GAAG,MAAM;IAQhF;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;WACW,UAAU,CAAC,KAAK,CAAC,EAAE,mBAAmB,GAAG,MAAM;IAgB7D,OAAO,CAAC,MAAM,CAAC,uBAAuB;IAStC,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAK/B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2CG;WACiB,SAAS,CACzB,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,IAAI,GAAG,IAAI,EAAE,EACpB,OAAO,CAAC,EAAE,sBAAsB,GAAG,oBAAoB,GACxD,OAAO,CAAC,MAAM,CAAC;WAaE,eAAe,CAC/B,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,IAAI,GAAG,IAAI,EAAE,GACrB,OAAO,CAAC,MAAM,CAAC;IAmBlB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAsCG;WACW,aAAa,CACvB,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,IAAI,GAAG,IAAI,EAAE,GACrB,MAAM;IAaT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA+BG;WACW,eAAe,CACzB,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,EACrB,EAAE,EAAE,qBAAqB,GAAG,qBAAqB,EAAE,GACpD,MAAM;IAWT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgCG;WACW,iBAAiB,CAAC,OAAO,EAAE,oBAAoB,GAAG,MAAM;CAiBzE"}
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { Query } from "../index.js";
|
|
1
11
|
/** Utility class for building SQL query strings */
|
|
2
12
|
export default class QueryStatementBuilder {
|
|
3
13
|
/**
|
|
@@ -92,7 +102,7 @@ export default class QueryStatementBuilder {
|
|
|
92
102
|
const setClauses = Object.keys(record).map(col => `${col} = @${col}`);
|
|
93
103
|
queryParts.push(`UPDATE "${tableName}"`);
|
|
94
104
|
queryParts.push(`SET ${setClauses.join(", ")}`);
|
|
95
|
-
queryParts.push(this.BuildWhere(where));
|
|
105
|
+
queryParts.push(this.BuildWhere(where).replace(/@(\w+)/g, '@where_$1'));
|
|
96
106
|
return queryParts.join(" ");
|
|
97
107
|
}
|
|
98
108
|
/**
|
|
@@ -246,14 +256,28 @@ export default class QueryStatementBuilder {
|
|
|
246
256
|
* ```
|
|
247
257
|
*/
|
|
248
258
|
static BuildJoin(fromTableName, joins, options) {
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
259
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
260
|
+
const queryParts = [];
|
|
261
|
+
const selectClause = yield QueryStatementBuilder.BuildJoinSelect(fromTableName, joins);
|
|
262
|
+
queryParts.push(`SELECT ${selectClause}`);
|
|
263
|
+
queryParts.push(`FROM "${fromTableName}"`);
|
|
264
|
+
queryParts.push(this.BuildJoinPart(fromTableName, joins));
|
|
265
|
+
queryParts.push(this.BuildWhere(options === null || options === void 0 ? void 0 : options.where));
|
|
266
|
+
queryParts.push(this.BuildQueryOptions(options !== null && options !== void 0 ? options : {}));
|
|
267
|
+
return queryParts.join(" ");
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
static BuildJoinSelect(fromTableName, joins) {
|
|
271
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
272
|
+
const mainTableCols = yield Query.TableColumnInformation(fromTableName);
|
|
273
|
+
const mainTableSelect = mainTableCols.map(col => `"${fromTableName}"."${col.name}" AS "${fromTableName}__${col.name}"`).join(', ');
|
|
274
|
+
const joinArray = Array.isArray(joins) ? joins : [joins];
|
|
275
|
+
const joinedSelects = yield Promise.all(joinArray.map((join) => __awaiter(this, void 0, void 0, function* () {
|
|
276
|
+
const cols = yield Query.TableColumnInformation(join.fromTable);
|
|
277
|
+
return cols.map(col => `"${join.fromTable}"."${col.name}" AS "${join.fromTable}__${col.name}"`).join(', ');
|
|
278
|
+
})));
|
|
279
|
+
return [mainTableSelect, ...joinedSelects].join(', ');
|
|
280
|
+
});
|
|
257
281
|
}
|
|
258
282
|
/**
|
|
259
283
|
* Build JOIN clause(s) recursively (helper method)
|
|
@@ -296,12 +320,11 @@ export default class QueryStatementBuilder {
|
|
|
296
320
|
*/
|
|
297
321
|
static BuildJoinPart(fromTableName, joins) {
|
|
298
322
|
const queryParts = [];
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
323
|
+
joins = Array.isArray(joins) ? joins : [joins];
|
|
324
|
+
for (const join of joins) {
|
|
325
|
+
const baseTable = join.baseTable || fromTableName; // Use explicit base or default
|
|
302
326
|
queryParts.push(`${join.joinType} JOIN "${join.fromTable}"`);
|
|
303
|
-
queryParts.push(this.BuildJoinOnPart(
|
|
304
|
-
currentTableName = join.fromTable;
|
|
327
|
+
queryParts.push(this.BuildJoinOnPart(baseTable, join.fromTable, join.on));
|
|
305
328
|
}
|
|
306
329
|
return queryParts.join(" ");
|
|
307
330
|
}
|
|
@@ -6,6 +6,7 @@ export default interface IDatabaseAdapter {
|
|
|
6
6
|
exec(query: string): Promise<void>;
|
|
7
7
|
transaction(fn: (items: any[]) => void): Promise<Function>;
|
|
8
8
|
tableColumnInformation(tableName: string): Promise<TableColumnInfo[]>;
|
|
9
|
+
tableExists(tableName: string): Promise<boolean>;
|
|
9
10
|
close(): Promise<void>;
|
|
10
11
|
}
|
|
11
12
|
//# sourceMappingURL=IDatabaseAdapter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IDatabaseAdapter.d.ts","sourceRoot":"","sources":["../../src/interfaces/IDatabaseAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,iBAAiB,MAAM,wBAAwB,CAAC;AAEvD,MAAM,CAAC,OAAO,WAAW,gBAAgB;IACrC,OAAO,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACnD,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,WAAW,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC3D,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IACtE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B"}
|
|
1
|
+
{"version":3,"file":"IDatabaseAdapter.d.ts","sourceRoot":"","sources":["../../src/interfaces/IDatabaseAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,iBAAiB,MAAM,wBAAwB,CAAC;AAEvD,MAAM,CAAC,OAAO,WAAW,gBAAgB;IACrC,OAAO,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACnD,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,WAAW,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC3D,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IACtE,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACjD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B"}
|
|
@@ -1,19 +1,26 @@
|
|
|
1
1
|
import type Model from "../abstract/Model.js";
|
|
2
|
-
import
|
|
2
|
+
import Record from "../base/Record.js";
|
|
3
|
+
import { columnType, QueryWhereCondition, ExtraQueryParameters, relation, QueryIsEqualParameter } from "../types/index.js";
|
|
3
4
|
export default class Repository<Type extends columnType, ModelType extends Model<Type>> {
|
|
4
5
|
private static _instances;
|
|
5
6
|
private models;
|
|
7
|
+
private manyToManyRelations;
|
|
6
8
|
private Table;
|
|
7
|
-
constructor(tableName: string, ModelClass: ModelType);
|
|
8
|
-
static getInstance<ModelType extends columnType>(ModelClass: new () => Model<ModelType>, tableName: string): Repository<ModelType, Model<ModelType>>;
|
|
9
|
+
constructor(tableName: string, ModelClass: ModelType, customDatabaseAdapter?: string);
|
|
10
|
+
static getInstance<ModelType extends columnType>(ModelClass: new () => Model<ModelType>, tableName: string, customDatabaseAdapter?: string): Repository<ModelType, Model<ModelType>>;
|
|
11
|
+
private generatePivotTableKeys;
|
|
12
|
+
insertRecordIntoPivotTable(foreignKey: string, modelOfOrigin: ModelType, relation: relation): Promise<void>;
|
|
13
|
+
deleteRecordFromPivotTable(foreignKey: string, modelOfOrigin: ModelType, relation: relation): Promise<void>;
|
|
14
|
+
getManyToManyRelation(relation: relation): Promise<relation | undefined>;
|
|
15
|
+
doesTableExist(name: string): Promise<boolean>;
|
|
9
16
|
syncModel(model: ModelType): void;
|
|
10
17
|
getModel(name: string): ModelType;
|
|
11
18
|
save(attributes: Type): Promise<void>;
|
|
12
|
-
first(conditions:
|
|
13
|
-
get(conditions:
|
|
14
|
-
all(Model: Model<Type>, queryscopes?:
|
|
15
|
-
update(
|
|
19
|
+
first(conditions: QueryWhereCondition, Model: Model<Type>): Promise<Type | null>;
|
|
20
|
+
get(conditions: QueryWhereCondition, queryOptions: ExtraQueryParameters, Model: Model<Type>): Promise<Type[]>;
|
|
21
|
+
all(Model: Model<Type>, queryscopes?: QueryWhereCondition, queryOptions?: ExtraQueryParameters): Promise<Type[]>;
|
|
22
|
+
update(primaryKey: QueryIsEqualParameter, newAttributes: Partial<Type>): Promise<Record<Type> | undefined>;
|
|
16
23
|
private join;
|
|
17
|
-
private
|
|
24
|
+
private mergeQueryWhereConditions;
|
|
18
25
|
}
|
|
19
26
|
//# sourceMappingURL=Repository.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Repository.d.ts","sourceRoot":"","sources":["../../src/runtime/Repository.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"Repository.d.ts","sourceRoot":"","sources":["../../src/runtime/Repository.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,yBAAyB,CAAC;AACjD,OAAO,MAAM,MAAM,sBAAsB,CAAC;AAG1C,OAAO,EAAE,UAAU,EAAQ,mBAAmB,EAAE,oBAAoB,EAAE,QAAQ,EAA6B,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE/J,MAAM,CAAC,OAAO,OAAO,UAAU,CAAC,IAAI,SAAS,UAAU,EAAE,SAAS,SAAS,KAAK,CAAC,IAAI,CAAC;IAClF,OAAO,CAAC,MAAM,CAAC,UAAU,CAAqE;IAC9F,OAAO,CAAC,MAAM,CAAqC;IACnD,OAAO,CAAC,mBAAmB,CAAoC;IAC/D,OAAO,CAAC,KAAK,CAAO;gBAER,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,qBAAqB,CAAC,EAAE,MAAM;WAMtE,WAAW,CAAC,SAAS,SAAS,UAAU,EAClD,UAAU,EAAE,UAAU,KAAK,CAAC,SAAS,CAAC,EACtC,SAAS,EAAE,MAAM,EACjB,qBAAqB,CAAC,EAAE,MAAM,GAC/B,UAAU,CAAC,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAW1C,OAAO,CAAC,sBAAsB;IAajB,0BAA0B,CACnC,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,SAAS,EACxB,QAAQ,EAAE,QAAQ,GACnB,OAAO,CAAC,IAAI,CAAC;IAKH,0BAA0B,CACnC,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,SAAS,EACxB,QAAQ,EAAE,QAAQ,GACnB,OAAO,CAAC,IAAI,CAAC;IAMH,qBAAqB,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC;IAaxE,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKpD,SAAS,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI;IAKjC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS;IAI3B,IAAI,CAAC,UAAU,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrC,KAAK,CAAC,UAAU,EAAE,mBAAmB,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAYhF,GAAG,CAAC,UAAU,EAAE,mBAAmB,EAAE,YAAY,EAAE,oBAAoB,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAS7G,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC,EAAE,mBAAmB,EAAE,YAAY,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAShH,MAAM,CAAC,UAAU,EAAE,qBAAqB,EAAE,aAAa,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC;YAOzG,IAAI;IAgDlB,OAAO,CAAC,yBAAyB;CAGpC"}
|
|
@@ -10,22 +10,64 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
import Query from "../base/Query.js";
|
|
11
11
|
import Table from "../base/Table.js";
|
|
12
12
|
class Repository {
|
|
13
|
-
constructor(tableName, ModelClass) {
|
|
13
|
+
constructor(tableName, ModelClass, customDatabaseAdapter) {
|
|
14
14
|
var _a;
|
|
15
15
|
this.models = new Map();
|
|
16
|
+
this.manyToManyRelations = new Map();
|
|
16
17
|
const modelPk = ((_a = ModelClass.primaryKey) === null || _a === void 0 ? void 0 : _a.toString()) || ModelClass.constructor.name;
|
|
17
18
|
this.models.set(modelPk, ModelClass);
|
|
18
|
-
this.Table = new Table(tableName);
|
|
19
|
+
this.Table = new Table(tableName, customDatabaseAdapter);
|
|
19
20
|
}
|
|
20
|
-
static getInstance(ModelClass, tableName) {
|
|
21
|
+
static getInstance(ModelClass, tableName, customDatabaseAdapter) {
|
|
21
22
|
const className = ModelClass.name;
|
|
22
23
|
if (!this._instances.has(className)) {
|
|
23
|
-
const instance = new Repository(tableName, new ModelClass());
|
|
24
|
+
const instance = new Repository(tableName, new ModelClass(), customDatabaseAdapter);
|
|
24
25
|
this._instances.set(className, instance);
|
|
25
26
|
return instance;
|
|
26
27
|
}
|
|
27
28
|
return this._instances.get(className);
|
|
28
29
|
}
|
|
30
|
+
generatePivotTableKeys(foreignKey, modelOfOrigin, relation) {
|
|
31
|
+
var _a;
|
|
32
|
+
const isLocal = !((_a = relation.pivotLocalKey) === null || _a === void 0 ? void 0 : _a.includes(modelOfOrigin.Configuration.table));
|
|
33
|
+
return {
|
|
34
|
+
[relation.pivotLocalKey]: isLocal ? foreignKey : modelOfOrigin.values[relation.foreignKey],
|
|
35
|
+
[relation.pivotForeignKey]: isLocal ? modelOfOrigin.values[relation.foreignKey] : foreignKey
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
insertRecordIntoPivotTable(foreignKey, modelOfOrigin, relation) {
|
|
39
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
40
|
+
const table = new Table(relation.pivotTable);
|
|
41
|
+
yield table.Insert(this.generatePivotTableKeys(foreignKey, modelOfOrigin, relation));
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
deleteRecordFromPivotTable(foreignKey, modelOfOrigin, relation) {
|
|
45
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
46
|
+
const table = new Table(relation.pivotTable);
|
|
47
|
+
const record = yield table.Record(this.generatePivotTableKeys(foreignKey, modelOfOrigin, relation));
|
|
48
|
+
yield (record === null || record === void 0 ? void 0 : record.Delete());
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
getManyToManyRelation(relation) {
|
|
52
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
53
|
+
if (relation.pivotTable && this.manyToManyRelations.has(relation.pivotTable)) {
|
|
54
|
+
return this.manyToManyRelations.get(relation.pivotTable);
|
|
55
|
+
}
|
|
56
|
+
if (yield this.doesTableExist(relation.pivotTable)) {
|
|
57
|
+
this.manyToManyRelations.set(relation.pivotTable, relation);
|
|
58
|
+
return relation;
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
throw new Error(`Pivot table ${relation.pivotTable} does not exist. Create it in alphabetical order before using many-to-many relationships.`);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
doesTableExist(name) {
|
|
66
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
67
|
+
const table = new Table(name);
|
|
68
|
+
return yield table.exists();
|
|
69
|
+
});
|
|
70
|
+
}
|
|
29
71
|
syncModel(model) {
|
|
30
72
|
var _a;
|
|
31
73
|
const modelPk = ((_a = model.primaryKey) === null || _a === void 0 ? void 0 : _a.toString()) || model.constructor.name;
|
|
@@ -43,7 +85,8 @@ class Repository {
|
|
|
43
85
|
return __awaiter(this, void 0, void 0, function* () {
|
|
44
86
|
let record;
|
|
45
87
|
if (Model.JoinedEntities.length > 0) {
|
|
46
|
-
|
|
88
|
+
const results = yield this.join(Model, conditions, { limit: 1 });
|
|
89
|
+
record = results[0] ? { values: results[0] } : undefined;
|
|
47
90
|
}
|
|
48
91
|
else {
|
|
49
92
|
record = yield this.Table.Record({ where: conditions });
|
|
@@ -57,7 +100,8 @@ class Repository {
|
|
|
57
100
|
return yield this.join(Model, conditions, queryOptions);
|
|
58
101
|
}
|
|
59
102
|
else {
|
|
60
|
-
|
|
103
|
+
const records = yield this.Table.Records(Object.assign({ where: conditions }, queryOptions));
|
|
104
|
+
return records.map(record => record.values);
|
|
61
105
|
}
|
|
62
106
|
});
|
|
63
107
|
}
|
|
@@ -67,49 +111,64 @@ class Repository {
|
|
|
67
111
|
return yield this.join(Model);
|
|
68
112
|
}
|
|
69
113
|
else {
|
|
70
|
-
|
|
114
|
+
const records = yield this.Table.Records(Object.assign({ where: queryscopes }, queryOptions));
|
|
115
|
+
return records.map(record => record.values);
|
|
71
116
|
}
|
|
72
117
|
});
|
|
73
118
|
}
|
|
74
|
-
update(
|
|
119
|
+
update(primaryKey, newAttributes) {
|
|
75
120
|
return __awaiter(this, void 0, void 0, function* () {
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
const record = yield this.Table.Record({ where: { [primaryKey]: pkValue } });
|
|
80
|
-
if (record) {
|
|
81
|
-
yield record.Update(attributes);
|
|
82
|
-
}
|
|
121
|
+
const record = yield this.Table.Record({ where: primaryKey });
|
|
122
|
+
if (record) {
|
|
123
|
+
return yield record.Update(newAttributes, primaryKey);
|
|
83
124
|
}
|
|
84
|
-
else {
|
|
85
|
-
throw new Error("Primary key value is required for update.");
|
|
86
|
-
}
|
|
87
|
-
return this;
|
|
88
125
|
});
|
|
89
126
|
}
|
|
90
127
|
join(Model, conditions, queryOptions) {
|
|
91
128
|
return __awaiter(this, void 0, void 0, function* () {
|
|
92
|
-
const Join = Model.JoinedEntities.
|
|
93
|
-
const relation = Model.Relations.find(rel => rel.model.Configuration.table.toLowerCase() === join.relation.toLowerCase());
|
|
129
|
+
const Join = Model.JoinedEntities.flatMap(join => {
|
|
130
|
+
const relation = Model.Relations.find(rel => rel.model.Configuration.table.replace("_", "").toLowerCase() === join.relation.toLowerCase());
|
|
94
131
|
if (join.queryScopes) {
|
|
95
|
-
conditions = this.
|
|
132
|
+
conditions = this.mergeQueryWhereConditions(conditions || {}, join.queryScopes);
|
|
96
133
|
}
|
|
97
134
|
if (!relation) {
|
|
98
135
|
throw new Error(`Relation for joined entity ${join} not found.`);
|
|
99
136
|
}
|
|
137
|
+
if (relation.type === 'manyToMany') {
|
|
138
|
+
return [
|
|
139
|
+
{
|
|
140
|
+
fromTable: relation.pivotTable,
|
|
141
|
+
baseTable: Model.Configuration.table,
|
|
142
|
+
joinType: 'INNER',
|
|
143
|
+
on: [
|
|
144
|
+
{ [relation.pivotForeignKey]: relation.localKey }
|
|
145
|
+
]
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
fromTable: relation.model.Configuration.table,
|
|
149
|
+
baseTable: relation.pivotTable,
|
|
150
|
+
joinType: 'INNER',
|
|
151
|
+
on: [
|
|
152
|
+
{ [relation.foreignKey]: relation.pivotLocalKey }
|
|
153
|
+
]
|
|
154
|
+
}
|
|
155
|
+
];
|
|
156
|
+
}
|
|
100
157
|
const JoinType = relation.type === 'hasOne' || relation.type === 'belongsTo' ? 'INNER' : 'LEFT';
|
|
101
|
-
return {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
158
|
+
return [{
|
|
159
|
+
fromTable: relation.model.Configuration.table,
|
|
160
|
+
baseTable: Model.Configuration.table,
|
|
161
|
+
joinType: JoinType,
|
|
162
|
+
on: [
|
|
163
|
+
{ [relation.foreignKey]: relation.localKey }
|
|
164
|
+
]
|
|
165
|
+
}];
|
|
108
166
|
});
|
|
109
|
-
|
|
167
|
+
const records = yield this.Table.Join(Join, Object.assign({ where: conditions }, queryOptions));
|
|
168
|
+
return records.map(record => record.values);
|
|
110
169
|
});
|
|
111
170
|
}
|
|
112
|
-
|
|
171
|
+
mergeQueryWhereConditions(base, additional) {
|
|
113
172
|
return [...Query.ConvertParamsToArray(base), ...Query.ConvertParamsToArray(additional)];
|
|
114
173
|
}
|
|
115
174
|
}
|
package/dist/types/model.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** Model configuration and types */
|
|
2
2
|
import Model from "../abstract/Model";
|
|
3
|
-
import { columnType,
|
|
3
|
+
import { columnType, QueryWhereCondition } from "./index";
|
|
4
4
|
export type ModelEventType = 'retrieved' | 'creating' | 'created' | 'updating' | 'updated' | 'saving' | 'saved' | 'deleting' | 'deleted' | 'restoring' | 'restored' | 'forceDeleting' | 'forceDeleted';
|
|
5
5
|
export type ModelEventHandler<T> = (model: T) => void | Promise<void>;
|
|
6
6
|
export interface ModelObserver<T> {
|
|
@@ -24,6 +24,8 @@ export interface ModelScope {
|
|
|
24
24
|
export interface ModelConfig {
|
|
25
25
|
/** Table name - defaults to lowercase class name */
|
|
26
26
|
table: string;
|
|
27
|
+
/** Custom adapter name - defaults to default name */
|
|
28
|
+
customAdapter?: string;
|
|
27
29
|
/** Primary key column - defaults to 'id' */
|
|
28
30
|
primaryKey: string;
|
|
29
31
|
/** Whether to auto-increment primary key - defaults to true */
|
|
@@ -56,20 +58,24 @@ export interface ModelConfig {
|
|
|
56
58
|
dateFormat?: string;
|
|
57
59
|
}
|
|
58
60
|
export type relation = {
|
|
59
|
-
type: 'hasOne' | 'hasMany' | 'belongsTo';
|
|
61
|
+
type: 'hasOne' | 'hasMany' | 'belongsTo' | 'manyToMany';
|
|
60
62
|
model: unknown & Model<columnType>;
|
|
61
63
|
foreignKey: string;
|
|
62
|
-
localKey
|
|
64
|
+
localKey: string;
|
|
65
|
+
pivotTable?: string;
|
|
66
|
+
pivotForeignKey?: string;
|
|
67
|
+
pivotLocalKey?: string;
|
|
63
68
|
};
|
|
64
69
|
export interface SoftDeletable {
|
|
65
70
|
deleted_at?: string | Date | null;
|
|
66
71
|
}
|
|
67
72
|
export type ModelWithTimestamps = {
|
|
68
|
-
created_at?: string;
|
|
69
|
-
updated_at?: string;
|
|
73
|
+
created_at?: string | number | Date;
|
|
74
|
+
updated_at?: string | number | Date;
|
|
75
|
+
deleted_at?: string | number | Date;
|
|
70
76
|
};
|
|
71
77
|
export type joinedEntity = {
|
|
72
78
|
relation: string;
|
|
73
|
-
queryScopes?:
|
|
79
|
+
queryScopes?: QueryWhereCondition;
|
|
74
80
|
};
|
|
75
81
|
//# sourceMappingURL=model.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/types/model.ts"],"names":[],"mappings":"AAAA,oCAAoC;AAEpC,OAAO,KAAK,MAAM,sBAAsB,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/types/model.ts"],"names":[],"mappings":"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"}
|