sedentary 0.0.23 → 0.0.24
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/db.d.ts +14 -3
- package/db.js +21 -0
- package/index.d.ts +25 -12
- package/index.js +135 -20
- package/package.json +6 -6
package/db.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export declare type Natural = Date | Record<string, unknown> | boolean | number | string;
|
|
1
|
+
export declare type Natural = Date | Record<string, unknown> | boolean | number | string | null;
|
|
2
2
|
export declare class EntryBase {
|
|
3
|
-
constructor(from?: Partial<EntryBase>
|
|
3
|
+
constructor(from?: Partial<EntryBase>);
|
|
4
4
|
construct(): void;
|
|
5
5
|
postLoad(): void;
|
|
6
6
|
postSave(): void;
|
|
@@ -57,7 +57,11 @@ interface ITable {
|
|
|
57
57
|
autoIncrement: boolean;
|
|
58
58
|
constraints: Constraint[];
|
|
59
59
|
indexes: Index[];
|
|
60
|
+
model: {
|
|
61
|
+
load: (where: any, order?: string[], tx?: Transaction) => Promise<EntryBase[]>;
|
|
62
|
+
};
|
|
60
63
|
parent?: Attribute<Natural, unknown>;
|
|
64
|
+
pk: Attribute<Natural, unknown>;
|
|
61
65
|
sync: boolean;
|
|
62
66
|
tableName: string;
|
|
63
67
|
}
|
|
@@ -78,8 +82,10 @@ export declare abstract class DB {
|
|
|
78
82
|
protected indexesEq(a: Index, b: Index): boolean;
|
|
79
83
|
syncDataBase(): Promise<void>;
|
|
80
84
|
protected syncLog(message: string): void;
|
|
85
|
+
begin(): Promise<Transaction>;
|
|
81
86
|
abstract escape(value: Natural): string;
|
|
82
|
-
abstract
|
|
87
|
+
abstract load(tableName: string, attributes: Record<string, string>, pk: Attribute<Natural, unknown>, model: new () => EntryBase, table: Table): (where: string, order?: string[], tx?: Transaction) => Promise<EntryBase[]>;
|
|
88
|
+
abstract save(tableName: string, attributes: Record<string, string>, pk: Attribute<Natural, unknown>): (this: EntryBase & Record<string, Natural>) => Promise<boolean>;
|
|
83
89
|
abstract dropConstraints(table: Table): Promise<number[]>;
|
|
84
90
|
abstract dropFields(table: Table): Promise<void>;
|
|
85
91
|
abstract dropIndexes(table: Table, constraintIndexes: number[]): Promise<void>;
|
|
@@ -90,5 +96,10 @@ export declare abstract class DB {
|
|
|
90
96
|
abstract syncTable(table: Table): Promise<void>;
|
|
91
97
|
}
|
|
92
98
|
export declare class Transaction {
|
|
99
|
+
private entries;
|
|
100
|
+
addEntry(entry: EntryBase): void;
|
|
101
|
+
clean(): void;
|
|
102
|
+
commit(): Promise<void>;
|
|
103
|
+
rollback(): Promise<void>;
|
|
93
104
|
}
|
|
94
105
|
export {};
|
package/db.js
CHANGED
|
@@ -83,8 +83,29 @@ class DB {
|
|
|
83
83
|
syncLog(message) {
|
|
84
84
|
this.log(this.sync ? message : "NOT SYNCING: " + message);
|
|
85
85
|
}
|
|
86
|
+
async begin() {
|
|
87
|
+
return new Transaction();
|
|
88
|
+
}
|
|
86
89
|
}
|
|
87
90
|
exports.DB = DB;
|
|
88
91
|
class Transaction {
|
|
92
|
+
constructor() {
|
|
93
|
+
this.entries = [];
|
|
94
|
+
}
|
|
95
|
+
addEntry(entry) {
|
|
96
|
+
this.entries.push(entry);
|
|
97
|
+
}
|
|
98
|
+
clean() {
|
|
99
|
+
const { entries } = this;
|
|
100
|
+
for (const entry of entries)
|
|
101
|
+
delete entry.tx;
|
|
102
|
+
this.entries = [];
|
|
103
|
+
}
|
|
104
|
+
async commit() {
|
|
105
|
+
this.clean();
|
|
106
|
+
}
|
|
107
|
+
async rollback() {
|
|
108
|
+
this.clean();
|
|
109
|
+
}
|
|
89
110
|
}
|
|
90
111
|
exports.Transaction = Transaction;
|
package/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Attribute, DB, EntryBase, ForeignKeyOptions, Natural, Type } from "./db";
|
|
2
|
-
export { EntryBase, ForeignKeyActions, ForeignKeyOptions, Natural, Type } from "./db";
|
|
1
|
+
import { Attribute, DB, EntryBase, ForeignKeyOptions, Natural, Transaction, Type } from "./db";
|
|
2
|
+
export { EntryBase, ForeignKeyActions, ForeignKeyOptions, Natural, Transaction, Type } from "./db";
|
|
3
3
|
export declare type TypeDefinition<N extends Natural, E> = (() => Type<N, E>) | Type<N, E>;
|
|
4
4
|
export interface AttributeOptions<N extends Natural, E> {
|
|
5
5
|
defaultValue?: N;
|
|
@@ -16,7 +16,7 @@ declare type ForeignKeysAttributes<T, k> = T extends AttributeDefinition<Natural
|
|
|
16
16
|
declare type ForeignKeys<A extends AttributesDefinition> = {
|
|
17
17
|
[a in keyof A]?: ForeignKeysAttributes<A[a], a>;
|
|
18
18
|
}[keyof A];
|
|
19
|
-
declare type Native__<T> = T extends Type<infer N, unknown> ? N : never;
|
|
19
|
+
declare type Native__<T> = T extends Type<infer N, unknown> ? N | null : never;
|
|
20
20
|
declare type Native_<T> = T extends () => Type<infer N, infer E> ? Native__<Type<N, E>> : Native__<T>;
|
|
21
21
|
declare type Native<T> = T extends AttributeOptions<infer N, infer E> ? Native__<Type<N, E>> : Native_<T>;
|
|
22
22
|
export declare type IndexAttributes = string[] | string;
|
|
@@ -39,11 +39,12 @@ export interface ModelOptions extends BaseModelOptions {
|
|
|
39
39
|
parent?: Attribute<Natural, EntryBase>;
|
|
40
40
|
primaryKey?: string;
|
|
41
41
|
}
|
|
42
|
-
declare type ConditionAttribute<N extends Natural> = N | [">" | "<" | ">=" | "<=" | "<>", N] | ["IN",
|
|
42
|
+
declare type ConditionAttribute<N extends Natural> = N | ["=" | ">" | "<" | ">=" | "<=" | "<>", N] | ["IN", N[]] | ["IS NULL"] | ["LIKE", string] | ["NOT"];
|
|
43
43
|
declare type ConditionBase<A extends AttributesDefinition> = string | {
|
|
44
44
|
[a in keyof A]?: ConditionAttribute<Native<A[a]>>;
|
|
45
45
|
};
|
|
46
46
|
declare type Condition<A extends AttributesDefinition> = ConditionBase<A> | ["NOT", Condition<A>] | ["AND", ...Condition<A>[]] | ["OR", ...Condition<A>[]];
|
|
47
|
+
declare type Order<A extends AttributesDefinition> = (keyof A | `-${string & keyof A}`)[];
|
|
47
48
|
declare type UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
|
|
48
49
|
declare type IsUnion<T> = [T] extends [UnionToIntersection<T>] ? false : true;
|
|
49
50
|
declare type BaseKeyType<B extends boolean> = IsUnion<B> extends true ? number : B extends true ? string : number;
|
|
@@ -61,16 +62,19 @@ declare type ModelAttributesIf<A extends AttributesDefinition, T> = keyof A exte
|
|
|
61
62
|
declare type ModelAttributes<A extends AttributesDefinition, B extends boolean, K extends string, P extends ModelStd> = K extends keyof A ? A : ModelAttributesIf<A, P extends new () => EntryBase ? P["attributes"] : {
|
|
62
63
|
id: Type<BaseKeyType<B>, unknown>;
|
|
63
64
|
}>;
|
|
64
|
-
|
|
65
|
+
interface ModelLoad<A extends AttributesDefinition, E extends EntryBase> {
|
|
65
66
|
attributes: A;
|
|
67
|
+
load(where: Condition<A>, order?: Order<A>, tx?: Transaction): Promise<E[]>;
|
|
68
|
+
load(where: Condition<A>, tx: Transaction): Promise<E[]>;
|
|
69
|
+
}
|
|
70
|
+
declare type ModelBase<N extends Natural, A extends AttributesDefinition, EA extends Record<string, Natural | undefined>, EM extends EntryBase, E extends EntryBase> = (new (from?: EA) => E) & Attribute<N, E> & {
|
|
66
71
|
foreignKeys: Record<string, boolean>;
|
|
67
72
|
methods: EM;
|
|
68
73
|
parent?: ModelStd;
|
|
69
74
|
tableName: string;
|
|
70
|
-
load: (where?: Condition<A>) => Promise<E[]>;
|
|
71
75
|
} & {
|
|
72
76
|
[a in keyof A]: Attribute<Native<A[a]>, E>;
|
|
73
|
-
}
|
|
77
|
+
} & ModelLoad<A, E>;
|
|
74
78
|
declare type Model<N extends Natural, A extends AttributesDefinition, EM extends EntryBase> = ModelBase<N, A, EntryBaseAttributes<A>, EM, EntryBaseAttributes<A> & EM>;
|
|
75
79
|
declare type ModelStd = Attribute<Natural, EntryBase> & {
|
|
76
80
|
attributes: AttributesDefinition;
|
|
@@ -79,9 +83,14 @@ declare type ModelStd = Attribute<Natural, EntryBase> & {
|
|
|
79
83
|
parent?: ModelStd;
|
|
80
84
|
};
|
|
81
85
|
export declare type Entry<M> = M extends new () => infer E ? E : never;
|
|
82
|
-
export declare type
|
|
83
|
-
load
|
|
86
|
+
export declare type OrderBy<M> = M extends {
|
|
87
|
+
load(where: unknown, order?: infer T, tx?: Transaction): void;
|
|
88
|
+
load(where: unknown, tx?: Transaction): void;
|
|
84
89
|
} ? Exclude<T, undefined> : never;
|
|
90
|
+
export declare type Where<M> = M extends {
|
|
91
|
+
load(where: infer T, order?: unknown, tx?: Transaction): void;
|
|
92
|
+
load(where: unknown, tx?: Transaction): void;
|
|
93
|
+
} ? T : never;
|
|
85
94
|
export interface SedentaryOptions {
|
|
86
95
|
autoSync?: boolean;
|
|
87
96
|
log?: ((message: string) => void) | null;
|
|
@@ -90,8 +99,8 @@ export interface SedentaryOptions {
|
|
|
90
99
|
export declare class Sedentary {
|
|
91
100
|
protected autoSync: boolean;
|
|
92
101
|
protected db: DB;
|
|
102
|
+
protected doSync: boolean;
|
|
93
103
|
protected log: (...data: unknown[]) => void;
|
|
94
|
-
protected sync: boolean;
|
|
95
104
|
private models;
|
|
96
105
|
constructor(options?: SedentaryOptions);
|
|
97
106
|
DATETIME(): Type<Date, unknown>;
|
|
@@ -99,10 +108,14 @@ export declare class Sedentary {
|
|
|
99
108
|
INT(size?: number): Type<number, unknown>;
|
|
100
109
|
INT8(): Type<string, unknown>;
|
|
101
110
|
VARCHAR(size?: number): Type<string, unknown>;
|
|
102
|
-
checkDB
|
|
103
|
-
|
|
111
|
+
private checkDB;
|
|
112
|
+
private checkOrderBy;
|
|
113
|
+
private checkSize;
|
|
114
|
+
private createWhere;
|
|
104
115
|
connect(sync?: boolean): Promise<void>;
|
|
116
|
+
sync(): Promise<void>;
|
|
105
117
|
end(): Promise<void>;
|
|
118
|
+
begin(): Promise<Transaction>;
|
|
106
119
|
escape(value: Natural): string;
|
|
107
120
|
model<A extends AttributesDefinition, B extends boolean, K extends string, P extends ModelStd, EM extends EntryMethods<A, P>>(modelName: string, attributes: A, options?: BaseModelOptions & {
|
|
108
121
|
int8id?: B;
|
package/index.js
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Sedentary = exports.Type = exports.EntryBase = void 0;
|
|
3
|
+
exports.Sedentary = exports.Type = exports.Transaction = exports.EntryBase = void 0;
|
|
4
4
|
const db_1 = require("./db");
|
|
5
5
|
var db_2 = require("./db");
|
|
6
6
|
Object.defineProperty(exports, "EntryBase", { enumerable: true, get: function () { return db_2.EntryBase; } });
|
|
7
|
+
Object.defineProperty(exports, "Transaction", { enumerable: true, get: function () { return db_2.Transaction; } });
|
|
7
8
|
Object.defineProperty(exports, "Type", { enumerable: true, get: function () { return db_2.Type; } });
|
|
9
|
+
const operators = ["=", ">", "<", ">=", "<=", "<>", "IN", "IS NULL", "LIKE", "NOT"];
|
|
8
10
|
const allowedOption = ["indexes", "int8id", "parent", "primaryKey", "sync", "tableName"];
|
|
9
11
|
const reservedNames = [
|
|
10
|
-
...["attributeName", "attributes", "base", "class", "construct", "constructor", "defaultValue", "entry", "fieldName", "foreignKeys", "load"],
|
|
12
|
+
...["attr2field", "attributeName", "attributes", "base", "class", "construct", "constructor", "defaultValue", "entry", "fieldName", "foreignKeys", "load"],
|
|
11
13
|
...["loaded", "methods", "name", "postLoad", "postSave", "preLoad", "preSave", "primaryKey", "prototype", "save", "size", "tableName", "tx", "type"]
|
|
12
14
|
];
|
|
13
15
|
class Sedentary {
|
|
14
16
|
constructor(options) {
|
|
15
|
-
this.
|
|
17
|
+
this.doSync = true;
|
|
16
18
|
this.models = {};
|
|
17
19
|
if (!options)
|
|
18
20
|
options = {};
|
|
@@ -32,7 +34,7 @@ class Sedentary {
|
|
|
32
34
|
this.db = null;
|
|
33
35
|
// eslint-disable-next-line no-console
|
|
34
36
|
this.log = log ? log : log === null ? () => { } : console.log;
|
|
35
|
-
this.
|
|
37
|
+
this.doSync = sync;
|
|
36
38
|
}
|
|
37
39
|
DATETIME() {
|
|
38
40
|
return new db_1.Type({ base: Date, type: "DATETIME" });
|
|
@@ -60,6 +62,24 @@ class Sedentary {
|
|
|
60
62
|
if (!this.db)
|
|
61
63
|
throw new Error("Package sedentary can't be used directly. Please check: https://www.npmjs.com/package/sedentary#disclaimer");
|
|
62
64
|
}
|
|
65
|
+
checkOrderBy(order, attributes, modelName) {
|
|
66
|
+
if (!order)
|
|
67
|
+
return true;
|
|
68
|
+
if (!(order instanceof Array))
|
|
69
|
+
return false;
|
|
70
|
+
const provided = {};
|
|
71
|
+
for (const attribute of order) {
|
|
72
|
+
if (typeof attribute !== "string")
|
|
73
|
+
return false;
|
|
74
|
+
const attributeName = attribute.startsWith("-") ? attribute.substring(1) : attribute;
|
|
75
|
+
if (!(attributeName in attributes))
|
|
76
|
+
throw new Error(`${modelName}.load: 'order' argument: '${attributeName}' is not an attribute name`);
|
|
77
|
+
if (provided[attributeName])
|
|
78
|
+
throw new Error(`${modelName}.load: 'order' argument: Reused '${attributeName}' attribute`);
|
|
79
|
+
provided[attributeName] = true;
|
|
80
|
+
}
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
63
83
|
checkSize(size, message) {
|
|
64
84
|
const str = size.toString();
|
|
65
85
|
const parsed = parseInt(str, 10);
|
|
@@ -67,28 +87,103 @@ class Sedentary {
|
|
|
67
87
|
throw new Error(message);
|
|
68
88
|
return parsed;
|
|
69
89
|
}
|
|
90
|
+
createWhere(modelName, attributes, where) {
|
|
91
|
+
if (typeof where === "string")
|
|
92
|
+
return [where, true, true];
|
|
93
|
+
if (typeof where !== "object")
|
|
94
|
+
throw new Error(`${modelName}.load: 'where' argument: Wrong type, expected 'Array', 'Object' or 'string'`);
|
|
95
|
+
if (!where)
|
|
96
|
+
return ["", false, false];
|
|
97
|
+
if (where instanceof Array) {
|
|
98
|
+
const length = where.length;
|
|
99
|
+
if (!length)
|
|
100
|
+
throw new Error(`${modelName}.load: 'where' argument: Empty Array`);
|
|
101
|
+
if (!["AND", "NOT", "OR"].includes(where[0]))
|
|
102
|
+
throw new Error(`${modelName}.load: 'where' argument: Wrong logical operator, expected 'AND', 'OR' or 'NOT'`);
|
|
103
|
+
if (length === 1)
|
|
104
|
+
return ["", false, false];
|
|
105
|
+
if (where[0] === "NOT") {
|
|
106
|
+
if (length > 2)
|
|
107
|
+
throw new Error(`${modelName}.load: 'where' argument: 'NOT' operator is unary`);
|
|
108
|
+
const [res] = this.createWhere(modelName, attributes, where[1]);
|
|
109
|
+
return [res === "" ? "" : `NOT (${res})`, false, false];
|
|
110
|
+
}
|
|
111
|
+
const conditions = where
|
|
112
|
+
.filter((_, i) => i)
|
|
113
|
+
.map(_ => this.createWhere(modelName, attributes, _))
|
|
114
|
+
.filter(([_]) => _);
|
|
115
|
+
if (conditions.length === 1)
|
|
116
|
+
return conditions[0];
|
|
117
|
+
const isOr = where[0] === "OR";
|
|
118
|
+
return [isOr ? conditions.map(([_, , a]) => (a ? `(${_})` : _)).join(" OR ") : conditions.map(([_, o]) => (o ? `(${_})` : _)).join(" AND "), isOr, false];
|
|
119
|
+
}
|
|
120
|
+
const conditions = [];
|
|
121
|
+
for (const key in where) {
|
|
122
|
+
const field = attributes[key];
|
|
123
|
+
if (!field)
|
|
124
|
+
throw new Error(`${modelName}.load: 'where' argument: Unknown '${key}' attribute`);
|
|
125
|
+
const value = where[key];
|
|
126
|
+
if (value instanceof Array) {
|
|
127
|
+
const operator = value[0];
|
|
128
|
+
const length = value.length;
|
|
129
|
+
if (!length)
|
|
130
|
+
throw new Error(`${modelName}.load: 'where' argument: Missing arithmetic operator, expected one of: ${operators.map(_ => `'${_}'`).join(", ")}`);
|
|
131
|
+
if (!operators.includes(operator))
|
|
132
|
+
throw new Error(`${modelName}.load: 'where' argument: Wrong arithmetic operator, expected one of: ${operators.map(_ => `'${_}'`).join(", ")}`);
|
|
133
|
+
if (operator === "IS NULL") {
|
|
134
|
+
if (length !== 1)
|
|
135
|
+
throw new Error(`${modelName}.load: 'where' argument: 'IS NULL' operator is unary`);
|
|
136
|
+
conditions.push(`${field} IS NULL`);
|
|
137
|
+
}
|
|
138
|
+
else if (operator === "NOT") {
|
|
139
|
+
if (length !== 1)
|
|
140
|
+
throw new Error(`${modelName}.load: 'where' argument: 'NOT' operator is unary`);
|
|
141
|
+
conditions.push(`NOT ${field}`);
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
if (length !== 2)
|
|
145
|
+
throw new Error(`${modelName}.load: 'where' argument: '${operator}' operator is binary`);
|
|
146
|
+
if (operator === "IN") {
|
|
147
|
+
if (!(value[1] instanceof Array))
|
|
148
|
+
throw new Error(`${modelName}.load: 'where' argument: 'IN' right operand: Wrong type, expected Array`);
|
|
149
|
+
conditions.push(`${field} IN (${value[1].map(_ => this.escape(_)).join(", ")})`);
|
|
150
|
+
}
|
|
151
|
+
else
|
|
152
|
+
conditions.push(`${field} ${operator} ${this.escape(value[1])}`);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
else
|
|
156
|
+
conditions.push(`${field} = ${this.escape(value)}`);
|
|
157
|
+
}
|
|
158
|
+
return [conditions.length ? conditions.join(" AND ") : "", false, false];
|
|
159
|
+
}
|
|
70
160
|
async connect(sync) {
|
|
71
161
|
try {
|
|
72
162
|
this.checkDB();
|
|
73
163
|
this.log("Connecting...");
|
|
74
164
|
await this.db.connect();
|
|
75
165
|
this.log("Connected");
|
|
76
|
-
if (this.autoSync || sync)
|
|
77
|
-
this.
|
|
78
|
-
await this.db.syncDataBase();
|
|
79
|
-
this.log("Synced");
|
|
80
|
-
}
|
|
166
|
+
if (this.autoSync || sync)
|
|
167
|
+
await this.sync();
|
|
81
168
|
}
|
|
82
169
|
catch (e) {
|
|
83
170
|
this.log("Connecting: " + (e instanceof Error ? e.message : JSON.stringify(e)));
|
|
84
171
|
throw e;
|
|
85
172
|
}
|
|
86
173
|
}
|
|
174
|
+
async sync() {
|
|
175
|
+
this.log("Syncing...");
|
|
176
|
+
await this.db.syncDataBase();
|
|
177
|
+
this.log("Synced");
|
|
178
|
+
}
|
|
87
179
|
async end() {
|
|
88
180
|
this.log("Closing connection...");
|
|
89
181
|
await this.db.end();
|
|
90
182
|
this.log("Connection closed");
|
|
91
183
|
}
|
|
184
|
+
async begin() {
|
|
185
|
+
return this.db.begin();
|
|
186
|
+
}
|
|
92
187
|
escape(value) {
|
|
93
188
|
return this.db.escape(value);
|
|
94
189
|
}
|
|
@@ -117,13 +212,14 @@ class Sedentary {
|
|
|
117
212
|
if (options.parent && options.primaryKey)
|
|
118
213
|
throw new Error(`Sedentary.model: '${modelName}' model: 'parent' and 'primaryKey' options conflict each other`);
|
|
119
214
|
let autoIncrement = true;
|
|
120
|
-
const { indexes, int8id, parent, primaryKey, sync, tableName } = Object.assign({ sync: this.
|
|
215
|
+
const { indexes, int8id, parent, primaryKey, sync, tableName } = Object.assign({ sync: this.doSync, tableName: modelName }, options);
|
|
121
216
|
let aarray = int8id
|
|
122
217
|
? [new db_1.Attribute(Object.assign(Object.assign({}, this.INT8()), { attributeName: "id", fieldName: "id", modelName, notNull: true, tableName, unique: true }))]
|
|
123
218
|
: [new db_1.Attribute(Object.assign(Object.assign({}, this.INT(4)), { attributeName: "id", fieldName: "id", modelName, notNull: true, tableName, unique: true }))];
|
|
124
219
|
let constraints = [{ attribute: aarray[0], constraintName: `${tableName}_id_unique`, type: "u" }];
|
|
125
220
|
const iarray = [];
|
|
126
|
-
|
|
221
|
+
let pk = aarray[0];
|
|
222
|
+
let attr2field = { id: "id" };
|
|
127
223
|
if (!methods)
|
|
128
224
|
methods = {};
|
|
129
225
|
if (!(methods instanceof Object))
|
|
@@ -136,6 +232,8 @@ class Sedentary {
|
|
|
136
232
|
if (primaryKey && !Object.keys(attributes).includes(primaryKey))
|
|
137
233
|
throw new Error(`Sedentary.model: '${modelName}' model: 'primaryKey' option: Attribute '${primaryKey}' does not exists`);
|
|
138
234
|
if (parent || primaryKey) {
|
|
235
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
236
|
+
attr2field = parent ? Object.assign({}, parent.attr2field) : {};
|
|
139
237
|
autoIncrement = false;
|
|
140
238
|
aarray = [];
|
|
141
239
|
constraints = [];
|
|
@@ -212,7 +310,10 @@ class Sedentary {
|
|
|
212
310
|
if (defaultValue)
|
|
213
311
|
notNull = true;
|
|
214
312
|
const attribute = new db_1.Attribute({ attributeName, base, defaultValue, fieldName, foreignKey, modelName, notNull, size, tableName, type, unique });
|
|
313
|
+
if (primaryKey === attributeName)
|
|
314
|
+
pk = attribute;
|
|
215
315
|
aarray.push(attribute);
|
|
316
|
+
attr2field[attributeName] = fieldName;
|
|
216
317
|
if (foreignKey)
|
|
217
318
|
constraints.push({ attribute, constraintName: `fkey_${fieldName}_${foreignKey.tableName}_${foreignKey.fieldName}`, type: "f" });
|
|
218
319
|
if (unique)
|
|
@@ -270,7 +371,6 @@ class Sedentary {
|
|
|
270
371
|
iarray.push({ fields: attributes, indexName, type, unique });
|
|
271
372
|
}
|
|
272
373
|
}
|
|
273
|
-
this.db.tables.push(new db_1.Table({ autoIncrement, constraints, attributes: aarray, indexes: iarray, parent, sync, tableName }));
|
|
274
374
|
this.models[modelName] = true;
|
|
275
375
|
const foreignKeys = aarray
|
|
276
376
|
.filter(_ => _.foreignKey)
|
|
@@ -311,27 +411,42 @@ class Sedentary {
|
|
|
311
411
|
for (const foreignKey in parent.foreignKeys)
|
|
312
412
|
if (foreignKey + "Load" === method)
|
|
313
413
|
throw new Error(`Sedentary.model: '${modelName}' model: '${method}' method: conflicts with an inferred methods of '${parent.modelName}' model`);
|
|
314
|
-
if (method in parent.methods)
|
|
315
|
-
throw new Error(`Sedentary.model: '${modelName}' model: '${method}' method: conflicts with a method of '${parent.modelName}' model`);
|
|
316
414
|
}
|
|
317
415
|
checkParent(parent.parent);
|
|
318
416
|
};
|
|
319
417
|
checkParent(parent);
|
|
320
418
|
const ret = class extends (parent || db_1.EntryBase) {
|
|
321
419
|
};
|
|
322
|
-
const
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
420
|
+
const table = new db_1.Table({ autoIncrement, constraints, attributes: aarray, indexes: iarray, model: ret, parent, pk, sync, tableName });
|
|
421
|
+
this.db.tables.push(table);
|
|
422
|
+
const load_ = this.db.load(tableName, attr2field, pk, ret, table);
|
|
423
|
+
const load = async (where, order, tx) => {
|
|
424
|
+
if (order instanceof db_1.Transaction) {
|
|
425
|
+
tx = order;
|
|
426
|
+
order = undefined;
|
|
427
|
+
}
|
|
428
|
+
if (!this.checkOrderBy(order, attr2field, modelName))
|
|
429
|
+
throw new Error(`${modelName}.load: 'order' argument: Wrong type, expected 'string[]'`);
|
|
430
|
+
const [str] = this.createWhere(modelName, attr2field, where);
|
|
431
|
+
const ret = await load_(str, order, tx);
|
|
432
|
+
return ret;
|
|
433
|
+
};
|
|
327
434
|
Object.defineProperty(load, "name", { value: modelName + ".load" });
|
|
328
435
|
Object.defineProperty(ret, "name", { value: modelName });
|
|
329
436
|
Object.defineProperty(ret, "load", { value: load });
|
|
437
|
+
Object.defineProperty(ret, "attr2field", { value: attr2field });
|
|
330
438
|
Object.defineProperty(ret, "attributes", { value: attributes });
|
|
331
439
|
Object.defineProperty(ret, "foreignKeys", { value: foreignKeys });
|
|
332
440
|
Object.defineProperty(ret, "methods", { value: methods });
|
|
333
441
|
Object.assign(ret.prototype, methods);
|
|
334
|
-
|
|
442
|
+
const save = this.db.save(tableName, attr2field, pk);
|
|
443
|
+
ret.prototype.save = async function () {
|
|
444
|
+
this.preSave();
|
|
445
|
+
const ret = await save.call(this);
|
|
446
|
+
if (ret)
|
|
447
|
+
this.postSave();
|
|
448
|
+
return ret;
|
|
449
|
+
};
|
|
335
450
|
Object.defineProperty(ret.prototype.save, "name", { value: modelName + ".save" });
|
|
336
451
|
for (const attribute of aarray)
|
|
337
452
|
Object.defineProperty(ret, attribute.attributeName, { value: attribute });
|
package/package.json
CHANGED
|
@@ -9,16 +9,16 @@
|
|
|
9
9
|
"description": "The ORM which never needs to migrate",
|
|
10
10
|
"devDependencies": {
|
|
11
11
|
"@types/mocha": "9.0.0",
|
|
12
|
-
"@types/node": "17.0.
|
|
12
|
+
"@types/node": "17.0.8",
|
|
13
13
|
"@types/yamljs": "0.2.31",
|
|
14
|
-
"@typescript-eslint/eslint-plugin": "5.
|
|
15
|
-
"@typescript-eslint/parser": "5.
|
|
16
|
-
"eslint": "8.
|
|
14
|
+
"@typescript-eslint/eslint-plugin": "5.9.0",
|
|
15
|
+
"@typescript-eslint/parser": "5.9.0",
|
|
16
|
+
"eslint": "8.6.0",
|
|
17
17
|
"mocha": "9.1.3",
|
|
18
18
|
"nyc": "15.1.0",
|
|
19
19
|
"prettier": "2.5.1",
|
|
20
20
|
"ts-node": "10.4.0",
|
|
21
|
-
"tsd": "0.19.
|
|
21
|
+
"tsd": "0.19.1",
|
|
22
22
|
"typescript": "4.5.4",
|
|
23
23
|
"yamljs": "0.3.0"
|
|
24
24
|
},
|
|
@@ -78,5 +78,5 @@
|
|
|
78
78
|
}
|
|
79
79
|
},
|
|
80
80
|
"types": "index.d.ts",
|
|
81
|
-
"version": "0.0.
|
|
81
|
+
"version": "0.0.24"
|
|
82
82
|
}
|