sedentary 0.0.20 → 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/README.md +2 -3
- package/{lib/db.d.ts → db.d.ts} +20 -3
- package/{lib/db.js → db.js} +35 -1
- package/index.d.ts +31 -16
- package/index.js +173 -51
- package/package.json +10 -6
- package/lib/minidb.d.ts +0 -17
- package/lib/minidb.js +0 -191
- package/lib/transaction.d.ts +0 -2
- package/lib/transaction.js +0 -6
- package/requirements.txt +0 -2
- package/utils.d.ts +0 -1
- package/utils.js +0 -130
package/README.md
CHANGED
|
@@ -81,10 +81,9 @@ $ npm install --save sedentary
|
|
|
81
81
|
|
|
82
82
|
# Disclaimer
|
|
83
83
|
|
|
84
|
-
**Do not use this package itself
|
|
85
|
-
purposes.**
|
|
84
|
+
**Do not use this package itself! It does not support any DB engine.**
|
|
86
85
|
|
|
87
|
-
|
|
86
|
+
A _DB engine dedicated extension_ must be used:
|
|
88
87
|
|
|
89
88
|
- MySQL: planned
|
|
90
89
|
- PostgreSQL: [sedentary-pg](https://github.com/iccicci/sedentary-pg#readme)
|
package/{lib/db.d.ts → db.d.ts}
RENAMED
|
@@ -1,7 +1,9 @@
|
|
|
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
4
|
construct(): void;
|
|
4
5
|
postLoad(): void;
|
|
6
|
+
postSave(): void;
|
|
5
7
|
preLoad(): void;
|
|
6
8
|
preSave(): void;
|
|
7
9
|
save(): Promise<boolean>;
|
|
@@ -29,7 +31,7 @@ export declare class Type<N extends Natural, E> {
|
|
|
29
31
|
}
|
|
30
32
|
export interface Attribute<N extends Natural, E> extends Type<N, E> {
|
|
31
33
|
attributeName: string;
|
|
32
|
-
defaultValue?:
|
|
34
|
+
defaultValue?: Natural;
|
|
33
35
|
fieldName: string;
|
|
34
36
|
modelName: string;
|
|
35
37
|
notNull: boolean;
|
|
@@ -55,7 +57,11 @@ interface ITable {
|
|
|
55
57
|
autoIncrement: boolean;
|
|
56
58
|
constraints: Constraint[];
|
|
57
59
|
indexes: Index[];
|
|
58
|
-
|
|
60
|
+
model: {
|
|
61
|
+
load: (where: any, order?: string[], tx?: Transaction) => Promise<EntryBase[]>;
|
|
62
|
+
};
|
|
63
|
+
parent?: Attribute<Natural, unknown>;
|
|
64
|
+
pk: Attribute<Natural, unknown>;
|
|
59
65
|
sync: boolean;
|
|
60
66
|
tableName: string;
|
|
61
67
|
}
|
|
@@ -76,6 +82,10 @@ export declare abstract class DB {
|
|
|
76
82
|
protected indexesEq(a: Index, b: Index): boolean;
|
|
77
83
|
syncDataBase(): Promise<void>;
|
|
78
84
|
protected syncLog(message: string): void;
|
|
85
|
+
begin(): Promise<Transaction>;
|
|
86
|
+
abstract escape(value: Natural): string;
|
|
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>;
|
|
79
89
|
abstract dropConstraints(table: Table): Promise<number[]>;
|
|
80
90
|
abstract dropFields(table: Table): Promise<void>;
|
|
81
91
|
abstract dropIndexes(table: Table, constraintIndexes: number[]): Promise<void>;
|
|
@@ -85,4 +95,11 @@ export declare abstract class DB {
|
|
|
85
95
|
abstract syncSequence(table: Table): Promise<void>;
|
|
86
96
|
abstract syncTable(table: Table): Promise<void>;
|
|
87
97
|
}
|
|
98
|
+
export declare class Transaction {
|
|
99
|
+
private entries;
|
|
100
|
+
addEntry(entry: EntryBase): void;
|
|
101
|
+
clean(): void;
|
|
102
|
+
commit(): Promise<void>;
|
|
103
|
+
rollback(): Promise<void>;
|
|
104
|
+
}
|
|
88
105
|
export {};
|
package/{lib/db.js → db.js}
RENAMED
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DB = exports.Table = exports.Attribute = exports.Type = exports.EntryBase = void 0;
|
|
3
|
+
exports.Transaction = exports.DB = exports.Table = exports.Attribute = exports.Type = exports.EntryBase = void 0;
|
|
4
4
|
class EntryBase {
|
|
5
|
+
constructor(from) {
|
|
6
|
+
if (from === "load")
|
|
7
|
+
this.preLoad();
|
|
8
|
+
else {
|
|
9
|
+
if (from)
|
|
10
|
+
Object.assign(this, from);
|
|
11
|
+
this.construct();
|
|
12
|
+
}
|
|
13
|
+
}
|
|
5
14
|
construct() { }
|
|
6
15
|
postLoad() { }
|
|
16
|
+
postSave() { }
|
|
7
17
|
preLoad() { }
|
|
8
18
|
preSave() { }
|
|
9
19
|
async save() {
|
|
@@ -73,5 +83,29 @@ class DB {
|
|
|
73
83
|
syncLog(message) {
|
|
74
84
|
this.log(this.sync ? message : "NOT SYNCING: " + message);
|
|
75
85
|
}
|
|
86
|
+
async begin() {
|
|
87
|
+
return new Transaction();
|
|
88
|
+
}
|
|
76
89
|
}
|
|
77
90
|
exports.DB = DB;
|
|
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
|
+
}
|
|
110
|
+
}
|
|
111
|
+
exports.Transaction = Transaction;
|
package/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Attribute, DB, EntryBase, ForeignKeyOptions, Natural, Type } from "./
|
|
2
|
-
export { EntryBase, ForeignKeyActions, ForeignKeyOptions, Natural, Type } from "./
|
|
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;
|
|
@@ -36,14 +36,15 @@ interface BaseModelOptions {
|
|
|
36
36
|
}
|
|
37
37
|
export interface ModelOptions extends BaseModelOptions {
|
|
38
38
|
int8id?: boolean;
|
|
39
|
-
parent?:
|
|
39
|
+
parent?: Attribute<Natural, EntryBase>;
|
|
40
40
|
primaryKey?: string;
|
|
41
41
|
}
|
|
42
|
-
declare type ConditionAttribute<N extends Natural> = N | [">" | "<" | ">=" | "<=" | "<>", N] | ["
|
|
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,28 +83,40 @@ 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 {
|
|
95
|
+
autoSync?: boolean;
|
|
86
96
|
log?: ((message: string) => void) | null;
|
|
87
|
-
serverless?: boolean;
|
|
88
97
|
sync?: boolean;
|
|
89
98
|
}
|
|
90
99
|
export declare class Sedentary {
|
|
100
|
+
protected autoSync: boolean;
|
|
91
101
|
protected db: DB;
|
|
102
|
+
protected doSync: boolean;
|
|
92
103
|
protected log: (...data: unknown[]) => void;
|
|
93
|
-
protected sync: boolean;
|
|
94
104
|
private models;
|
|
95
|
-
constructor(
|
|
105
|
+
constructor(options?: SedentaryOptions);
|
|
96
106
|
DATETIME(): Type<Date, unknown>;
|
|
97
107
|
FKEY<N extends Natural, E extends EntryBase>(attribute: Attribute<N, E>, options?: ForeignKeyOptions): Type<N, E>;
|
|
98
108
|
INT(size?: number): Type<number, unknown>;
|
|
99
109
|
INT8(): Type<string, unknown>;
|
|
100
110
|
VARCHAR(size?: number): Type<string, unknown>;
|
|
101
|
-
|
|
102
|
-
|
|
111
|
+
private checkDB;
|
|
112
|
+
private checkOrderBy;
|
|
113
|
+
private checkSize;
|
|
114
|
+
private createWhere;
|
|
115
|
+
connect(sync?: boolean): Promise<void>;
|
|
116
|
+
sync(): Promise<void>;
|
|
103
117
|
end(): Promise<void>;
|
|
118
|
+
begin(): Promise<Transaction>;
|
|
119
|
+
escape(value: Natural): string;
|
|
104
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 & {
|
|
105
121
|
int8id?: B;
|
|
106
122
|
parent?: P;
|
|
@@ -112,4 +128,3 @@ export declare class Sedentary {
|
|
|
112
128
|
primaryKey?: K | keyof A;
|
|
113
129
|
}, methods: M & Record<keyof M, (this: EA & EM & M, ...args: any[]) => void>): Model<K extends keyof A ? Native<A[K]> : KeyType<B, P>, ModelAttributes<A, B, K, P>, EM & M>;
|
|
114
130
|
}
|
|
115
|
-
export declare const Package: typeof Sedentary;
|
package/index.js
CHANGED
|
@@ -1,38 +1,40 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
const db_1 = require("./
|
|
5
|
-
|
|
6
|
-
var db_2 = require("./lib/db");
|
|
3
|
+
exports.Sedentary = exports.Type = exports.Transaction = exports.EntryBase = void 0;
|
|
4
|
+
const db_1 = require("./db");
|
|
5
|
+
var db_2 = require("./db");
|
|
7
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; } });
|
|
8
8
|
Object.defineProperty(exports, "Type", { enumerable: true, get: function () { return db_2.Type; } });
|
|
9
|
+
const operators = ["=", ">", "<", ">=", "<=", "<>", "IN", "IS NULL", "LIKE", "NOT"];
|
|
9
10
|
const allowedOption = ["indexes", "int8id", "parent", "primaryKey", "sync", "tableName"];
|
|
10
11
|
const reservedNames = [
|
|
11
|
-
...["attributeName", "attributes", "base", "class", "construct", "constructor", "defaultValue", "entry", "fieldName", "foreignKeys", "load"],
|
|
12
|
-
...["methods", "name", "postLoad", "postSave", "preLoad", "preSave", "primaryKey", "prototype", "save", "size", "tableName", "type"]
|
|
12
|
+
...["attr2field", "attributeName", "attributes", "base", "class", "construct", "constructor", "defaultValue", "entry", "fieldName", "foreignKeys", "load"],
|
|
13
|
+
...["loaded", "methods", "name", "postLoad", "postSave", "preLoad", "preSave", "primaryKey", "prototype", "save", "size", "tableName", "tx", "type"]
|
|
13
14
|
];
|
|
14
15
|
class Sedentary {
|
|
15
|
-
constructor(
|
|
16
|
-
this.
|
|
16
|
+
constructor(options) {
|
|
17
|
+
this.doSync = true;
|
|
17
18
|
this.models = {};
|
|
18
|
-
if (typeof filename !== "string")
|
|
19
|
-
throw new Error("new Sedentary: 'filename' argument: Wrong type, expected 'string'");
|
|
20
19
|
if (!options)
|
|
21
20
|
options = {};
|
|
22
21
|
if (!(options instanceof Object))
|
|
23
22
|
throw new Error("new Sedentary: 'options' argument: Wrong type, expected 'Object'");
|
|
24
23
|
for (const k in options)
|
|
25
|
-
if (!["log", "sync"].includes(k))
|
|
24
|
+
if (!["autoSync", "log", "sync"].includes(k))
|
|
26
25
|
throw new Error(`new Sedentary: 'options' argument: Unknown '${k}' option`);
|
|
27
|
-
const { log, sync } = Object.assign({ sync: true }, options);
|
|
26
|
+
const { autoSync, log, sync } = Object.assign({ autoSync: true, sync: true }, options);
|
|
27
|
+
if (typeof autoSync !== "boolean")
|
|
28
|
+
throw new Error("new Sedentary: 'autoSync' option: Wrong type, expected 'boolean'");
|
|
28
29
|
if (log !== null && log !== undefined && !(log instanceof Function))
|
|
29
30
|
throw new Error("new Sedentary: 'log' option: Wrong type, expected 'null' or 'Function'");
|
|
30
31
|
if (typeof sync !== "boolean")
|
|
31
32
|
throw new Error("new Sedentary: 'sync' option: Wrong type, expected 'boolean'");
|
|
33
|
+
this.autoSync = autoSync;
|
|
34
|
+
this.db = null;
|
|
32
35
|
// eslint-disable-next-line no-console
|
|
33
36
|
this.log = log ? log : log === null ? () => { } : console.log;
|
|
34
|
-
this.
|
|
35
|
-
this.sync = sync;
|
|
37
|
+
this.doSync = sync;
|
|
36
38
|
}
|
|
37
39
|
DATETIME() {
|
|
38
40
|
return new db_1.Type({ base: Date, type: "DATETIME" });
|
|
@@ -56,6 +58,28 @@ class Sedentary {
|
|
|
56
58
|
size = size ? this.checkSize(size, message) : undefined;
|
|
57
59
|
return new db_1.Type({ base: String, size, type: "VARCHAR" });
|
|
58
60
|
}
|
|
61
|
+
checkDB() {
|
|
62
|
+
if (!this.db)
|
|
63
|
+
throw new Error("Package sedentary can't be used directly. Please check: https://www.npmjs.com/package/sedentary#disclaimer");
|
|
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
|
+
}
|
|
59
83
|
checkSize(size, message) {
|
|
60
84
|
const str = size.toString();
|
|
61
85
|
const parsed = parseInt(str, 10);
|
|
@@ -63,26 +87,109 @@ class Sedentary {
|
|
|
63
87
|
throw new Error(message);
|
|
64
88
|
return parsed;
|
|
65
89
|
}
|
|
66
|
-
|
|
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
|
+
}
|
|
160
|
+
async connect(sync) {
|
|
67
161
|
try {
|
|
162
|
+
this.checkDB();
|
|
68
163
|
this.log("Connecting...");
|
|
69
164
|
await this.db.connect();
|
|
70
|
-
this.log("Connected
|
|
71
|
-
|
|
72
|
-
|
|
165
|
+
this.log("Connected");
|
|
166
|
+
if (this.autoSync || sync)
|
|
167
|
+
await this.sync();
|
|
73
168
|
}
|
|
74
169
|
catch (e) {
|
|
75
170
|
this.log("Connecting: " + (e instanceof Error ? e.message : JSON.stringify(e)));
|
|
76
171
|
throw e;
|
|
77
172
|
}
|
|
78
173
|
}
|
|
174
|
+
async sync() {
|
|
175
|
+
this.log("Syncing...");
|
|
176
|
+
await this.db.syncDataBase();
|
|
177
|
+
this.log("Synced");
|
|
178
|
+
}
|
|
79
179
|
async end() {
|
|
80
180
|
this.log("Closing connection...");
|
|
81
181
|
await this.db.end();
|
|
82
182
|
this.log("Connection closed");
|
|
83
183
|
}
|
|
184
|
+
async begin() {
|
|
185
|
+
return this.db.begin();
|
|
186
|
+
}
|
|
187
|
+
escape(value) {
|
|
188
|
+
return this.db.escape(value);
|
|
189
|
+
}
|
|
84
190
|
/* eslint-enable @typescript-eslint/no-explicit-any */
|
|
85
191
|
model(modelName, attributes, options, methods) {
|
|
192
|
+
this.checkDB();
|
|
86
193
|
if (typeof modelName !== "string")
|
|
87
194
|
throw new Error("Sedentary.model: 'name' argument: Wrong type, expected 'string'");
|
|
88
195
|
if (this.models[modelName])
|
|
@@ -105,25 +212,28 @@ class Sedentary {
|
|
|
105
212
|
if (options.parent && options.primaryKey)
|
|
106
213
|
throw new Error(`Sedentary.model: '${modelName}' model: 'parent' and 'primaryKey' options conflict each other`);
|
|
107
214
|
let autoIncrement = true;
|
|
108
|
-
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);
|
|
109
216
|
let aarray = int8id
|
|
110
217
|
? [new db_1.Attribute(Object.assign(Object.assign({}, this.INT8()), { attributeName: "id", fieldName: "id", modelName, notNull: true, tableName, unique: true }))]
|
|
111
218
|
: [new db_1.Attribute(Object.assign(Object.assign({}, this.INT(4)), { attributeName: "id", fieldName: "id", modelName, notNull: true, tableName, unique: true }))];
|
|
112
219
|
let constraints = [{ attribute: aarray[0], constraintName: `${tableName}_id_unique`, type: "u" }];
|
|
113
220
|
const iarray = [];
|
|
114
|
-
|
|
115
|
-
|
|
221
|
+
let pk = aarray[0];
|
|
222
|
+
let attr2field = { id: "id" };
|
|
223
|
+
if (!methods)
|
|
224
|
+
methods = {};
|
|
225
|
+
if (!(methods instanceof Object))
|
|
116
226
|
throw new Error(`Sedentary.model: '${modelName}' model: 'methods' option: Wrong type, expected 'Object'`);
|
|
117
|
-
const originalMethods = methods;
|
|
118
227
|
if (parent)
|
|
119
228
|
if (!parent.attributes)
|
|
120
229
|
throw new Error(`Sedentary.model: '${modelName}' model: 'parent' option: Wrong type, expected 'Model'`);
|
|
121
|
-
//methods = (methods ? { ...(parent.methods || {}), ...methods } : parent.methods) as never;
|
|
122
230
|
if (primaryKey && typeof primaryKey !== "string")
|
|
123
231
|
throw new Error(`Sedentary.model: '${modelName}' model: 'primaryKey' option: Wrong type, expected 'string'`);
|
|
124
232
|
if (primaryKey && !Object.keys(attributes).includes(primaryKey))
|
|
125
233
|
throw new Error(`Sedentary.model: '${modelName}' model: 'primaryKey' option: Attribute '${primaryKey}' does not exists`);
|
|
126
234
|
if (parent || primaryKey) {
|
|
235
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
236
|
+
attr2field = parent ? Object.assign({}, parent.attr2field) : {};
|
|
127
237
|
autoIncrement = false;
|
|
128
238
|
aarray = [];
|
|
129
239
|
constraints = [];
|
|
@@ -200,7 +310,10 @@ class Sedentary {
|
|
|
200
310
|
if (defaultValue)
|
|
201
311
|
notNull = true;
|
|
202
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;
|
|
203
315
|
aarray.push(attribute);
|
|
316
|
+
attr2field[attributeName] = fieldName;
|
|
204
317
|
if (foreignKey)
|
|
205
318
|
constraints.push({ attribute, constraintName: `fkey_${fieldName}_${foreignKey.tableName}_${foreignKey.fieldName}`, type: "f" });
|
|
206
319
|
if (unique)
|
|
@@ -258,7 +371,6 @@ class Sedentary {
|
|
|
258
371
|
iarray.push({ fields: attributes, indexName, type, unique });
|
|
259
372
|
}
|
|
260
373
|
}
|
|
261
|
-
this.db.tables.push(new db_1.Table({ autoIncrement, constraints, attributes: aarray, indexes: iarray, parent, sync, tableName }));
|
|
262
374
|
this.models[modelName] = true;
|
|
263
375
|
const foreignKeys = aarray
|
|
264
376
|
.filter(_ => _.foreignKey)
|
|
@@ -269,13 +381,12 @@ class Sedentary {
|
|
|
269
381
|
for (const foreignKey in foreignKeys) {
|
|
270
382
|
if (foreignKey + "Load" in attributes)
|
|
271
383
|
throw new Error(`Sedentary.model: '${modelName}' model: '${foreignKey}' attribute: '${foreignKey}Load' inferred methods conflicts with an attribute`);
|
|
272
|
-
if (
|
|
384
|
+
if (foreignKey + "Load" in methods)
|
|
273
385
|
throw new Error(`Sedentary.model: '${modelName}' model: '${foreignKey}' attribute: '${foreignKey}Load' inferred methods conflicts with a method`);
|
|
274
386
|
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
throw new Error(`Sedentary.model: '${modelName}' model: '${method}' method: conflicts with an attribute`);
|
|
387
|
+
for (const method in methods)
|
|
388
|
+
if (method in attributes)
|
|
389
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${method}' method: conflicts with an attribute`);
|
|
279
390
|
const checkParent = (parent) => {
|
|
280
391
|
if (!parent)
|
|
281
392
|
return;
|
|
@@ -294,37 +405,49 @@ class Sedentary {
|
|
|
294
405
|
if (foreignKey + "Load" in parent.methods)
|
|
295
406
|
throw new Error(`Sedentary.model: '${modelName}' model: '${foreignKey}' attribute: '${foreignKey}Load' inferred methods conflicts with a method of '${parent.modelName}' model`);
|
|
296
407
|
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
throw new Error(`Sedentary.model: '${modelName}' model: '${method}' method: conflicts with an inferred methods of '${parent.modelName}' model`);
|
|
304
|
-
if (method in parent.methods)
|
|
305
|
-
throw new Error(`Sedentary.model: '${modelName}' model: '${method}' method: conflicts with a method of '${parent.modelName}' model`);
|
|
306
|
-
}
|
|
408
|
+
for (const method in methods) {
|
|
409
|
+
if (method in parent.attributes)
|
|
410
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${method}' method: conflicts with an attribute of '${parent.modelName}' model`);
|
|
411
|
+
for (const foreignKey in parent.foreignKeys)
|
|
412
|
+
if (foreignKey + "Load" === method)
|
|
413
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${method}' method: conflicts with an inferred methods of '${parent.modelName}' model`);
|
|
307
414
|
}
|
|
308
415
|
checkParent(parent.parent);
|
|
309
416
|
};
|
|
310
417
|
checkParent(parent);
|
|
311
|
-
const ret =
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
418
|
+
const ret = class extends (parent || db_1.EntryBase) {
|
|
419
|
+
};
|
|
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
|
+
};
|
|
317
434
|
Object.defineProperty(load, "name", { value: modelName + ".load" });
|
|
318
435
|
Object.defineProperty(ret, "name", { value: modelName });
|
|
319
436
|
Object.defineProperty(ret, "load", { value: load });
|
|
437
|
+
Object.defineProperty(ret, "attr2field", { value: attr2field });
|
|
320
438
|
Object.defineProperty(ret, "attributes", { value: attributes });
|
|
321
439
|
Object.defineProperty(ret, "foreignKeys", { value: foreignKeys });
|
|
322
|
-
Object.defineProperty(ret, "methods", { value: methods
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
ret.prototype.save = function () {
|
|
326
|
-
|
|
440
|
+
Object.defineProperty(ret, "methods", { value: methods });
|
|
441
|
+
Object.assign(ret.prototype, methods);
|
|
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;
|
|
327
449
|
};
|
|
450
|
+
Object.defineProperty(ret.prototype.save, "name", { value: modelName + ".save" });
|
|
328
451
|
for (const attribute of aarray)
|
|
329
452
|
Object.defineProperty(ret, attribute.attributeName, { value: attribute });
|
|
330
453
|
for (const key of ["attributeName", "base", "fieldName", "modelName", "size", "tableName", "type", "unique"])
|
|
@@ -333,4 +456,3 @@ class Sedentary {
|
|
|
333
456
|
}
|
|
334
457
|
}
|
|
335
458
|
exports.Sedentary = Sedentary;
|
|
336
|
-
exports.Package = Sedentary;
|
package/package.json
CHANGED
|
@@ -1,20 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"author": "Daniele Ricci <daniele.icc@gmail.com> (https://github.com/iccicci)",
|
|
3
3
|
"bugs": "https://github.com/iccicci/sedentary/issues",
|
|
4
|
+
"contributors": [
|
|
5
|
+
"Daniele Ricci <daniele.icc@gmail.com> (https://github.com/iccicci)",
|
|
6
|
+
"yossarian <sergiybiluk@gmail.com> (https://github.com/captain-yossarian)"
|
|
7
|
+
],
|
|
4
8
|
"dependencies": {},
|
|
5
9
|
"description": "The ORM which never needs to migrate",
|
|
6
10
|
"devDependencies": {
|
|
7
11
|
"@types/mocha": "9.0.0",
|
|
8
|
-
"@types/node": "17.0.
|
|
12
|
+
"@types/node": "17.0.8",
|
|
9
13
|
"@types/yamljs": "0.2.31",
|
|
10
|
-
"@typescript-eslint/eslint-plugin": "5.
|
|
11
|
-
"@typescript-eslint/parser": "5.
|
|
12
|
-
"eslint": "8.
|
|
14
|
+
"@typescript-eslint/eslint-plugin": "5.9.0",
|
|
15
|
+
"@typescript-eslint/parser": "5.9.0",
|
|
16
|
+
"eslint": "8.6.0",
|
|
13
17
|
"mocha": "9.1.3",
|
|
14
18
|
"nyc": "15.1.0",
|
|
15
19
|
"prettier": "2.5.1",
|
|
16
20
|
"ts-node": "10.4.0",
|
|
17
|
-
"tsd": "0.19.
|
|
21
|
+
"tsd": "0.19.1",
|
|
18
22
|
"typescript": "4.5.4",
|
|
19
23
|
"yamljs": "0.3.0"
|
|
20
24
|
},
|
|
@@ -74,5 +78,5 @@
|
|
|
74
78
|
}
|
|
75
79
|
},
|
|
76
80
|
"types": "index.d.ts",
|
|
77
|
-
"version": "0.0.
|
|
81
|
+
"version": "0.0.24"
|
|
78
82
|
}
|
package/lib/minidb.d.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { DB, Table } from "./db";
|
|
2
|
-
export declare class MiniDB extends DB {
|
|
3
|
-
private body;
|
|
4
|
-
private file;
|
|
5
|
-
constructor(filename: string, log: (message: string) => void);
|
|
6
|
-
connect(): Promise<void>;
|
|
7
|
-
dropConstraints(table: Table): Promise<number[]>;
|
|
8
|
-
dropFields(table: Table): Promise<void>;
|
|
9
|
-
dropIndexes(table: Table, constraintIndexes: number[]): Promise<void>;
|
|
10
|
-
end(): Promise<void>;
|
|
11
|
-
save(): Promise<void>;
|
|
12
|
-
syncConstraints(table: Table): Promise<void>;
|
|
13
|
-
syncIndexes(table: Table): Promise<void>;
|
|
14
|
-
syncFields(table: Table): Promise<void>;
|
|
15
|
-
syncSequence(table: Table): Promise<void>;
|
|
16
|
-
syncTable(table: Table): Promise<void>;
|
|
17
|
-
}
|
package/lib/minidb.js
DELETED
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
3
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.MiniDB = void 0;
|
|
5
|
-
const db_1 = require("./db");
|
|
6
|
-
const fs_1 = require("fs");
|
|
7
|
-
const { readFile, writeFile } = fs_1.promises;
|
|
8
|
-
class MiniDB extends db_1.DB {
|
|
9
|
-
constructor(filename, log) {
|
|
10
|
-
super(log);
|
|
11
|
-
this.file = filename;
|
|
12
|
-
}
|
|
13
|
-
async connect() {
|
|
14
|
-
this.body = { next: {}, tables: {} };
|
|
15
|
-
try {
|
|
16
|
-
this.body = JSON.parse((await readFile(this.file)).toString());
|
|
17
|
-
}
|
|
18
|
-
catch (e) {
|
|
19
|
-
const err = e;
|
|
20
|
-
if (err.code !== "ENOENT")
|
|
21
|
-
throw e;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
async dropConstraints(table) {
|
|
25
|
-
const { constraints } = this.body.tables[table.tableName] || { constraints: { f: {}, u: {} } };
|
|
26
|
-
for (const constraint of Object.keys(constraints.f).sort()) {
|
|
27
|
-
const arr = table.constraints.filter(({ constraintName, type }) => constraintName === constraint && type === "f");
|
|
28
|
-
const dbOptions = arr.length ? arr[0].attribute.foreignKey.options : { onDelete: "delete", onUpdate: "delete" };
|
|
29
|
-
const inOptions = constraints.f[constraint].options;
|
|
30
|
-
if (dbOptions.onDelete !== inOptions.onDelete || dbOptions.onUpdate !== inOptions.onUpdate) {
|
|
31
|
-
this.syncLog(`'${table.tableName}': Removing foreign key: '${constraint}'`);
|
|
32
|
-
if (this.sync)
|
|
33
|
-
delete constraints.f[constraint];
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
for (const constraint of Object.keys(constraints.u).sort()) {
|
|
37
|
-
if (!table.constraints.filter(({ constraintName, type }) => constraintName === constraint && type === "u").length) {
|
|
38
|
-
this.syncLog(`'${table.tableName}': Removing unique constraint from field: '${constraints.u[constraint].on}'`);
|
|
39
|
-
if (this.sync)
|
|
40
|
-
delete constraints.u[constraint];
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
await this.save();
|
|
44
|
-
return [];
|
|
45
|
-
}
|
|
46
|
-
async dropFields(table) {
|
|
47
|
-
const { fields } = this.body.tables[table.tableName] || { fields: {} };
|
|
48
|
-
for (const attribute of Object.keys(fields).sort()) {
|
|
49
|
-
if (!table.findField(attribute)) {
|
|
50
|
-
this.syncLog(`'${table.tableName}': Removing field: '${attribute}'`);
|
|
51
|
-
if (this.sync)
|
|
52
|
-
delete fields[attribute];
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
await this.save();
|
|
56
|
-
}
|
|
57
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
58
|
-
async dropIndexes(table, constraintIndexes) {
|
|
59
|
-
const { indexes } = this.body.tables[table.tableName] || { indexes: {} };
|
|
60
|
-
for (const name of Object.keys(indexes).sort()) {
|
|
61
|
-
const index = table.indexes.filter(_ => _.indexName === name);
|
|
62
|
-
if (index.length === 0 || !this.indexesEq(indexes[name], index[0])) {
|
|
63
|
-
this.syncLog(`'${table.tableName}': Removing index: '${name}'`);
|
|
64
|
-
if (this.sync)
|
|
65
|
-
delete indexes[name];
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
await this.save();
|
|
69
|
-
}
|
|
70
|
-
async end() { }
|
|
71
|
-
async save() {
|
|
72
|
-
await writeFile(this.file, JSON.stringify(this.body));
|
|
73
|
-
}
|
|
74
|
-
async syncConstraints(table) {
|
|
75
|
-
const { constraints } = this.body.tables[table.tableName] || { constraints: { f: {}, u: {} } };
|
|
76
|
-
for (const constraint of table.constraints) {
|
|
77
|
-
const { attribute, constraintName, type } = constraint;
|
|
78
|
-
if (!constraints[type][constraintName]) {
|
|
79
|
-
if (type === "f") {
|
|
80
|
-
const { fieldName, options, tableName } = attribute.foreignKey;
|
|
81
|
-
const onDelete = options.onDelete !== "no action" ? ` on delete ${options.onDelete}` : "";
|
|
82
|
-
const onUpdate = options.onUpdate !== "no action" ? ` on update ${options.onUpdate}` : "";
|
|
83
|
-
this.syncLog(`'${table.tableName}': Adding foreign key '${constraint.constraintName}' on field: '${attribute.fieldName}' references '${tableName}(${fieldName})'${onDelete}${onUpdate}`);
|
|
84
|
-
if (this.sync)
|
|
85
|
-
constraints[type][constraintName] = { on: attribute.fieldName, options, fieldName, tableName };
|
|
86
|
-
}
|
|
87
|
-
else {
|
|
88
|
-
this.syncLog(`'${table.tableName}': Adding unique constraint on field: '${attribute.fieldName}'`);
|
|
89
|
-
if (this.sync)
|
|
90
|
-
constraints[type][constraintName] = { on: attribute.fieldName };
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
await this.save();
|
|
95
|
-
}
|
|
96
|
-
async syncIndexes(table) {
|
|
97
|
-
const { indexes } = this.body.tables[table.tableName] || { indexes: {} };
|
|
98
|
-
for (const index of table.indexes) {
|
|
99
|
-
const { indexName } = index;
|
|
100
|
-
if (!(indexName in indexes)) {
|
|
101
|
-
this.syncLog(`'${table.tableName}': Adding index: '${indexName}' on (${index.fields.map(_ => `'${_}'`).join(", ")}) type '${index.type}'${index.unique ? " unique" : ""}`);
|
|
102
|
-
if (this.sync)
|
|
103
|
-
indexes[indexName] = index;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
await this.save();
|
|
107
|
-
}
|
|
108
|
-
async syncFields(table) {
|
|
109
|
-
for (const attribute of table.attributes) {
|
|
110
|
-
const { fields } = this.body.tables[table.tableName] || { fields: {} };
|
|
111
|
-
const { defaultValue, fieldName, notNull, size, type } = attribute;
|
|
112
|
-
let field = fields[fieldName];
|
|
113
|
-
if (!field) {
|
|
114
|
-
this.syncLog(`'${table.tableName}': Adding field: '${fieldName}' '${type}' '${size || ""}'`);
|
|
115
|
-
if (this.sync)
|
|
116
|
-
field = fields[fieldName] = { size, type };
|
|
117
|
-
else
|
|
118
|
-
field = {};
|
|
119
|
-
}
|
|
120
|
-
if (field.size !== size || field.type !== type) {
|
|
121
|
-
this.syncLog(`'${table.tableName}': Changing field type: '${fieldName}' '${type}' '${size || ""}'`);
|
|
122
|
-
if (this.sync)
|
|
123
|
-
field = fields[fieldName] = Object.assign(Object.assign({}, field), { size, type });
|
|
124
|
-
}
|
|
125
|
-
if (field.default) {
|
|
126
|
-
if (!defaultValue) {
|
|
127
|
-
this.syncLog(`'${table.tableName}': Dropping default value for field: '${fieldName}'`);
|
|
128
|
-
if (this.sync)
|
|
129
|
-
delete field.default;
|
|
130
|
-
}
|
|
131
|
-
else if (field.default !== defaultValue) {
|
|
132
|
-
this.syncLog(`'${table.tableName}': Changing default value to '${defaultValue}' for field: '${fieldName}'`);
|
|
133
|
-
if (this.sync)
|
|
134
|
-
field.default = defaultValue;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
else if (defaultValue) {
|
|
138
|
-
this.syncLog(`'${table.tableName}': Setting default value '${defaultValue instanceof Date ? defaultValue.toISOString() : defaultValue}' for field: '${fieldName}'`);
|
|
139
|
-
if (this.sync)
|
|
140
|
-
field.default = defaultValue;
|
|
141
|
-
}
|
|
142
|
-
if (field.notNull) {
|
|
143
|
-
if (!notNull) {
|
|
144
|
-
this.syncLog(`'${table.tableName}': Dropping not null for field: '${fieldName}'`);
|
|
145
|
-
if (this.sync)
|
|
146
|
-
delete field.notNull;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
else if (notNull) {
|
|
150
|
-
this.syncLog(`'${table.tableName}': Setting not null for field: '${fieldName}'`);
|
|
151
|
-
if (this.sync)
|
|
152
|
-
field.notNull = true;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
await this.save();
|
|
156
|
-
}
|
|
157
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
158
|
-
async syncSequence(table) { }
|
|
159
|
-
async syncTable(table) {
|
|
160
|
-
if (this.body.tables[table.tableName]) {
|
|
161
|
-
(() => {
|
|
162
|
-
if (table.parent) {
|
|
163
|
-
if (this.body.tables[table.tableName].parent === table.parent.tableName)
|
|
164
|
-
return;
|
|
165
|
-
}
|
|
166
|
-
else if (!this.body.tables[table.tableName].parent)
|
|
167
|
-
return;
|
|
168
|
-
this.syncLog(`Removing table: '${table.tableName}'`);
|
|
169
|
-
if (this.sync)
|
|
170
|
-
delete this.body.tables[table.tableName];
|
|
171
|
-
})();
|
|
172
|
-
}
|
|
173
|
-
if (!this.body.tables[table.tableName]) {
|
|
174
|
-
this.syncLog(`Adding table: '${table.tableName}'`);
|
|
175
|
-
if (this.sync)
|
|
176
|
-
this.body.tables[table.tableName] = { constraints: { f: {}, u: {} }, fields: {}, indexes: {} };
|
|
177
|
-
if (table.parent) {
|
|
178
|
-
this.syncLog(`Setting parent: '${table.parent.tableName}' - to table: '${table.tableName}'`);
|
|
179
|
-
if (this.sync)
|
|
180
|
-
this.body.tables[table.tableName].parent = table.parent.tableName;
|
|
181
|
-
}
|
|
182
|
-
if (table.autoIncrement && !this.body.next[table.tableName]) {
|
|
183
|
-
this.syncLog(`Setting auto increment: '${table.tableName}'`);
|
|
184
|
-
if (this.sync)
|
|
185
|
-
this.body.next[table.tableName] = 1;
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
await this.save();
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
exports.MiniDB = MiniDB;
|
package/lib/transaction.d.ts
DELETED
package/lib/transaction.js
DELETED
package/requirements.txt
DELETED
package/utils.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/utils.js
DELETED
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const yamljs_1 = __importDefault(require("yamljs"));
|
|
7
|
-
const fs_1 = require("fs");
|
|
8
|
-
const { readFile, writeFile } = fs_1.promises;
|
|
9
|
-
const { VERSION, npm_package_name } = process.env;
|
|
10
|
-
const common = ["*.tgz", "coverage", "node_modules", "test.json", ""];
|
|
11
|
-
const git = [".gitignore", ".npmignore", ".nyc_output", "docs/build", "docs/__pycache__", "index.d.ts", "index.js", "lib/*.d.ts", "lib/*.js"];
|
|
12
|
-
const npm = [".*", "Makefile", "docs", "index.ts", "lib/db.ts", "lib/minidb.ts", "lib/transaction.ts", "sedentary-*", "test", "tsconfig.json", "utils.ts"];
|
|
13
|
-
const descriptions = { sedentary: "", "sedentary-mysql": " - MySQL", "sedentary-pg": " - PostgreSQL", "sedentary-sqlite": " - SQLite" };
|
|
14
|
-
const urls = { sedentary: "", "sedentary-mysql": "-mysql", "sedentary-pg": "-pg", "sedentary-sqlite": "-sqlite" };
|
|
15
|
-
const deps = { sedentary: {}, "sedentary-mysql": {}, "sedentary-pg": { pg: "8.7.1", "pg-format": "1.0.4" }, "sedentary-sqlite": {} };
|
|
16
|
-
const devd = { sedentary: {}, "sedentary-mysql": {}, "sedentary-pg": { "@types/pg": "8.6.3", "@types/pg-format": "1.0.2" }, "sedentary-sqlite": {} };
|
|
17
|
-
const packagejson = {
|
|
18
|
-
author: "Daniele Ricci <daniele.icc@gmail.com> (https://github.com/iccicci)",
|
|
19
|
-
dependencies: {},
|
|
20
|
-
devDependencies: {
|
|
21
|
-
"@types/mocha": "9.0.0",
|
|
22
|
-
"@types/node": "17.0.5",
|
|
23
|
-
"@types/yamljs": "0.2.31",
|
|
24
|
-
"@typescript-eslint/eslint-plugin": "5.8.1",
|
|
25
|
-
"@typescript-eslint/parser": "5.8.1",
|
|
26
|
-
eslint: "8.5.0",
|
|
27
|
-
mocha: "9.1.3",
|
|
28
|
-
prettier: "2.5.1",
|
|
29
|
-
nyc: "15.1.0",
|
|
30
|
-
"ts-node": "10.4.0",
|
|
31
|
-
tsd: "0.19.0",
|
|
32
|
-
typescript: "4.5.4",
|
|
33
|
-
yamljs: "0.3.0"
|
|
34
|
-
},
|
|
35
|
-
engines: { node: ">=12.0" },
|
|
36
|
-
funding: { url: "https://blockchain.info/address/1Md9WFAHrXTb3yPBwQWmUfv2RmzrtbHioB" },
|
|
37
|
-
keywords: ["DB", "ORM", "database", "migration", "mysql", "postgresql", "sqlite"],
|
|
38
|
-
license: "MIT",
|
|
39
|
-
prettier: {
|
|
40
|
-
arrowParens: "avoid",
|
|
41
|
-
endOfLine: "lf",
|
|
42
|
-
jsxBracketSameLine: true,
|
|
43
|
-
printWidth: 200,
|
|
44
|
-
trailingComma: "none",
|
|
45
|
-
useTabs: false
|
|
46
|
-
},
|
|
47
|
-
readmeFilename: "README.md",
|
|
48
|
-
scripts: {
|
|
49
|
-
coverage: "nyc -r lcov -r text -r text-summary -r html mocha -r ts-node/register test/*ts",
|
|
50
|
-
gitignore: "node -r ts-node/register utils.ts gitignore",
|
|
51
|
-
npmignore: "node -r ts-node/register utils.ts npmignore",
|
|
52
|
-
packagejson: "node -r ts-node/register utils.ts packagejson",
|
|
53
|
-
test: "mocha -r ts-node/register test/*ts",
|
|
54
|
-
travis: "node -r ts-node/register utils.ts travis",
|
|
55
|
-
tsc: "tsc --declaration",
|
|
56
|
-
version: "node -r ts-node/register utils.ts version"
|
|
57
|
-
},
|
|
58
|
-
tsd: { compilerOptions: {} },
|
|
59
|
-
types: "index.d.ts"
|
|
60
|
-
};
|
|
61
|
-
const before_script_common = [
|
|
62
|
-
"curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter",
|
|
63
|
-
"chmod +x ./cc-test-reporter",
|
|
64
|
-
"./cc-test-reporter before-build"
|
|
65
|
-
];
|
|
66
|
-
const conditions = { sedentary: "", "sedentary-pg": "&& $PG_VERSION == 14 " };
|
|
67
|
-
const travis = {
|
|
68
|
-
common: {
|
|
69
|
-
after_script: [`if [[ \`node --version\` =~ ^v16 ${conditions[npm_package_name]}]] ; then ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT ; fi`],
|
|
70
|
-
before_script: before_script_common,
|
|
71
|
-
language: "node_js",
|
|
72
|
-
node_js: ["16", "14", "12"],
|
|
73
|
-
script: "npm run coverage",
|
|
74
|
-
sudo: "required"
|
|
75
|
-
},
|
|
76
|
-
sedentary: { env: { global: ["CC_TEST_REPORTER_ID=1aa1f737e7bf7d2859a2c7d9a0d9634a0d9aa89e3a19476d576faa7d02a1d46f"] } },
|
|
77
|
-
"sedentary-pg": {
|
|
78
|
-
before_install: ["sudo service postgresql stop", "sudo service postgresql restart $PG_VERSION"],
|
|
79
|
-
before_script: [
|
|
80
|
-
...before_script_common,
|
|
81
|
-
'psql -c "CREATE DATABASE sedentary;" -U postgres',
|
|
82
|
-
"psql -c \"ALTER DATABASE sedentary SET timezone TO 'GMT';\" -U postgres",
|
|
83
|
-
'export SPG=\'{"database":"sedentary","password":"postgres","user":"postgres"}\''
|
|
84
|
-
],
|
|
85
|
-
env: {
|
|
86
|
-
global: ["CC_TEST_REPORTER_ID=c7519657dfea145349c1b7a98f7134f033c25f598b40ad5b077744eb4beb7c66"],
|
|
87
|
-
matrix: ["PG_VERSION=14", "PG_VERSION=13", "PG_VERSION=12", "PG_VERSION=11", "PG_VERSION=10"]
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
};
|
|
91
|
-
function sort(obj) {
|
|
92
|
-
const ret = {};
|
|
93
|
-
if (obj instanceof Array || !(obj instanceof Object))
|
|
94
|
-
return obj;
|
|
95
|
-
Object.entries(obj)
|
|
96
|
-
.sort(([a], [b]) => (a < b ? -1 : 1))
|
|
97
|
-
.forEach(([k, v]) => (ret[k] = sort(v)));
|
|
98
|
-
return ret;
|
|
99
|
-
}
|
|
100
|
-
(async function () {
|
|
101
|
-
if (process.argv[2] === "gitignore")
|
|
102
|
-
writeFile(".gitignore", [...git, ...common].join("\n"), "utf-8");
|
|
103
|
-
if (process.argv[2] === "npmignore")
|
|
104
|
-
writeFile(".npmignore", [...npm, ...common].join("\n"), "utf-8");
|
|
105
|
-
if (process.argv[2] === "travis")
|
|
106
|
-
writeFile(".travis.yml", yamljs_1.default.stringify(sort(Object.assign(Object.assign({}, travis.common), travis[npm_package_name])), 4, 2), "utf-8");
|
|
107
|
-
if (process.argv[2] === "packagejson") {
|
|
108
|
-
const bugs = `https://github.com/iccicci/sedentary${urls[npm_package_name]}/issues`;
|
|
109
|
-
const description = "The ORM which never needs to migrate" + descriptions[npm_package_name];
|
|
110
|
-
const homepage = `https://github.com/iccicci/sedentary${urls[npm_package_name]}#readme`;
|
|
111
|
-
const repository = `https://github.com/iccicci/sedentary${urls[npm_package_name]}`;
|
|
112
|
-
const pkg = JSON.parse(await readFile("package.json", "utf-8"));
|
|
113
|
-
const { compilerOptions } = JSON.parse(await readFile("tsconfig.json", "utf-8"));
|
|
114
|
-
const { name, version } = pkg;
|
|
115
|
-
const tsd = { compilerOptions };
|
|
116
|
-
let { dependencies, devDependencies } = pkg;
|
|
117
|
-
try {
|
|
118
|
-
const { version } = JSON.parse(await readFile("../package.json", "utf-8"));
|
|
119
|
-
dependencies = Object.assign(Object.assign({}, deps[npm_package_name]), { sedentary: version });
|
|
120
|
-
devDependencies = Object.assign(Object.assign({}, devDependencies), devd[npm_package_name]);
|
|
121
|
-
}
|
|
122
|
-
catch (e) { }
|
|
123
|
-
await writeFile("package.json", JSON.stringify(sort(Object.assign(Object.assign({}, packagejson), { bugs, dependencies, devDependencies, description, homepage, name, repository, tsd, version })), null, 2), "utf-8");
|
|
124
|
-
}
|
|
125
|
-
if (process.argv[2] === "version") {
|
|
126
|
-
const pkg = JSON.parse(await readFile("package.json", "utf-8"));
|
|
127
|
-
pkg.version = VERSION;
|
|
128
|
-
await writeFile("package.json", JSON.stringify(pkg, null, 2), "utf-8");
|
|
129
|
-
}
|
|
130
|
-
})();
|