sedentary 0.0.13 → 0.0.17
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 +3 -4
- package/index.d.ts +83 -45
- package/index.js +150 -127
- package/lib/db.d.ts +37 -46
- package/lib/db.js +20 -30
- package/lib/log.d.ts +4 -0
- package/lib/log.js +20 -0
- package/lib/log.ts +22 -0
- package/lib/minidb.d.ts +2 -2
- package/lib/minidb.js +95 -58
- package/package.json +10 -7
- package/requirements.txt +2 -0
- package/tmp.js +0 -123
package/README.md
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
[![Stars][stars-badge]][github-url]
|
|
10
10
|
|
|
11
11
|
[![Types][types-badge]][npm-url]
|
|
12
|
+
[![Documentation][doc-badge]][doc-url]
|
|
12
13
|
[![Dependents][deps-badge]][npm-url]
|
|
13
14
|
[![Donate][donate-badge]][donate-url]
|
|
14
15
|
|
|
@@ -16,6 +17,8 @@
|
|
|
16
17
|
[code-url]: https://codeclimate.com/github/iccicci/sedentary
|
|
17
18
|
[cover-badge]: https://codeclimate.com/github/iccicci/sedentary/badges/coverage.svg
|
|
18
19
|
[deps-badge]: https://badgen.net/npm/dependents/sedentary?icon=npm&cache=300
|
|
20
|
+
[doc-badge]: https://readthedocs.org/projects/sedentary/badge/?version=latest
|
|
21
|
+
[doc-url]: https://sedentary.readthedocs.io/
|
|
19
22
|
[donate-badge]: https://badgen.net/badge/donate/bitcoin?icon=bitcoin&cache=300
|
|
20
23
|
[donate-url]: https://blockchain.info/address/1Md9WFAHrXTb3yPBwQWmUfv2RmzrtbHioB
|
|
21
24
|
[github-url]: https://github.com/iccicci/sedentary
|
|
@@ -115,10 +118,6 @@ To work with the package under Windows, be sure to configure `bash.exe` as your
|
|
|
115
118
|
|
|
116
119
|
Do not hesitate to report any bug or inconsistency [@github](https://github.com/iccicci/sedentary/issues).
|
|
117
120
|
|
|
118
|
-
# ChangeLog
|
|
119
|
-
|
|
120
|
-
[ChangeLog](https://github.com/iccicci/sedentary/blob/master/CHANGELOG.md)
|
|
121
|
-
|
|
122
121
|
# Donating
|
|
123
122
|
|
|
124
123
|
If you find useful this package, please consider the opportunity to donate some satoshis to this bitcoin address:
|
package/index.d.ts
CHANGED
|
@@ -1,79 +1,117 @@
|
|
|
1
|
-
import { DB, Entry,
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { DB, Entry, Meta, Natural, Type } from "./lib/db";
|
|
2
|
+
export { Entry, Natural, Type } from "./lib/db";
|
|
3
|
+
export declare type TypeDefinition<N extends Natural, E> = (() => Type<N, E>) | Type<N, E>;
|
|
4
|
+
export interface AttributeOptions<N extends Natural, E> {
|
|
4
5
|
defaultValue?: N;
|
|
5
6
|
fieldName?: string;
|
|
6
7
|
notNull?: boolean;
|
|
7
8
|
type: TypeDefinition<N, E>;
|
|
8
9
|
unique?: boolean;
|
|
9
10
|
}
|
|
10
|
-
declare type
|
|
11
|
-
declare type
|
|
12
|
-
[key: string]:
|
|
11
|
+
export declare type AttributeDefinition<N extends Natural, E> = TypeDefinition<N, E> | AttributeOptions<N, E>;
|
|
12
|
+
export declare type AttributesDefinition = {
|
|
13
|
+
[key: string]: AttributeDefinition<Natural, unknown>;
|
|
13
14
|
};
|
|
14
|
-
declare type
|
|
15
|
-
declare type
|
|
16
|
-
|
|
17
|
-
[f in keyof F]?: ForeignKeyFileds<F[f], f>;
|
|
15
|
+
declare type KeysAttributes<T, k> = T extends AttributeDefinition<Natural, infer E> ? (E extends Entry ? k : never) : never;
|
|
16
|
+
declare type Keys<F extends AttributesDefinition> = {
|
|
17
|
+
[f in keyof F]?: KeysAttributes<F[f], f>;
|
|
18
18
|
}[keyof F];
|
|
19
19
|
declare type Methods<T> = {
|
|
20
20
|
[key: string]: (this: T) => unknown;
|
|
21
21
|
};
|
|
22
|
-
declare type Native__<T> = T extends Type<infer N,
|
|
22
|
+
declare type Native__<T> = T extends Type<infer N, unknown> ? N : never;
|
|
23
23
|
declare type Native_<T> = T extends () => Type<infer N, infer E> ? Native__<Type<N, E>> : Native__<T>;
|
|
24
|
-
declare type Native<T> = T extends
|
|
25
|
-
declare type Parent<T> = T extends Meta<Natural, infer
|
|
26
|
-
declare type
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
24
|
+
declare type Native<T> = T extends AttributeOptions<infer N, infer E> ? Native__<Type<N, E>> : Native_<T>;
|
|
25
|
+
declare type Parent<T> = T extends Meta<Natural, infer E> ? E : never;
|
|
26
|
+
export declare type IndexAttributes = string[] | string;
|
|
27
|
+
export interface IndexOptions {
|
|
28
|
+
attributes: IndexAttributes;
|
|
29
|
+
type?: "btree" | "hash";
|
|
30
|
+
unique?: boolean;
|
|
31
|
+
}
|
|
32
|
+
export declare type IndexDefinition = IndexAttributes | IndexOptions;
|
|
33
|
+
export declare type IndexesDefinition = {
|
|
34
|
+
[key: string]: IndexDefinition;
|
|
35
|
+
};
|
|
36
|
+
declare type BaseModelOptions<T> = {
|
|
37
|
+
indexes?: IndexesDefinition;
|
|
30
38
|
init?: (this: T) => void;
|
|
31
|
-
methods?: M;
|
|
32
39
|
sync?: boolean;
|
|
33
40
|
tableName?: string;
|
|
34
41
|
};
|
|
35
|
-
declare type
|
|
36
|
-
|
|
42
|
+
export declare type ModelOptions<K extends string, M extends Methods<T>, P extends Meta<Natural, Entry>, T extends Entry> = BaseModelOptions<T> & {
|
|
43
|
+
int8id?: boolean;
|
|
44
|
+
methods?: M;
|
|
45
|
+
parent?: P;
|
|
46
|
+
primaryKey?: K;
|
|
47
|
+
};
|
|
48
|
+
declare type ForeignKey<T> = T extends AttributeDefinition<Natural, infer E> ? () => Promise<E> : never;
|
|
49
|
+
declare type ModelWithMetods<A extends AttributesDefinition, M> = {
|
|
50
|
+
[a in keyof A]?: Native<A[a]>;
|
|
37
51
|
} & {
|
|
38
|
-
[
|
|
52
|
+
[a in Keys<A> & string as `${a}Load`]?: ForeignKey<A[a]>;
|
|
39
53
|
} & M;
|
|
40
|
-
declare type
|
|
41
|
-
[
|
|
54
|
+
declare type Model<A extends AttributesDefinition> = {
|
|
55
|
+
[a in keyof A]?: Native<A[a]>;
|
|
42
56
|
} & {
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
|
|
57
|
+
[a in Keys<A> & string as `${a}Load`]?: ForeignKey<A[a]>;
|
|
58
|
+
};
|
|
59
|
+
declare type Ancestor<A, N extends Natural, T extends Entry> = (new () => T) & {
|
|
60
|
+
[a in keyof A]?: Meta<Native<A[a]>, T>;
|
|
61
|
+
} & {
|
|
62
|
+
load: (boh: boolean) => Promise<T[]>;
|
|
63
|
+
} & Meta<N, T>;
|
|
64
|
+
export interface SedentaryOptions {
|
|
65
|
+
log?: ((message: string) => void) | null;
|
|
66
|
+
serverless?: boolean;
|
|
47
67
|
sync?: boolean;
|
|
48
68
|
}
|
|
49
69
|
export declare class Sedentary {
|
|
50
70
|
protected db: DB;
|
|
51
|
-
protected log: (
|
|
52
|
-
|
|
71
|
+
protected log: (...data: unknown[]) => void;
|
|
72
|
+
protected sync: boolean;
|
|
53
73
|
private models;
|
|
54
|
-
constructor(filename: string, options?:
|
|
55
|
-
DATETIME(): Type<Date,
|
|
56
|
-
FKEY<N extends Natural, E extends Entry>(
|
|
57
|
-
INT(size?: number): Type<number,
|
|
58
|
-
INT8(): Type<string,
|
|
59
|
-
VARCHAR(size?: number): Type<string,
|
|
74
|
+
constructor(filename: string, options?: SedentaryOptions);
|
|
75
|
+
DATETIME(): Type<Date, unknown>;
|
|
76
|
+
FKEY<N extends Natural, E extends Entry>(attribute: Type<N, E>): Type<N, E>;
|
|
77
|
+
INT(size?: number): Type<number, unknown>;
|
|
78
|
+
INT8(): Type<string, unknown>;
|
|
79
|
+
VARCHAR(size?: number): Type<string, unknown>;
|
|
60
80
|
connect(): Promise<void>;
|
|
61
81
|
end(): Promise<void>;
|
|
62
|
-
model<
|
|
82
|
+
model<A extends AttributesDefinition, M extends Methods<T>, T extends Entry & {
|
|
83
|
+
id?: string;
|
|
84
|
+
} & ModelWithMetods<A, M>>(modelName: string, attributes: A, options?: BaseModelOptions<T> & {
|
|
85
|
+
int8id: true;
|
|
86
|
+
methods: M;
|
|
87
|
+
}): Ancestor<A, string, T>;
|
|
88
|
+
model<A extends AttributesDefinition, K extends keyof A, M extends Methods<T>, N extends K extends keyof A ? Native<A[K]> : never, T extends Entry & ModelWithMetods<A, M>>(modelName: string, attributes: A, options?: BaseModelOptions<T> & {
|
|
89
|
+
methods: M;
|
|
90
|
+
primaryKey: K;
|
|
91
|
+
}): Ancestor<A, N, T>;
|
|
92
|
+
model<A extends AttributesDefinition, M extends Methods<T>, P extends Meta<Natural, Entry>, N extends P extends Meta<infer N, Entry> ? N : never, T extends Parent<P> & ModelWithMetods<A, M>>(modelName: string, attributes: A, options?: BaseModelOptions<T> & {
|
|
93
|
+
methods: M;
|
|
94
|
+
parent: P;
|
|
95
|
+
}): Ancestor<A, N, T>;
|
|
96
|
+
model<A extends AttributesDefinition, M extends Methods<T>, T extends Entry & {
|
|
97
|
+
id?: number;
|
|
98
|
+
} & ModelWithMetods<A, M>>(modelName: string, attributes: A, options?: BaseModelOptions<T> & {
|
|
99
|
+
methods: M;
|
|
100
|
+
}): Ancestor<A, number, T>;
|
|
101
|
+
model<A extends AttributesDefinition, T extends Entry & {
|
|
63
102
|
id?: string;
|
|
64
|
-
} & Model<
|
|
103
|
+
} & Model<A>>(modelName: string, attributes: A, options?: BaseModelOptions<T> & {
|
|
65
104
|
int8id: true;
|
|
66
|
-
}): Ancestor<
|
|
67
|
-
model<
|
|
105
|
+
}): Ancestor<A, string, T>;
|
|
106
|
+
model<A extends AttributesDefinition, K extends keyof A, N extends K extends keyof A ? Native<A[K]> : never, T extends Entry & Model<A>>(modelName: string, attributes: A, options?: BaseModelOptions<T> & {
|
|
68
107
|
primaryKey: K;
|
|
69
|
-
}): Ancestor<
|
|
70
|
-
model<
|
|
108
|
+
}): Ancestor<A, N, T>;
|
|
109
|
+
model<A extends AttributesDefinition, P extends Meta<Natural, Entry>, N extends P extends Meta<infer N, Entry> ? N : never, T extends Parent<P> & Model<A>>(modelName: string, attributes: A, options?: BaseModelOptions<T> & {
|
|
71
110
|
parent: P;
|
|
72
|
-
}): Ancestor<
|
|
73
|
-
model<
|
|
111
|
+
}): Ancestor<A, N, T>;
|
|
112
|
+
model<A extends AttributesDefinition, T extends Entry & {
|
|
74
113
|
id?: number;
|
|
75
|
-
} & Model<
|
|
114
|
+
} & Model<A>>(modelName: string, attributes: A, options?: BaseModelOptions<T>): Ancestor<A, number, T>;
|
|
76
115
|
checkSize(size: number, message: string): number;
|
|
77
116
|
}
|
|
78
117
|
export declare const Package: typeof Sedentary;
|
|
79
|
-
export {};
|
package/index.js
CHANGED
|
@@ -1,33 +1,45 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Package = exports.Sedentary = void 0;
|
|
3
|
+
exports.Package = exports.Sedentary = exports.Type = exports.Entry = void 0;
|
|
4
4
|
const db_1 = require("./lib/db");
|
|
5
|
+
const log_1 = require("./lib/log");
|
|
5
6
|
const minidb_1 = require("./lib/minidb");
|
|
7
|
+
var db_2 = require("./lib/db");
|
|
8
|
+
Object.defineProperty(exports, "Entry", { enumerable: true, get: function () { return db_2.Entry; } });
|
|
9
|
+
Object.defineProperty(exports, "Type", { enumerable: true, get: function () { return db_2.Type; } });
|
|
6
10
|
const allowedOption = ["indexes", "init", "int8id", "methods", "parent", "primaryKey", "sync", "tableName", "type"];
|
|
11
|
+
const reservedNames = [
|
|
12
|
+
...["attributeName", "base", "class", "constructor", "defaultValue", "entry", "fieldName", "init", "isModel"],
|
|
13
|
+
...["load", "meta", "methods", "name", "primaryKey", "prototype", "save", "size", "tableName", "type"]
|
|
14
|
+
];
|
|
7
15
|
class Sedentary {
|
|
8
16
|
constructor(filename, options) {
|
|
9
17
|
this.sync = true;
|
|
10
18
|
this.models = {};
|
|
11
19
|
if (typeof filename !== "string")
|
|
12
|
-
throw new Error("Sedentary
|
|
20
|
+
throw new Error("new Sedentary: 'filename' argument: Wrong type, expected 'string'");
|
|
13
21
|
if (!options)
|
|
14
22
|
options = {};
|
|
15
23
|
if (!(options instanceof Object))
|
|
16
|
-
throw new Error("Sedentary
|
|
17
|
-
for (const k in options)
|
|
18
|
-
if (["log", "sync"].
|
|
19
|
-
throw new Error(`Sedentary
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
throw new Error("new Sedentary: 'options' argument: Wrong type, expected 'Object'");
|
|
25
|
+
for (const k in options)
|
|
26
|
+
if (!["log", "sync"].includes(k))
|
|
27
|
+
throw new Error(`new Sedentary: 'options' argument: Unknown '${k}' option`);
|
|
28
|
+
const { log, sync } = Object.assign({ sync: true }, options);
|
|
29
|
+
if (log !== null && log !== undefined && !(log instanceof Function))
|
|
30
|
+
throw new Error("new Sedentary: 'log' option: Wrong type, expected 'null' or 'Function'");
|
|
31
|
+
if (typeof sync !== "boolean")
|
|
32
|
+
throw new Error("new Sedentary: 'sync' option: Wrong type, expected 'boolean'");
|
|
33
|
+
this.log = (0, log_1.createLogger)(log);
|
|
24
34
|
this.db = new minidb_1.MiniDB(filename, this.log);
|
|
35
|
+
this.sync = sync;
|
|
25
36
|
}
|
|
26
37
|
DATETIME() {
|
|
27
38
|
return new db_1.Type({ base: Date, type: "DATETIME" });
|
|
28
39
|
}
|
|
29
|
-
FKEY(
|
|
30
|
-
|
|
40
|
+
FKEY(attribute) {
|
|
41
|
+
const { attributeName, base, fieldName, size, tableName, type } = attribute;
|
|
42
|
+
return new db_1.Type({ base, foreignKey: { attributeName, fieldName, tableName }, size, type });
|
|
31
43
|
}
|
|
32
44
|
INT(size) {
|
|
33
45
|
const message = "Sedentary.INT: 'size' argument: Wrong value, expected 2 or 4";
|
|
@@ -49,11 +61,11 @@ class Sedentary {
|
|
|
49
61
|
this.log("Connecting...");
|
|
50
62
|
await this.db.connect();
|
|
51
63
|
this.log("Connected, syncing...");
|
|
52
|
-
await this.db.
|
|
64
|
+
await this.db.syncDataBase();
|
|
53
65
|
this.log("Synced");
|
|
54
66
|
}
|
|
55
67
|
catch (e) {
|
|
56
|
-
this.log("Connecting:
|
|
68
|
+
this.log("Connecting:", e.message);
|
|
57
69
|
throw e;
|
|
58
70
|
}
|
|
59
71
|
}
|
|
@@ -62,166 +74,173 @@ class Sedentary {
|
|
|
62
74
|
await this.db.end();
|
|
63
75
|
this.log("Connection closed");
|
|
64
76
|
}
|
|
65
|
-
model(
|
|
66
|
-
if (typeof
|
|
77
|
+
model(modelName, attributes, options) {
|
|
78
|
+
if (typeof modelName !== "string")
|
|
67
79
|
throw new Error("Sedentary.model: 'name' argument: Wrong type, expected 'string'");
|
|
68
|
-
if (this.models[
|
|
69
|
-
throw new Error(`Sedentary.model: '${
|
|
70
|
-
if (!
|
|
71
|
-
|
|
72
|
-
if (!(
|
|
73
|
-
throw new Error(`Sedentary.model: '${
|
|
80
|
+
if (this.models[modelName])
|
|
81
|
+
throw new Error(`Sedentary.model: '${modelName}' model: Model already defined`);
|
|
82
|
+
if (!attributes)
|
|
83
|
+
attributes = {};
|
|
84
|
+
if (!(attributes instanceof Object))
|
|
85
|
+
throw new Error(`Sedentary.model: '${modelName}' model: 'attributes' argument: Wrong type, expected 'Object'`);
|
|
74
86
|
if (!options)
|
|
75
87
|
options = {};
|
|
76
88
|
if (!(options instanceof Object))
|
|
77
|
-
throw new Error(`Sedentary.model: '${
|
|
89
|
+
throw new Error(`Sedentary.model: '${modelName}' model: 'options' argument: Wrong type, expected 'Object'`);
|
|
78
90
|
for (const k in options)
|
|
79
|
-
if (allowedOption.
|
|
80
|
-
throw new Error(`Sedentary.model: '${
|
|
91
|
+
if (!allowedOption.includes(k))
|
|
92
|
+
throw new Error(`Sedentary.model: '${modelName}' model: 'options' argument: Unknown '${k}' option`);
|
|
81
93
|
if (options.int8id && options.parent)
|
|
82
|
-
throw new Error(`Sedentary.model: '${
|
|
94
|
+
throw new Error(`Sedentary.model: '${modelName}' model: 'int8id' and 'parent' options conflict each other`);
|
|
83
95
|
if (options.int8id && options.primaryKey)
|
|
84
|
-
throw new Error(`Sedentary.model: '${
|
|
96
|
+
throw new Error(`Sedentary.model: '${modelName}' model: 'int8id' and 'primaryKey' options conflict each other`);
|
|
85
97
|
if (options.parent && options.primaryKey)
|
|
86
|
-
throw new Error(`Sedentary.model: '${
|
|
87
|
-
|
|
88
|
-
const { indexes, int8id, parent, primaryKey, sync, tableName } = Object.assign({ sync: this.sync, tableName:
|
|
98
|
+
throw new Error(`Sedentary.model: '${modelName}' model: 'parent' and 'primaryKey' options conflict each other`);
|
|
99
|
+
let autoIncrement = true;
|
|
100
|
+
const { indexes, int8id, parent, primaryKey, sync, tableName } = Object.assign({ sync: this.sync, tableName: modelName }, options);
|
|
89
101
|
let { methods } = options;
|
|
102
|
+
let aarray = int8id
|
|
103
|
+
? [new db_1.Attribute(Object.assign(Object.assign({}, this.INT8()), { attributeName: "id", fieldName: "id", modelName, notNull: true, tableName, unique: true }))]
|
|
104
|
+
: [new db_1.Attribute(Object.assign(Object.assign({}, this.INT(4)), { attributeName: "id", fieldName: "id", modelName, notNull: true, tableName, unique: true }))];
|
|
105
|
+
let constraints = [{ attribute: aarray[0], constraintName: `${tableName}_id_unique`, type: "u" }];
|
|
90
106
|
const iarray = [];
|
|
91
|
-
const
|
|
92
|
-
let farray = int8id
|
|
93
|
-
? [new db_1.Field({ fieldName: "id", notNull: true, size: 8, type: "INT8", unique: true })]
|
|
94
|
-
: [new db_1.Field({ fieldName: "id", notNull: true, size: 4, type: "INT", unique: true })];
|
|
107
|
+
const pk = aarray[0];
|
|
95
108
|
if (methods && !(methods instanceof Object))
|
|
96
|
-
throw new Error(`Sedentary.model: '${
|
|
109
|
+
throw new Error(`Sedentary.model: '${modelName}' model: 'methods' option: Wrong type, expected 'Object'`);
|
|
97
110
|
if (parent) {
|
|
98
|
-
methods = (methods ? Object.assign(Object.assign({}, (parent.methods || {})), methods) : parent.methods);
|
|
99
111
|
try {
|
|
100
112
|
if (!parent.isModel())
|
|
101
113
|
throw new Error();
|
|
102
114
|
}
|
|
103
115
|
catch (e) {
|
|
104
|
-
throw new Error(`Sedentary.model: '${
|
|
116
|
+
throw new Error(`Sedentary.model: '${modelName}' model: 'parent' option: Wrong type, expected 'Model'`);
|
|
105
117
|
}
|
|
118
|
+
methods = (methods ? Object.assign(Object.assign({}, (parent.methods || {})), methods) : parent.methods);
|
|
106
119
|
}
|
|
107
120
|
if (primaryKey && typeof primaryKey !== "string")
|
|
108
|
-
throw new Error(`Sedentary.model: '${
|
|
109
|
-
if (primaryKey && Object.keys(
|
|
110
|
-
throw new Error(`Sedentary.model: '${
|
|
111
|
-
if (parent || primaryKey)
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
+
throw new Error(`Sedentary.model: '${modelName}' model: 'primaryKey' option: Wrong type, expected 'string'`);
|
|
122
|
+
if (primaryKey && !Object.keys(attributes).includes(primaryKey))
|
|
123
|
+
throw new Error(`Sedentary.model: '${modelName}' model: 'primaryKey' option: Attribute '${primaryKey}' does not exists`);
|
|
124
|
+
if (parent || primaryKey) {
|
|
125
|
+
autoIncrement = false;
|
|
126
|
+
aarray = [];
|
|
127
|
+
constraints = [];
|
|
128
|
+
}
|
|
129
|
+
for (const attributeName of Object.keys(attributes).sort()) {
|
|
130
|
+
if (reservedNames.includes(attributeName))
|
|
131
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${attributeName}' attribute: Reserved name`);
|
|
132
|
+
const call = (defaultValue, fieldName, notNull, unique, func, message1, message2) => {
|
|
133
|
+
if (func === this.FKEY)
|
|
134
|
+
throw new Error(`${message1} 'this.FKEY' can't be used directly`);
|
|
135
|
+
if (func !== this.DATETIME && func !== this.INT && func !== this.INT8 && func !== this.VARCHAR)
|
|
136
|
+
throw new Error(`${message1} ${message2}`);
|
|
137
|
+
return new db_1.Attribute(Object.assign({ attributeName, defaultValue, fieldName, modelName, notNull, tableName, unique }, func()));
|
|
138
|
+
};
|
|
139
|
+
const attributeDefinition = attributes[attributeName];
|
|
140
|
+
let { base, defaultValue, fieldName, foreignKey, notNull, size, type, unique } = (() => {
|
|
121
141
|
const ret = (() => {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
};
|
|
129
|
-
|
|
130
|
-
return new db_1.Field(Object.assign({ fieldName: fname }, Object.assign({ notNull: false }, field)));
|
|
131
|
-
if (field instanceof Function)
|
|
132
|
-
return call(undefined, fname, false, false, field, `Sedentary.model: '${name}' model: '${fname}' field: Wrong type, expected 'Field'`);
|
|
133
|
-
if (!(field instanceof Object))
|
|
134
|
-
throw new Error(`Sedentary.model: '${name}' model: '${fname}' field: Wrong field type, expected 'Field'`);
|
|
135
|
-
({ defaultValue, fieldName, notNull, unique, type } = Object.assign({ notNull: false }, field));
|
|
136
|
-
if (!fieldName)
|
|
137
|
-
fieldName = fname;
|
|
142
|
+
if (attributeDefinition instanceof db_1.Type)
|
|
143
|
+
return new db_1.Attribute(Object.assign({ attributeName, fieldName: attributeName, modelName, notNull: false, tableName }, attributeDefinition));
|
|
144
|
+
if (attributeDefinition instanceof Function)
|
|
145
|
+
return call(undefined, attributeName, false, false, attributeDefinition, `Sedentary.model: '${modelName}' model: '${attributeName}' attribute:`, "Wrong type, expected 'Attribute'");
|
|
146
|
+
if (!(attributeDefinition instanceof Object))
|
|
147
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${attributeName}' attribute: Wrong attribute type, expected 'Attribute'`);
|
|
148
|
+
const attributeDefaults = Object.assign({ defaultValue: undefined, fieldName: attributeName, notNull: false, unique: false }, attributeDefinition);
|
|
149
|
+
const { defaultValue, fieldName, notNull, unique, type } = attributeDefaults;
|
|
138
150
|
if (defaultValue === null)
|
|
139
|
-
throw new Error(`Sedentary.model: '${
|
|
151
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${attributeName}' attribute: 'defaultValue' option: Does 'null' default value really makes sense?`);
|
|
140
152
|
if (typeof fieldName !== "string")
|
|
141
|
-
throw new Error(`Sedentary.model: '${
|
|
142
|
-
if (
|
|
143
|
-
throw new Error(`Sedentary.model: '${
|
|
153
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${attributeName}' attribute: 'fieldName' option: Wrong type, expected 'string'`);
|
|
154
|
+
if (typeof notNull !== "boolean")
|
|
155
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${attributeName}' attribute: 'notNull' option: Wrong type, expected 'boolean'`);
|
|
156
|
+
if (typeof unique !== "boolean")
|
|
157
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${attributeName}' attribute: 'unique' option: Wrong type, expected 'boolean'`);
|
|
158
|
+
if (type === undefined)
|
|
159
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${attributeName}' attribute: Missing 'type' option`);
|
|
144
160
|
if (type instanceof db_1.Type)
|
|
145
|
-
return new db_1.
|
|
161
|
+
return new db_1.Attribute(Object.assign({ attributeName, defaultValue, fieldName, modelName, notNull, tableName, unique }, type));
|
|
146
162
|
if (type instanceof Function)
|
|
147
|
-
return call(defaultValue, fieldName, notNull, unique, type, `Sedentary.model: '${
|
|
148
|
-
throw new Error(`Sedentary.model: '${
|
|
163
|
+
return call(defaultValue, fieldName, notNull, unique, type, `Sedentary.model: '${modelName}' model: '${attributeName}' attribute: 'type' option:`, "Wrong type, expected 'Type'");
|
|
164
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${attributeName}' attribute: 'type' option: Wrong type, expected 'Type'`);
|
|
149
165
|
})();
|
|
150
166
|
const { base, defaultValue } = ret;
|
|
151
167
|
if (defaultValue !== undefined) {
|
|
152
168
|
if (base === Date && !(defaultValue instanceof Date))
|
|
153
|
-
throw new Error(`Sedentary.model: '${
|
|
169
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${attributeName}' attribute: 'defaultValue' option: Wrong type, expected 'Date'`);
|
|
154
170
|
if (base === Number && typeof defaultValue !== "number")
|
|
155
|
-
throw new Error(`Sedentary.model: '${
|
|
171
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${attributeName}' attribute: 'defaultValue' option: Wrong type, expected 'number'`);
|
|
156
172
|
if (base === String && typeof defaultValue !== "string")
|
|
157
|
-
throw new Error(`Sedentary.model: '${
|
|
173
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${attributeName}' attribute: 'defaultValue' option: Wrong type, expected 'string'`);
|
|
158
174
|
}
|
|
159
175
|
return ret;
|
|
160
176
|
})();
|
|
161
|
-
if (primaryKey ===
|
|
177
|
+
if (primaryKey === attributeName) {
|
|
162
178
|
notNull = true;
|
|
163
179
|
unique = true;
|
|
164
180
|
}
|
|
165
181
|
if (defaultValue)
|
|
166
182
|
notNull = true;
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
183
|
+
const attribute = new db_1.Attribute({ attributeName, base, defaultValue, fieldName, foreignKey, modelName, notNull, size, tableName, type, unique });
|
|
184
|
+
aarray.push(attribute);
|
|
185
|
+
if (foreignKey)
|
|
186
|
+
constraints.push({ attribute, constraintName: `fkey_${fieldName}_${foreignKey.tableName}_${foreignKey.fieldName}`, type: "f" });
|
|
187
|
+
if (unique)
|
|
188
|
+
constraints.push({ attribute, constraintName: `${tableName}_${fieldName}_unique`, type: "u" });
|
|
170
189
|
}
|
|
171
190
|
if (indexes) {
|
|
172
|
-
const flds =
|
|
191
|
+
const flds = attributes;
|
|
173
192
|
if (!(indexes instanceof Object))
|
|
174
|
-
throw new Error(`Sedentary.model: '${
|
|
175
|
-
for (const
|
|
176
|
-
if (
|
|
177
|
-
throw new Error(`Sedentary.model: '${
|
|
178
|
-
const idx = indexes[
|
|
179
|
-
const
|
|
180
|
-
if (typeof
|
|
181
|
-
throw new Error(`Sedentary.model: '${
|
|
182
|
-
if (!(
|
|
183
|
-
throw new Error(`Sedentary.model: '${
|
|
193
|
+
throw new Error(`Sedentary.model: '${modelName}' model: 'indexes' option: Wrong type, expected 'Object'`);
|
|
194
|
+
for (const indexName in indexes) {
|
|
195
|
+
if (aarray.filter(({ fieldName, unique }) => unique && `${tableName}_${fieldName}_unique` === indexName).length !== 0)
|
|
196
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${indexName}' index: index name already inferred by the unique constraint on an attribute`);
|
|
197
|
+
const idx = indexes[indexName];
|
|
198
|
+
const checkAttribute = (attribute, l) => {
|
|
199
|
+
if (typeof attribute !== "string")
|
|
200
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${indexName}' index: #${l + 1} attribute: Wrong type, expected 'string'`);
|
|
201
|
+
if (!(attribute in flds))
|
|
202
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${indexName}' index: #${l + 1} attribute: Unknown attribute '${attribute}'`);
|
|
184
203
|
};
|
|
185
|
-
let
|
|
204
|
+
let attributes;
|
|
186
205
|
let type = "btree";
|
|
187
206
|
let unique = false;
|
|
188
207
|
if (idx instanceof Array) {
|
|
189
|
-
idx.forEach(
|
|
190
|
-
|
|
208
|
+
idx.forEach(checkAttribute);
|
|
209
|
+
attributes = idx;
|
|
191
210
|
}
|
|
192
211
|
else if (typeof idx === "string") {
|
|
193
|
-
|
|
194
|
-
|
|
212
|
+
checkAttribute(idx, 0);
|
|
213
|
+
attributes = [idx];
|
|
195
214
|
}
|
|
196
215
|
else if (idx instanceof Object) {
|
|
197
216
|
for (const k in idx)
|
|
198
|
-
if (["
|
|
199
|
-
throw new Error(`Sedentary.model: '${
|
|
200
|
-
({
|
|
201
|
-
if (!
|
|
202
|
-
throw new Error(`Sedentary.model: '${
|
|
203
|
-
if (
|
|
204
|
-
|
|
205
|
-
else if (typeof
|
|
206
|
-
|
|
207
|
-
|
|
217
|
+
if (!["attributes", "type", "unique"].includes(k))
|
|
218
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${indexName}' index: Unknown index option '${k}'`);
|
|
219
|
+
({ attributes, type, unique } = Object.assign({ type: "btree", unique: false }, idx));
|
|
220
|
+
if (!attributes)
|
|
221
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${indexName}' index: Missing 'attributes' option`);
|
|
222
|
+
if (attributes instanceof Array)
|
|
223
|
+
attributes.forEach(checkAttribute);
|
|
224
|
+
else if (typeof attributes === "string") {
|
|
225
|
+
checkAttribute(attributes, 0);
|
|
226
|
+
attributes = [attributes];
|
|
208
227
|
}
|
|
209
228
|
else
|
|
210
|
-
throw new Error(`Sedentary.model: '${
|
|
229
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${indexName}' index: 'attributes' option: Wrong type, expected 'FieldNames'`);
|
|
211
230
|
if (typeof type !== "string")
|
|
212
|
-
throw new Error(`Sedentary.model: '${
|
|
213
|
-
if (["btree", "hash"].
|
|
214
|
-
throw new Error(`Sedentary.model: '${
|
|
231
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${indexName}' index: 'type' option: Wrong type, expected 'string'`);
|
|
232
|
+
if (!["btree", "hash"].includes(type))
|
|
233
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${indexName}' index: 'type' option: Wrong value, expected 'btree' or 'hash'`);
|
|
215
234
|
if (typeof unique !== "boolean")
|
|
216
|
-
throw new Error(`Sedentary.model: '${
|
|
235
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${indexName}' index: 'unique' option: Wrong type, expected 'boolean'`);
|
|
217
236
|
}
|
|
218
237
|
else
|
|
219
|
-
throw new Error(`Sedentary.model: '${
|
|
220
|
-
iarray.push({ fields
|
|
238
|
+
throw new Error(`Sedentary.model: '${modelName}' model: '${indexName}' index: Wrong type, expected 'Object'`);
|
|
239
|
+
iarray.push({ fields: attributes, indexName, type, unique });
|
|
221
240
|
}
|
|
222
241
|
}
|
|
223
|
-
this.db.
|
|
224
|
-
this.models[
|
|
242
|
+
this.db.tables.push(new db_1.Table({ autoIncrement, constraints, attributes: aarray, indexes: iarray, parent, sync, tableName }));
|
|
243
|
+
this.models[modelName] = true;
|
|
225
244
|
const init = parent
|
|
226
245
|
? options.init
|
|
227
246
|
? function () {
|
|
@@ -231,7 +250,7 @@ class Sedentary {
|
|
|
231
250
|
: parent.init
|
|
232
251
|
: options.init;
|
|
233
252
|
const flds = {};
|
|
234
|
-
for (const key in
|
|
253
|
+
for (const key in attributes)
|
|
235
254
|
flds[key] = null;
|
|
236
255
|
class Class {
|
|
237
256
|
constructor() {
|
|
@@ -241,7 +260,7 @@ class Sedentary {
|
|
|
241
260
|
save() {
|
|
242
261
|
return new Promise((resolve, reject) => {
|
|
243
262
|
const save = () => reject(new Error("eh no"));
|
|
244
|
-
Object.defineProperty(save, "name", { value:
|
|
263
|
+
Object.defineProperty(save, "name", { value: modelName + ".save" });
|
|
245
264
|
setTimeout(save, 10);
|
|
246
265
|
});
|
|
247
266
|
}
|
|
@@ -251,15 +270,19 @@ class Sedentary {
|
|
|
251
270
|
return resolve([new Class()]);
|
|
252
271
|
reject(new Error("boh"));
|
|
253
272
|
}, 10));
|
|
254
|
-
Object.defineProperty(load, "name", { value:
|
|
255
|
-
const meta = { tableName, primaryKey, init, methods };
|
|
256
|
-
Object.defineProperty(Class, "
|
|
273
|
+
Object.defineProperty(load, "name", { value: modelName + ".load" });
|
|
274
|
+
const meta = { base: Number, type: "meta", tableName, primaryKey, init, methods };
|
|
275
|
+
Object.defineProperty(Class, "isModel", { value: () => true });
|
|
257
276
|
Object.defineProperty(Class, "load", { value: load });
|
|
258
277
|
Object.defineProperty(Class, "meta", { value: new db_1.Meta(meta) });
|
|
259
|
-
Object.defineProperty(Class
|
|
278
|
+
Object.defineProperty(Class, "name", { value: modelName });
|
|
279
|
+
Object.defineProperty(Class.prototype.save, "name", { value: modelName + ".save" });
|
|
260
280
|
Object.assign(Class, new db_1.Meta(meta));
|
|
261
|
-
Object.assign(Class, Object.assign(Object.assign({}, fields), { isModel: () => true }));
|
|
262
281
|
Object.assign(Class.prototype, methods);
|
|
282
|
+
for (const attribute of aarray)
|
|
283
|
+
Object.defineProperty(Class, attribute.attributeName, { value: attribute });
|
|
284
|
+
for (const key of ["attributeName", "base", "fieldName", "modelName", "size", "type", "unique"])
|
|
285
|
+
Object.defineProperty(Class, key, { value: pk[key] });
|
|
263
286
|
return Class;
|
|
264
287
|
}
|
|
265
288
|
checkSize(size, message) {
|
|
@@ -273,12 +296,11 @@ class Sedentary {
|
|
|
273
296
|
exports.Sedentary = Sedentary;
|
|
274
297
|
exports.Package = Sedentary;
|
|
275
298
|
const db = new Sedentary("gino");
|
|
276
|
-
const Users = db.model("User", { foo: db.INT(), bar: db.VARCHAR() }, {});
|
|
277
|
-
|
|
299
|
+
const Users = db.model("User", { foo: db.INT(), bar: { type: db.VARCHAR(), unique: true } }, {});
|
|
300
|
+
class Item extends db.model("Item", {
|
|
278
301
|
num: db.FKEY(Users),
|
|
279
302
|
str: db.VARCHAR()
|
|
280
|
-
}
|
|
281
|
-
class Item extends db.model("Item", fields, {
|
|
303
|
+
}, {
|
|
282
304
|
init: function () {
|
|
283
305
|
this.num = 0;
|
|
284
306
|
this.str = "0";
|
|
@@ -301,6 +323,7 @@ class Super extends db.model("Super", {
|
|
|
301
323
|
this.num = 0;
|
|
302
324
|
const a = this.nLoad ? await this.nLoad() : { prova: () => null };
|
|
303
325
|
a.prova();
|
|
326
|
+
this.prova();
|
|
304
327
|
}
|
|
305
328
|
}) {
|
|
306
329
|
}
|
|
@@ -311,7 +334,7 @@ class Next extends db.model("Next", { a: db.INT, b: db.INT }, {
|
|
|
311
334
|
primaryKey: "a"
|
|
312
335
|
}) {
|
|
313
336
|
}
|
|
314
|
-
class Current extends db.model("Current", { b: db.FKEY(Next) }, {
|
|
337
|
+
class Current extends db.model("Current", { b: { type: db.FKEY(Next), unique: true } }, {
|
|
315
338
|
init: function () {
|
|
316
339
|
this.b = 24;
|
|
317
340
|
}
|