@iamkirbki/database-handler-core 4.2.0 → 4.3.1
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 +14 -11
- package/dist/abstract/Model.d.ts.map +1 -1
- package/dist/abstract/Model.js +48 -7
- package/dist/base/Query.d.ts +10 -9
- package/dist/base/Query.d.ts.map +1 -1
- package/dist/base/Query.js +31 -14
- package/dist/base/Record.d.ts +7 -4
- package/dist/base/Record.d.ts.map +1 -1
- package/dist/base/Record.js +36 -13
- package/dist/base/Table.d.ts +13 -7
- package/dist/base/Table.d.ts.map +1 -1
- package/dist/base/Table.js +81 -31
- package/dist/helpers/QueryStatementBuilder.d.ts +12 -10
- package/dist/helpers/QueryStatementBuilder.d.ts.map +1 -1
- package/dist/helpers/QueryStatementBuilder.js +36 -14
- package/dist/interfaces/IDatabaseAdapter.d.ts +1 -0
- package/dist/interfaces/IDatabaseAdapter.d.ts.map +1 -1
- package/dist/interfaces/ISchemaBuilder.d.ts +1 -1
- package/dist/interfaces/ISchemaBuilder.d.ts.map +1 -1
- package/dist/runtime/Container.d.ts +2 -0
- package/dist/runtime/Container.d.ts.map +1 -1
- package/dist/runtime/Container.js +7 -0
- package/dist/runtime/Repository.d.ts +18 -8
- package/dist/runtime/Repository.d.ts.map +1 -1
- package/dist/runtime/Repository.js +97 -21
- package/dist/types/factories.d.ts +6 -0
- package/dist/types/factories.d.ts.map +1 -0
- package/dist/types/factories.js +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -0
- package/dist/types/model.d.ts +9 -4
- package/dist/types/model.d.ts.map +1 -1
- package/dist/types/query.d.ts +14 -6
- 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/abstract/Model.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Repository from "../runtime/Repository.js";
|
|
2
|
-
import { columnType,
|
|
2
|
+
import { columnType, QueryWhereCondition, QueryValues, ModelConfig, relation, ExtraQueryParameters, joinedEntity } from "../types/index.js";
|
|
3
3
|
/** Abstract Model class for ORM-style database interactions */
|
|
4
4
|
export default abstract class Model<ModelType extends columnType> {
|
|
5
5
|
private _repository?;
|
|
@@ -10,8 +10,8 @@ export default abstract class Model<ModelType extends columnType> {
|
|
|
10
10
|
protected attributes: Partial<ModelType>;
|
|
11
11
|
protected exists: boolean;
|
|
12
12
|
protected dirty: boolean;
|
|
13
|
-
protected queryScopes?:
|
|
14
|
-
protected queryOptions:
|
|
13
|
+
protected queryScopes?: QueryWhereCondition;
|
|
14
|
+
protected queryOptions: ExtraQueryParameters;
|
|
15
15
|
get primaryKeyColumn(): string;
|
|
16
16
|
get primaryKey(): QueryValues | undefined;
|
|
17
17
|
get values(): Partial<ModelType> | ModelType;
|
|
@@ -21,8 +21,8 @@ export default abstract class Model<ModelType extends columnType> {
|
|
|
21
21
|
offset(value: number): this;
|
|
22
22
|
static orderBy<ParamterModelType extends Model<columnType>>(this: new () => ParamterModelType, column: string, direction?: 'ASC' | 'DESC'): ParamterModelType;
|
|
23
23
|
orderBy(column: string, direction?: 'ASC' | 'DESC'): this;
|
|
24
|
-
static where<ParamterModelType extends Model<columnType>>(this: new () => ParamterModelType, conditions:
|
|
25
|
-
where(conditions:
|
|
24
|
+
static where<ParamterModelType extends Model<columnType>>(this: new () => ParamterModelType, conditions: QueryWhereCondition): ParamterModelType;
|
|
25
|
+
where(conditions: QueryWhereCondition): this;
|
|
26
26
|
static whereId<ParamterModelType extends Model<columnType>>(this: new () => ParamterModelType, id: QueryValues): ParamterModelType;
|
|
27
27
|
whereId(id: QueryValues): this;
|
|
28
28
|
static find<ParamterModelType extends Model<columnType>>(this: new () => ParamterModelType, primaryKeyValue: QueryValues): ParamterModelType;
|
|
@@ -42,12 +42,15 @@ export default abstract class Model<ModelType extends columnType> {
|
|
|
42
42
|
protected relations: relation[];
|
|
43
43
|
get JoinedEntities(): joinedEntity[];
|
|
44
44
|
get Relations(): relation[];
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
45
|
+
insertRecordIntoPivotTable(otherTable: string, foreignKey: string): Promise<void>;
|
|
46
|
+
protected ManyToMany<modelType extends Model<columnType>>(model: modelType, pivotTable?: string, localKey?: string, foreignKey?: string, pivotForeignKey?: string, pivotLocalKey?: string): Promise<this>;
|
|
47
|
+
protected hasMany<modelType extends Model<columnType>>(model: modelType, foreignKey?: string, localKey?: string): this;
|
|
48
|
+
protected hasOne<modelType extends Model<columnType>>(model: modelType, foreignKey?: string, localKey?: string): this;
|
|
49
|
+
protected belongsTo<modelType extends Model<columnType>>(model: modelType, foreignKey?: string, localKey?: string): this;
|
|
50
|
+
static with<ParamterModelType extends Model<columnType>>(this: new () => ParamterModelType, relation: string, queryScopes?: QueryWhereCondition): ParamterModelType;
|
|
51
|
+
with(relation: string, queryScopes?: QueryWhereCondition): this;
|
|
52
|
+
asyncWith(relation: string, queryScopes?: QueryWhereCondition): Promise<this>;
|
|
53
|
+
callRelationMethod(relation: string): void | Promise<void>;
|
|
51
54
|
private normalizeQueryScopes;
|
|
52
55
|
toJSON(): Partial<ModelType> | ModelType;
|
|
53
56
|
toObject(): Partial<ModelType> | ModelType;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Model.d.ts","sourceRoot":"","sources":["../../src/abstract/Model.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Model.d.ts","sourceRoot":"","sources":["../../src/abstract/Model.ts"],"names":[],"mappings":"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"}
|
package/dist/abstract/Model.js
CHANGED
|
@@ -7,7 +7,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import Query from "../base/Query.js";
|
|
11
10
|
import Repository from "../runtime/Repository.js";
|
|
12
11
|
/** Abstract Model class for ORM-style database interactions */
|
|
13
12
|
export default class Model {
|
|
@@ -32,7 +31,7 @@ export default class Model {
|
|
|
32
31
|
}
|
|
33
32
|
get repository() {
|
|
34
33
|
if (!this._repository) {
|
|
35
|
-
this._repository = Repository.getInstance(this.constructor, this.Configuration.table);
|
|
34
|
+
this._repository = Repository.getInstance(this.constructor, this.Configuration.table, this.Configuration.customAdapter);
|
|
36
35
|
}
|
|
37
36
|
return this._repository;
|
|
38
37
|
}
|
|
@@ -214,6 +213,29 @@ export default class Model {
|
|
|
214
213
|
get Relations() {
|
|
215
214
|
return this.relations;
|
|
216
215
|
}
|
|
216
|
+
insertRecordIntoPivotTable(otherTable, foreignKey) {
|
|
217
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
218
|
+
yield this.callRelationMethod(otherTable);
|
|
219
|
+
const relation = this.relations[this.relations.length - 1];
|
|
220
|
+
this.relations.pop();
|
|
221
|
+
yield this.repository.insertRecordIntoPivotTable(foreignKey, this, relation);
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
ManyToMany(model_1) {
|
|
225
|
+
return __awaiter(this, arguments, void 0, function* (model, pivotTable = [this.Configuration.table, model.Configuration.table].sort().join('_'), localKey = this.Configuration.primaryKey, foreignKey = model.Configuration.primaryKey, pivotForeignKey = `${this.Configuration.table}_${localKey}`, pivotLocalKey = `${model.Configuration.table}_${foreignKey}`) {
|
|
226
|
+
const relation = yield this.repository.getManyToManyRelation({
|
|
227
|
+
type: 'manyToMany',
|
|
228
|
+
model: model,
|
|
229
|
+
pivotTable: pivotTable,
|
|
230
|
+
foreignKey: foreignKey,
|
|
231
|
+
pivotForeignKey: pivotForeignKey,
|
|
232
|
+
localKey: localKey,
|
|
233
|
+
pivotLocalKey: pivotLocalKey,
|
|
234
|
+
});
|
|
235
|
+
this.relations.push(relation);
|
|
236
|
+
return this;
|
|
237
|
+
});
|
|
238
|
+
}
|
|
217
239
|
hasMany(model, foreignKey = `${this.Configuration.table}_${this.Configuration.primaryKey}`, localKey = this.Configuration.primaryKey) {
|
|
218
240
|
this.relations.push({
|
|
219
241
|
type: 'hasMany',
|
|
@@ -246,7 +268,10 @@ export default class Model {
|
|
|
246
268
|
return instance.with(relation, queryScopes);
|
|
247
269
|
}
|
|
248
270
|
with(relation, queryScopes) {
|
|
249
|
-
this.callRelationMethod(relation);
|
|
271
|
+
const result = this.callRelationMethod(relation);
|
|
272
|
+
if (result instanceof Promise) {
|
|
273
|
+
throw new Error(`Relation method '${relation}' is asynchronous. Use asyncWith() instead of with().`);
|
|
274
|
+
}
|
|
250
275
|
const lastRelation = this.relations[this.relations.length - 1];
|
|
251
276
|
const tableName = lastRelation.model.Configuration.table;
|
|
252
277
|
const normalizedScopes = this.normalizeQueryScopes(queryScopes, tableName);
|
|
@@ -256,12 +281,28 @@ export default class Model {
|
|
|
256
281
|
});
|
|
257
282
|
return this;
|
|
258
283
|
}
|
|
284
|
+
asyncWith(relation, queryScopes) {
|
|
285
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
286
|
+
yield this.callRelationMethod(relation);
|
|
287
|
+
const lastRelation = this.relations[this.relations.length - 1];
|
|
288
|
+
const tableName = lastRelation.model.Configuration.table;
|
|
289
|
+
const normalizedScopes = this.normalizeQueryScopes(queryScopes, tableName);
|
|
290
|
+
this.joinedEntities.push({
|
|
291
|
+
relation: relation,
|
|
292
|
+
queryScopes: normalizedScopes
|
|
293
|
+
});
|
|
294
|
+
return this;
|
|
295
|
+
});
|
|
296
|
+
}
|
|
259
297
|
callRelationMethod(relation) {
|
|
260
298
|
const method = Reflect.get(this, relation);
|
|
261
299
|
if (typeof method !== 'function') {
|
|
262
|
-
throw new Error(`Relation method '${relation}' does not exist
|
|
300
|
+
throw new Error(`Relation method '${relation}' does not exist`);
|
|
263
301
|
}
|
|
264
|
-
method.call(this);
|
|
302
|
+
const result = method.call(this);
|
|
303
|
+
//@TODO: check if method is not static
|
|
304
|
+
// Only return promise if the method is actually async
|
|
305
|
+
return result instanceof Promise ? result : undefined;
|
|
265
306
|
}
|
|
266
307
|
normalizeQueryScopes(queryScopes, tableName) {
|
|
267
308
|
if (!queryScopes) {
|
|
@@ -271,9 +312,9 @@ export default class Model {
|
|
|
271
312
|
'column' in queryScopes &&
|
|
272
313
|
'operator' in queryScopes &&
|
|
273
314
|
'value' in queryScopes;
|
|
274
|
-
|
|
315
|
+
const scopesArray = isSingleParameter
|
|
275
316
|
? [queryScopes]
|
|
276
|
-
:
|
|
317
|
+
: this.repository.ConvertParamsToArray(queryScopes);
|
|
277
318
|
return scopesArray.map(scope => (Object.assign(Object.assign({}, scope), { column: `${tableName}.${scope.column}` })));
|
|
278
319
|
}
|
|
279
320
|
toJSON() {
|
package/dist/base/Query.d.ts
CHANGED
|
@@ -1,26 +1,27 @@
|
|
|
1
|
-
import { columnType,
|
|
1
|
+
import { columnType, QueryWhereCondition, QueryIsEqualParameter, TableColumnInfo, QueryComparisonParameters, QueryConstructorType } from "../types/index.js";
|
|
2
2
|
import { Record } from "../index.js";
|
|
3
3
|
/** Query class for executing custom SQL queries */
|
|
4
4
|
export default class Query {
|
|
5
5
|
readonly TableName: string;
|
|
6
6
|
private readonly _adapter;
|
|
7
|
-
private _query
|
|
7
|
+
private _query?;
|
|
8
8
|
private _parameters;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
constructor(
|
|
9
|
+
private readonly _recordFactory;
|
|
10
|
+
get Parameters(): QueryWhereCondition;
|
|
11
|
+
constructor({ tableName, query, parameters, adapterName, recordFactory }: QueryConstructorType);
|
|
12
12
|
/** Execute a non-SELECT query (INSERT, UPDATE, DELETE, etc.) */
|
|
13
13
|
Run<Type>(): Promise<Type>;
|
|
14
14
|
/** Execute a SELECT query and return all matching rows */
|
|
15
15
|
All<Type extends columnType>(): Promise<Record<Type>[]>;
|
|
16
16
|
/** Execute a SELECT query and return the first matching row */
|
|
17
17
|
Get<Type extends columnType>(): Promise<Record<Type> | undefined>;
|
|
18
|
-
|
|
18
|
+
TableColumnInformation(tableName: string): Promise<TableColumnInfo[]>;
|
|
19
|
+
DoesTableExist(): Promise<boolean>;
|
|
19
20
|
Count(): Promise<number>;
|
|
20
|
-
|
|
21
|
+
ConvertParamsToArray(params: QueryWhereCondition): QueryComparisonParameters[];
|
|
21
22
|
/** Convert various parameter formats to a consistent object format */
|
|
22
|
-
|
|
23
|
+
ConvertParamsToObject(params: QueryWhereCondition): QueryIsEqualParameter;
|
|
23
24
|
/** Databases don't like numeric values when inserting with a query */
|
|
24
|
-
|
|
25
|
+
ConvertValueToString(params: QueryIsEqualParameter): QueryIsEqualParameter;
|
|
25
26
|
}
|
|
26
27
|
//# sourceMappingURL=Query.d.ts.map
|
package/dist/base/Query.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Query.d.ts","sourceRoot":"","sources":["../../src/base/Query.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"Query.d.ts","sourceRoot":"","sources":["../../src/base/Query.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,eAAe,EAAE,yBAAyB,EAAE,oBAAoB,EAAiB,MAAM,sBAAsB,CAAC;AAC/K,OAAO,EAAa,MAAM,EAAoB,MAAM,gBAAgB,CAAC;AAErE,mDAAmD;AACnD,MAAM,CAAC,OAAO,OAAO,KAAK;IACxB,SAAgB,SAAS,EAAE,MAAM,CAAC;IAElC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmB;IAC5C,OAAO,CAAC,MAAM,CAAC,CAAc;IAC7B,OAAO,CAAC,WAAW,CAA2B;IAC9C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAgB;IAE/C,IAAW,UAAU,IAAI,mBAAmB,CAE3C;gBAEW,EACV,SAAS,EACT,KAAK,EACL,UAAU,EACV,WAAW,EACX,aAA8E,EAC/E,EAAE,oBAAoB;IAWvB,gEAAgE;IACnD,GAAG,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC;IAQvC,0DAA0D;IAC7C,GAAG,CAAC,IAAI,SAAS,UAAU,KAAK,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;IAUpE,+DAA+D;IAClD,GAAG,CAAC,IAAI,SAAS,UAAU,KAAK,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC;IASjE,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAIrE,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;IAIlC,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IAS9B,oBAAoB,CAAC,MAAM,EAAE,mBAAmB,GAAG,yBAAyB,EAAE;IAkBrF,sEAAsE;IAC/D,qBAAqB,CAAC,MAAM,EAAE,mBAAmB,GAAG,qBAAqB;IAahF,sEAAsE;IAC/D,oBAAoB,CAAC,MAAM,EAAE,qBAAqB,GAAG,qBAAqB;CAKlF"}
|
package/dist/base/Query.js
CHANGED
|
@@ -13,19 +13,22 @@ export default class Query {
|
|
|
13
13
|
get Parameters() {
|
|
14
14
|
return this._parameters;
|
|
15
15
|
}
|
|
16
|
-
|
|
17
|
-
this._parameters = Query.ConvertParamsToObject(value);
|
|
18
|
-
}
|
|
19
|
-
constructor(TableName, Query) {
|
|
20
|
-
this._adapter = Container.getInstance().getAdapter();
|
|
16
|
+
constructor({ tableName, query, parameters, adapterName, recordFactory = (table, values, adapter) => new Record(table, values, adapter) }) {
|
|
21
17
|
this._query = "";
|
|
22
18
|
this._parameters = {};
|
|
23
|
-
this.TableName =
|
|
24
|
-
this._query =
|
|
19
|
+
this.TableName = tableName;
|
|
20
|
+
this._query = query;
|
|
21
|
+
if (parameters)
|
|
22
|
+
this._parameters = this.ConvertParamsToObject(parameters);
|
|
23
|
+
this._adapter = Container.getInstance().getAdapter(adapterName);
|
|
24
|
+
this._recordFactory = recordFactory;
|
|
25
25
|
}
|
|
26
26
|
/** Execute a non-SELECT query (INSERT, UPDATE, DELETE, etc.) */
|
|
27
27
|
Run() {
|
|
28
28
|
return __awaiter(this, void 0, void 0, function* () {
|
|
29
|
+
if (!this._query) {
|
|
30
|
+
throw new Error("No query defined to run.");
|
|
31
|
+
}
|
|
29
32
|
const stmt = yield this._adapter.prepare(this._query);
|
|
30
33
|
return yield stmt.run(this.Parameters);
|
|
31
34
|
});
|
|
@@ -33,32 +36,46 @@ export default class Query {
|
|
|
33
36
|
/** Execute a SELECT query and return all matching rows */
|
|
34
37
|
All() {
|
|
35
38
|
return __awaiter(this, void 0, void 0, function* () {
|
|
39
|
+
if (!this._query) {
|
|
40
|
+
throw new Error("No query defined to run.");
|
|
41
|
+
}
|
|
36
42
|
const stmt = yield this._adapter.prepare(this._query);
|
|
37
43
|
const results = yield stmt.all(this.Parameters);
|
|
38
|
-
return results.map(res =>
|
|
44
|
+
return results.map(res => this._recordFactory(this.TableName, res));
|
|
39
45
|
});
|
|
40
46
|
}
|
|
41
47
|
/** Execute a SELECT query and return the first matching row */
|
|
42
48
|
Get() {
|
|
43
49
|
return __awaiter(this, void 0, void 0, function* () {
|
|
50
|
+
if (!this._query) {
|
|
51
|
+
throw new Error("No query defined to run.");
|
|
52
|
+
}
|
|
44
53
|
const stmt = yield this._adapter.prepare(this._query);
|
|
45
54
|
const results = yield stmt.get(this.Parameters);
|
|
46
|
-
return results ?
|
|
55
|
+
return results ? this._recordFactory(this.TableName, results) : undefined;
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
TableColumnInformation(tableName) {
|
|
59
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
60
|
+
return this._adapter.tableColumnInformation(tableName);
|
|
47
61
|
});
|
|
48
62
|
}
|
|
49
|
-
|
|
63
|
+
DoesTableExist() {
|
|
50
64
|
return __awaiter(this, void 0, void 0, function* () {
|
|
51
|
-
return
|
|
65
|
+
return yield this._adapter.tableExists(this.TableName);
|
|
52
66
|
});
|
|
53
67
|
}
|
|
54
68
|
Count() {
|
|
55
69
|
return __awaiter(this, void 0, void 0, function* () {
|
|
70
|
+
if (!this._query) {
|
|
71
|
+
throw new Error("No query defined to run.");
|
|
72
|
+
}
|
|
56
73
|
const stmt = yield this._adapter.prepare(this._query);
|
|
57
74
|
const result = yield stmt.get(this.Parameters);
|
|
58
75
|
return parseInt(result.count) || 0;
|
|
59
76
|
});
|
|
60
77
|
}
|
|
61
|
-
|
|
78
|
+
ConvertParamsToArray(params) {
|
|
62
79
|
const paramArray = [];
|
|
63
80
|
if (Array.isArray(params)) {
|
|
64
81
|
return params;
|
|
@@ -75,7 +92,7 @@ export default class Query {
|
|
|
75
92
|
return paramArray;
|
|
76
93
|
}
|
|
77
94
|
/** Convert various parameter formats to a consistent object format */
|
|
78
|
-
|
|
95
|
+
ConvertParamsToObject(params) {
|
|
79
96
|
const paramObject = {};
|
|
80
97
|
if (Array.isArray(params)) {
|
|
81
98
|
params.forEach(param => {
|
|
@@ -88,7 +105,7 @@ export default class Query {
|
|
|
88
105
|
return this.ConvertValueToString(paramObject);
|
|
89
106
|
}
|
|
90
107
|
/** Databases don't like numeric values when inserting with a query */
|
|
91
|
-
|
|
108
|
+
ConvertValueToString(params) {
|
|
92
109
|
return Object.entries(params).map(([key, value]) => {
|
|
93
110
|
return { [key]: value !== null && !(value instanceof Date) && value !== undefined ? value.toString() : value };
|
|
94
111
|
}).reduce((acc, curr) => (Object.assign(Object.assign({}, acc), curr)), {});
|
package/dist/base/Record.d.ts
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import { inspect } from "util";
|
|
2
|
-
import { columnType,
|
|
2
|
+
import { columnType, QueryIsEqualParameter, QueryFactory, RecordFactory } from "../types/index.js";
|
|
3
3
|
/** Record class represents a single database row */
|
|
4
4
|
export default class Record<ColumnValuesType extends columnType> {
|
|
5
5
|
private _values;
|
|
6
6
|
private readonly _tableName;
|
|
7
|
-
|
|
7
|
+
private readonly _customAdapter?;
|
|
8
|
+
private readonly _queryFactory;
|
|
9
|
+
private readonly _recordFactory;
|
|
10
|
+
constructor(table: string, values: ColumnValuesType, adapter?: string, queryFactory?: QueryFactory, recordFactory?: RecordFactory);
|
|
8
11
|
/** Get the raw values object for this record */
|
|
9
12
|
get values(): ColumnValuesType;
|
|
10
13
|
Insert(): Promise<this | undefined>;
|
|
11
14
|
/** Update this record in the database */
|
|
12
|
-
Update(newValues: Partial<ColumnValuesType>,
|
|
15
|
+
Update(newValues: Partial<ColumnValuesType>, whereParameters: QueryIsEqualParameter): Promise<this>;
|
|
13
16
|
/** Delete this record from the database */
|
|
14
|
-
Delete(primaryKey
|
|
17
|
+
Delete(primaryKey?: QueryIsEqualParameter): Promise<void>;
|
|
15
18
|
/** Returns the values object for JSON.stringify() */
|
|
16
19
|
toJSON(): ColumnValuesType;
|
|
17
20
|
/** Convert record to pretty-printed JSON string */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Record.d.ts","sourceRoot":"","sources":["../../src/base/Record.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAE/B,OAAO,EAAE,UAAU,EAAoC,
|
|
1
|
+
{"version":3,"file":"Record.d.ts","sourceRoot":"","sources":["../../src/base/Record.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAE/B,OAAO,EAAE,UAAU,EAAoC,qBAAqB,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAGxI,oDAAoD;AACpD,MAAM,CAAC,OAAO,OAAO,MAAM,CAAC,gBAAgB,SAAS,UAAU;IAC3D,OAAO,CAAC,OAAO,CAA4C;IAC3D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAe;IAC7C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAgB;gBAG3C,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,gBAAgB,EACxB,OAAO,CAAC,EAAE,MAAM,EAChB,YAAY,GAAE,YAA4C,EAC1D,aAAa,GAAE,aAA8E;IASjG,gDAAgD;IAChD,IAAW,MAAM,IAAI,gBAAgB,CAEpC;IAEY,MAAM,IAAI,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC;IAiDhD,yCAAyC;IAC5B,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,gBAAgB,CAAC,EAAE,eAAe,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IA2BhH,2CAA2C;IAC9B,MAAM,CAAC,UAAU,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBtE,qDAAqD;IAC9C,MAAM,IAAI,gBAAgB;IAIjC,mDAAmD;IAC5C,QAAQ,IAAI,MAAM;IAIzB,uCAAuC;IACvC,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,gBAAgB;CAGvC"}
|
package/dist/base/Record.js
CHANGED
|
@@ -12,10 +12,13 @@ import Query from "./Query.js";
|
|
|
12
12
|
import QueryStatementBuilder from "../helpers/QueryStatementBuilder.js";
|
|
13
13
|
/** Record class represents a single database row */
|
|
14
14
|
export default class Record {
|
|
15
|
-
constructor(values, table) {
|
|
15
|
+
constructor(table, values, adapter, queryFactory = (config) => new Query(config), recordFactory = (table, values, adapter) => new Record(table, values, adapter)) {
|
|
16
16
|
this._values = {};
|
|
17
|
-
this._values = values;
|
|
18
17
|
this._tableName = table;
|
|
18
|
+
this._values = values;
|
|
19
|
+
this._customAdapter = adapter;
|
|
20
|
+
this._queryFactory = queryFactory;
|
|
21
|
+
this._recordFactory = recordFactory;
|
|
19
22
|
}
|
|
20
23
|
/** Get the raw values object for this record */
|
|
21
24
|
get values() {
|
|
@@ -30,8 +33,13 @@ export default class Record {
|
|
|
30
33
|
throw new Error("Cannot insert record with no columns");
|
|
31
34
|
}
|
|
32
35
|
const queryStr = QueryStatementBuilder.BuildInsert(this._tableName, this._values);
|
|
33
|
-
const query =
|
|
34
|
-
|
|
36
|
+
const query = this._queryFactory({
|
|
37
|
+
tableName: this._tableName,
|
|
38
|
+
query: queryStr,
|
|
39
|
+
parameters: this._values,
|
|
40
|
+
adapterName: this._customAdapter,
|
|
41
|
+
recordFactory: this._recordFactory
|
|
42
|
+
});
|
|
35
43
|
const result = yield query.Run();
|
|
36
44
|
let recordId;
|
|
37
45
|
// For PostgreSQL compatibility: use 'id' from values if lastInsertRowid is undefined
|
|
@@ -45,8 +53,13 @@ export default class Record {
|
|
|
45
53
|
return undefined;
|
|
46
54
|
}
|
|
47
55
|
const queryStrSelect = QueryStatementBuilder.BuildSelect(this._tableName, { where: Object.assign({}, this._values) });
|
|
48
|
-
const querySelect =
|
|
49
|
-
|
|
56
|
+
const querySelect = this._queryFactory({
|
|
57
|
+
tableName: this._tableName,
|
|
58
|
+
query: queryStrSelect,
|
|
59
|
+
parameters: this._values,
|
|
60
|
+
adapterName: this._customAdapter,
|
|
61
|
+
recordFactory: this._recordFactory
|
|
62
|
+
});
|
|
50
63
|
const insertedRecord = yield querySelect.All();
|
|
51
64
|
if (insertedRecord.length > 0) {
|
|
52
65
|
this._values = insertedRecord[insertedRecord.length - 1].values;
|
|
@@ -56,20 +69,25 @@ export default class Record {
|
|
|
56
69
|
});
|
|
57
70
|
}
|
|
58
71
|
/** Update this record in the database */
|
|
59
|
-
Update(newValues,
|
|
72
|
+
Update(newValues, whereParameters) {
|
|
60
73
|
return __awaiter(this, void 0, void 0, function* () {
|
|
61
74
|
const originalValues = this._values;
|
|
62
75
|
if (originalValues.updated_at !== undefined) {
|
|
63
76
|
newValues.updated_at = new Date().toISOString();
|
|
64
77
|
}
|
|
65
|
-
const queryStr = QueryStatementBuilder.BuildUpdate(this._tableName, newValues,
|
|
66
|
-
const _query = new Query(this._tableName, queryStr);
|
|
78
|
+
const queryStr = QueryStatementBuilder.BuildUpdate(this._tableName, newValues, whereParameters);
|
|
67
79
|
// Merge newValues and originalValues for parameters (with 'where_' prefix for where clause)
|
|
68
80
|
const params = Object.assign({}, newValues);
|
|
69
81
|
Object.entries(originalValues).forEach(([key, value]) => {
|
|
70
82
|
params[`where_${key}`] = value;
|
|
71
83
|
});
|
|
72
|
-
_query
|
|
84
|
+
const _query = this._queryFactory({
|
|
85
|
+
tableName: this._tableName,
|
|
86
|
+
query: queryStr,
|
|
87
|
+
parameters: params,
|
|
88
|
+
adapterName: this._customAdapter,
|
|
89
|
+
recordFactory: this._recordFactory
|
|
90
|
+
});
|
|
73
91
|
yield _query.Run();
|
|
74
92
|
this._values = Object.assign(Object.assign({}, this._values), newValues);
|
|
75
93
|
return this;
|
|
@@ -81,12 +99,17 @@ export default class Record {
|
|
|
81
99
|
const originalValues = this._values;
|
|
82
100
|
if (originalValues.deleted_at !== undefined) {
|
|
83
101
|
this._values.deleted_at = new Date().toISOString();
|
|
84
|
-
this.Update(this._values, primaryKey);
|
|
102
|
+
yield this.Update(this._values, this._values.id ? { id: this._values.id } : primaryKey || {});
|
|
85
103
|
return;
|
|
86
104
|
}
|
|
87
105
|
const queryStr = QueryStatementBuilder.BuildDelete(this._tableName, this._values);
|
|
88
|
-
const _query =
|
|
89
|
-
|
|
106
|
+
const _query = this._queryFactory({
|
|
107
|
+
tableName: this._tableName,
|
|
108
|
+
query: queryStr,
|
|
109
|
+
parameters: this.values,
|
|
110
|
+
adapterName: this._customAdapter,
|
|
111
|
+
recordFactory: this._recordFactory
|
|
112
|
+
});
|
|
90
113
|
yield _query.Run();
|
|
91
114
|
});
|
|
92
115
|
}
|
package/dist/base/Table.d.ts
CHANGED
|
@@ -1,25 +1,31 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Record } from "../index.js";
|
|
1
|
+
import { DefaultQueryParameters, Join, ExtraQueryParameters, ReadableTableColumnInfo, TableColumnInfo, columnType, QueryFactory, RecordFactory } from "../types/index.js";
|
|
2
|
+
import { Record, Query } from "../index.js";
|
|
3
3
|
/** Table class for interacting with a database table */
|
|
4
4
|
export default class Table {
|
|
5
|
+
private readonly _query;
|
|
6
|
+
private readonly _customAdapter?;
|
|
5
7
|
private readonly _name;
|
|
8
|
+
private readonly _queryFactory;
|
|
9
|
+
private readonly _recordFactory;
|
|
6
10
|
/** Private constructor - use Table.create() */
|
|
7
|
-
constructor(name: string);
|
|
11
|
+
constructor(name: string, customAdapter?: string, queryFactory?: QueryFactory, recordFactory?: RecordFactory);
|
|
12
|
+
get QueryHelperObject(): Query;
|
|
8
13
|
/** Get raw column information */
|
|
9
|
-
TableColumnInformation(): Promise<TableColumnInfo[]>;
|
|
14
|
+
TableColumnInformation(tableName?: string): Promise<TableColumnInfo[]>;
|
|
10
15
|
/** Get readable, formatted column information */
|
|
11
16
|
ReadableTableColumnInformation(): Promise<ReadableTableColumnInfo[]>;
|
|
12
17
|
Drop(): Promise<void>;
|
|
13
18
|
/** Fetch records with optional filtering, ordering, and pagination */
|
|
14
|
-
Records<Type extends columnType>(options?:
|
|
19
|
+
Records<Type extends columnType>(options?: DefaultQueryParameters & ExtraQueryParameters): Promise<Record<Type>[]>;
|
|
15
20
|
/** Fetch a single record from the table */
|
|
16
|
-
Record<Type extends columnType>(options?:
|
|
21
|
+
Record<Type extends columnType>(options?: DefaultQueryParameters & ExtraQueryParameters): Promise<Record<Type> | undefined>;
|
|
17
22
|
/** Get the total count of records */
|
|
18
23
|
RecordsCount(): Promise<number>;
|
|
24
|
+
exists(): Promise<boolean>;
|
|
19
25
|
/** Insert a record into the table */
|
|
20
26
|
Insert<Type extends columnType>(values: Type): Promise<Record<Type> | undefined>;
|
|
21
27
|
/** Perform JOIN operations with other tables */
|
|
22
|
-
Join<Type extends columnType>(Joins: Join | Join[], options?:
|
|
28
|
+
Join<Type extends columnType>(Joins: Join | Join[], options?: DefaultQueryParameters & ExtraQueryParameters): Promise<Record<Type>[]>;
|
|
23
29
|
private splitJoinValues;
|
|
24
30
|
}
|
|
25
31
|
//# sourceMappingURL=Table.d.ts.map
|
package/dist/base/Table.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Table.d.ts","sourceRoot":"","sources":["../../src/base/Table.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,
|
|
1
|
+
{"version":3,"file":"Table.d.ts","sourceRoot":"","sources":["../../src/base/Table.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,sBAAsB,EACtB,IAAI,EACJ,oBAAoB,EACpB,uBAAuB,EACvB,eAAe,EACf,UAAU,EACV,YAAY,EACZ,aAAa,EAChB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAE/C,wDAAwD;AACxD,MAAM,CAAC,OAAO,OAAO,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAe;IAC7C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAgB;IAE/C,+CAA+C;gBAE3C,IAAI,EAAE,MAAM,EACZ,aAAa,CAAC,EAAE,MAAM,EACtB,YAAY,GAAE,YAA4C,EAC1D,aAAa,GAAE,aAA8E;IAcjG,IAAW,iBAAiB,IAAI,KAAK,CAEpC;IAED,iCAAiC;IACpB,sBAAsB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAInF,iDAAiD;IACpC,8BAA8B,IAAI,OAAO,CAAC,uBAAuB,EAAE,CAAC;IAWpE,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAWlC,sEAAsE;IACzD,OAAO,CAAC,IAAI,SAAS,UAAU,EACxC,OAAO,CAAC,EAAE,sBAAsB,GAAG,oBAAoB,GACxD,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;IAuB1B,2CAA2C;IAC9B,MAAM,CAAC,IAAI,SAAS,UAAU,EACvC,OAAO,CAAC,EAAE,sBAAsB,GAAG,oBAAoB,GACxD,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC;IAWpC,qCAAqC;IACxB,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;IAU/B,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC;IAUvC,qCAAqC;IACxB,MAAM,CAAC,IAAI,SAAS,UAAU,EAAE,MAAM,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC;IAM7F,gDAAgD;IACnC,IAAI,CAAC,IAAI,SAAS,UAAU,EACrC,KAAK,EAAE,IAAI,GAAG,IAAI,EAAE,EACpB,OAAO,CAAC,EAAE,sBAAsB,GAAG,oBAAoB,GACxD,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;YAuBZ,eAAe;CAgChC"}
|