sedentary 0.0.13 → 0.0.14
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/index.d.ts +76 -40
- package/index.js +128 -110
- package/lib/db.d.ts +27 -35
- package/lib/db.js +7 -11
- 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 +50 -33
- package/package.json +1 -1
- package/sedentary-pg/LICENSE +21 -0
- package/sedentary-pg/README.md +32 -0
- package/sedentary-pg/lib/pgdb.ts +341 -0
- package/sedentary-pg/package-lock.json +6765 -0
- package/sedentary-pg/package.json +63 -0
- package/tmp.js +0 -123
package/index.d.ts
CHANGED
|
@@ -1,79 +1,115 @@
|
|
|
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
|
|
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 BaseModelOptions<T> = {
|
|
27
34
|
indexes?: {
|
|
28
|
-
[key: string]:
|
|
35
|
+
[key: string]: IndexDefinition;
|
|
29
36
|
};
|
|
30
37
|
init?: (this: T) => void;
|
|
31
|
-
methods?: M;
|
|
32
38
|
sync?: boolean;
|
|
33
39
|
tableName?: string;
|
|
34
40
|
};
|
|
35
|
-
declare type
|
|
36
|
-
|
|
41
|
+
export declare type ModelOptions<K extends string, M extends Methods<T>, P extends Meta<Natural, Entry>, T extends Entry> = BaseModelOptions<T> & {
|
|
42
|
+
int8id?: boolean;
|
|
43
|
+
methods?: M;
|
|
44
|
+
parent?: P;
|
|
45
|
+
primaryKey?: K;
|
|
46
|
+
};
|
|
47
|
+
declare type ForeignKey<T> = T extends AttributeDefinition<Natural, infer E> ? () => Promise<E> : never;
|
|
48
|
+
declare type ModelWithMetods<A extends AttributesDefinition, M> = {
|
|
49
|
+
[a in keyof A]?: Native<A[a]>;
|
|
37
50
|
} & {
|
|
38
|
-
[
|
|
51
|
+
[a in Keys<A> & string as `${a}Load`]?: ForeignKey<A[a]>;
|
|
39
52
|
} & M;
|
|
40
|
-
declare type
|
|
41
|
-
[
|
|
53
|
+
declare type Model<A extends AttributesDefinition> = {
|
|
54
|
+
[a in keyof A]?: Native<A[a]>;
|
|
55
|
+
} & {
|
|
56
|
+
[a in Keys<A> & string as `${a}Load`]?: ForeignKey<A[a]>;
|
|
57
|
+
};
|
|
58
|
+
declare type Ancestor<A, N extends Natural, T extends Entry> = (new () => T) & {
|
|
59
|
+
[a in keyof A]?: Meta<Native<A[a]>, T>;
|
|
42
60
|
} & {
|
|
43
|
-
load: (boh: boolean) => Promise<
|
|
44
|
-
} & Meta<N,
|
|
61
|
+
load: (boh: boolean) => Promise<T[]>;
|
|
62
|
+
} & Meta<N, T>;
|
|
45
63
|
export interface SchemaOptions {
|
|
46
|
-
log?: (message: string) => void;
|
|
64
|
+
log?: ((message: string) => void) | null;
|
|
47
65
|
sync?: boolean;
|
|
48
66
|
}
|
|
49
67
|
export declare class Sedentary {
|
|
50
68
|
protected db: DB;
|
|
51
|
-
protected log: (
|
|
69
|
+
protected log: (...data: unknown[]) => void;
|
|
52
70
|
private sync;
|
|
53
71
|
private models;
|
|
54
72
|
constructor(filename: string, options?: SchemaOptions);
|
|
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,
|
|
73
|
+
DATETIME(): Type<Date, unknown>;
|
|
74
|
+
FKEY<N extends Natural, E extends Entry>(attribute: Type<N, E>): Type<N, E>;
|
|
75
|
+
INT(size?: number): Type<number, unknown>;
|
|
76
|
+
INT8(): Type<string, unknown>;
|
|
77
|
+
VARCHAR(size?: number): Type<string, unknown>;
|
|
60
78
|
connect(): Promise<void>;
|
|
61
79
|
end(): Promise<void>;
|
|
62
|
-
model<
|
|
80
|
+
model<A extends AttributesDefinition, M extends Methods<T>, T extends Entry & {
|
|
81
|
+
id?: string;
|
|
82
|
+
} & ModelWithMetods<A, M>>(name: string, attributes: A, options?: BaseModelOptions<T> & {
|
|
83
|
+
int8id: true;
|
|
84
|
+
methods: M;
|
|
85
|
+
}): Ancestor<A, string, T>;
|
|
86
|
+
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>>(name: string, attributes: A, options?: BaseModelOptions<T> & {
|
|
87
|
+
methods: M;
|
|
88
|
+
primaryKey: K;
|
|
89
|
+
}): Ancestor<A, N, T>;
|
|
90
|
+
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>>(name: string, attributes: A, options?: BaseModelOptions<T> & {
|
|
91
|
+
methods: M;
|
|
92
|
+
parent: P;
|
|
93
|
+
}): Ancestor<A, N, T>;
|
|
94
|
+
model<A extends AttributesDefinition, M extends Methods<T>, T extends Entry & {
|
|
95
|
+
id?: number;
|
|
96
|
+
} & ModelWithMetods<A, M>>(name: string, attributes: A, options?: BaseModelOptions<T> & {
|
|
97
|
+
methods: M;
|
|
98
|
+
}): Ancestor<A, number, T>;
|
|
99
|
+
model<A extends AttributesDefinition, T extends Entry & {
|
|
63
100
|
id?: string;
|
|
64
|
-
} & Model<
|
|
101
|
+
} & Model<A>>(name: string, attributes: A, options?: BaseModelOptions<T> & {
|
|
65
102
|
int8id: true;
|
|
66
|
-
}): Ancestor<
|
|
67
|
-
model<
|
|
103
|
+
}): Ancestor<A, string, T>;
|
|
104
|
+
model<A extends AttributesDefinition, K extends keyof A, N extends K extends keyof A ? Native<A[K]> : never, T extends Entry & Model<A>>(name: string, attributes: A, options?: BaseModelOptions<T> & {
|
|
68
105
|
primaryKey: K;
|
|
69
|
-
}): Ancestor<
|
|
70
|
-
model<
|
|
106
|
+
}): Ancestor<A, N, T>;
|
|
107
|
+
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>>(name: string, attributes: A, options?: BaseModelOptions<T> & {
|
|
71
108
|
parent: P;
|
|
72
|
-
}): Ancestor<
|
|
73
|
-
model<
|
|
109
|
+
}): Ancestor<A, N, T>;
|
|
110
|
+
model<A extends AttributesDefinition, T extends Entry & {
|
|
74
111
|
id?: number;
|
|
75
|
-
} & Model<
|
|
112
|
+
} & Model<A>>(name: string, attributes: A, options?: BaseModelOptions<T>): Ancestor<A, number, T>;
|
|
76
113
|
checkSize(size: number, message: string): number;
|
|
77
114
|
}
|
|
78
115
|
export declare const Package: typeof Sedentary;
|
|
79
|
-
export {};
|
package/index.js
CHANGED
|
@@ -1,33 +1,43 @@
|
|
|
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
|
-
this.log || (this.log = console.log);
|
|
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
|
+
this.log = (0, log_1.createLogger)(options.log);
|
|
29
|
+
if ("sync" in options)
|
|
30
|
+
this.sync = options.sync;
|
|
24
31
|
this.db = new minidb_1.MiniDB(filename, this.log);
|
|
25
32
|
}
|
|
26
33
|
DATETIME() {
|
|
27
34
|
return new db_1.Type({ base: Date, type: "DATETIME" });
|
|
28
35
|
}
|
|
29
|
-
FKEY(
|
|
30
|
-
|
|
36
|
+
FKEY(attribute) {
|
|
37
|
+
const { attributeName, base, fieldName, size, tableName, type, unique } = attribute;
|
|
38
|
+
if (!unique)
|
|
39
|
+
throw new Error(`Sedentary.FKEY: '${tableName}' table: '${attributeName}' attribute: is not unique: can't be used as FKEY target`);
|
|
40
|
+
return new db_1.Type({ base, foreignKey: { attributeName, fieldName, tableName }, size, type });
|
|
31
41
|
}
|
|
32
42
|
INT(size) {
|
|
33
43
|
const message = "Sedentary.INT: 'size' argument: Wrong value, expected 2 or 4";
|
|
@@ -53,7 +63,7 @@ class Sedentary {
|
|
|
53
63
|
this.log("Synced");
|
|
54
64
|
}
|
|
55
65
|
catch (e) {
|
|
56
|
-
this.log("Connecting:
|
|
66
|
+
this.log("Connecting:", e.message);
|
|
57
67
|
throw e;
|
|
58
68
|
}
|
|
59
69
|
}
|
|
@@ -62,21 +72,21 @@ class Sedentary {
|
|
|
62
72
|
await this.db.end();
|
|
63
73
|
this.log("Connection closed");
|
|
64
74
|
}
|
|
65
|
-
model(name,
|
|
75
|
+
model(name, attributes, options) {
|
|
66
76
|
if (typeof name !== "string")
|
|
67
77
|
throw new Error("Sedentary.model: 'name' argument: Wrong type, expected 'string'");
|
|
68
78
|
if (this.models[name])
|
|
69
79
|
throw new Error(`Sedentary.model: '${name}' model: Model already defined`);
|
|
70
|
-
if (!
|
|
71
|
-
|
|
72
|
-
if (!(
|
|
73
|
-
throw new Error(`Sedentary.model: '${name}' model: '
|
|
80
|
+
if (!attributes)
|
|
81
|
+
attributes = {};
|
|
82
|
+
if (!(attributes instanceof Object))
|
|
83
|
+
throw new Error(`Sedentary.model: '${name}' model: 'attributes' argument: Wrong type, expected 'Object'`);
|
|
74
84
|
if (!options)
|
|
75
85
|
options = {};
|
|
76
86
|
if (!(options instanceof Object))
|
|
77
87
|
throw new Error(`Sedentary.model: '${name}' model: 'options' argument: Wrong type, expected 'Object'`);
|
|
78
88
|
for (const k in options)
|
|
79
|
-
if (allowedOption.
|
|
89
|
+
if (!allowedOption.includes(k))
|
|
80
90
|
throw new Error(`Sedentary.model: '${name}' model: 'options' argument: Unknown '${k}' option`);
|
|
81
91
|
if (options.int8id && options.parent)
|
|
82
92
|
throw new Error(`Sedentary.model: '${name}' model: 'int8id' and 'parent' options conflict each other`);
|
|
@@ -84,14 +94,14 @@ class Sedentary {
|
|
|
84
94
|
throw new Error(`Sedentary.model: '${name}' model: 'int8id' and 'primaryKey' options conflict each other`);
|
|
85
95
|
if (options.parent && options.primaryKey)
|
|
86
96
|
throw new Error(`Sedentary.model: '${name}' model: 'parent' and 'primaryKey' options conflict each other`);
|
|
87
|
-
const
|
|
88
|
-
const { indexes, int8id, parent, primaryKey, sync, tableName } = Object.assign({ sync: this.sync, tableName: name + "s" }, options);
|
|
97
|
+
const { indexes, int8id, parent, primaryKey, sync, tableName } = Object.assign({ sync: this.sync, tableName: name }, options);
|
|
89
98
|
let { methods } = options;
|
|
99
|
+
let aarray = int8id
|
|
100
|
+
? [new db_1.Attribute(Object.assign(Object.assign({}, this.INT8()), { attributeName: "id", fieldName: "id", notNull: true, tableName, unique: true }))]
|
|
101
|
+
: [new db_1.Attribute(Object.assign(Object.assign({}, this.INT(4)), { attributeName: "id", fieldName: "id", notNull: true, tableName, unique: true }))];
|
|
102
|
+
let constraints = [{ attribute: aarray[0], constraintName: `${tableName}_id_unique`, type: "u" }];
|
|
90
103
|
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 })];
|
|
104
|
+
const pk = aarray[0];
|
|
95
105
|
if (methods && !(methods instanceof Object))
|
|
96
106
|
throw new Error(`Sedentary.model: '${name}' model: 'methods' option: Wrong type, expected 'Object'`);
|
|
97
107
|
if (parent) {
|
|
@@ -106,121 +116,126 @@ class Sedentary {
|
|
|
106
116
|
}
|
|
107
117
|
if (primaryKey && typeof primaryKey !== "string")
|
|
108
118
|
throw new Error(`Sedentary.model: '${name}' model: 'primaryKey' option: Wrong type, expected 'string'`);
|
|
109
|
-
if (primaryKey && Object.keys(
|
|
110
|
-
throw new Error(`Sedentary.model: '${name}' model: 'primaryKey' option:
|
|
111
|
-
if (parent || primaryKey)
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
for (const
|
|
116
|
-
if (
|
|
117
|
-
throw new Error(`Sedentary.model: '${name}' model: '${
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
119
|
+
if (primaryKey && !Object.keys(attributes).includes(primaryKey))
|
|
120
|
+
throw new Error(`Sedentary.model: '${name}' model: 'primaryKey' option: Attribute '${primaryKey}' does not exists`);
|
|
121
|
+
if (parent || primaryKey) {
|
|
122
|
+
aarray = [];
|
|
123
|
+
constraints = [];
|
|
124
|
+
}
|
|
125
|
+
for (const attributeName in attributes) {
|
|
126
|
+
if (reservedNames.includes(attributeName))
|
|
127
|
+
throw new Error(`Sedentary.model: '${name}' model: '${attributeName}' attribute: Reserved name`);
|
|
128
|
+
const call = (defaultValue, fieldName, notNull, unique, func, message1, message2) => {
|
|
129
|
+
if (func === this.FKEY)
|
|
130
|
+
throw new Error(`${message1} 'this.FKEY' can't be used directly`);
|
|
131
|
+
if (func !== this.DATETIME && func !== this.INT && func !== this.INT8 && func !== this.VARCHAR)
|
|
132
|
+
throw new Error(`${message1} ${message2}`);
|
|
133
|
+
return new db_1.Attribute(Object.assign({ attributeName, defaultValue, fieldName, notNull, tableName, unique }, func()));
|
|
134
|
+
};
|
|
135
|
+
const attributeDefinition = attributes[attributeName];
|
|
136
|
+
let { base, defaultValue, fieldName, foreignKey, notNull, size, type, unique } = (() => {
|
|
121
137
|
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;
|
|
138
|
+
if (attributeDefinition instanceof db_1.Type)
|
|
139
|
+
return new db_1.Attribute(Object.assign({ attributeName, fieldName: attributeName, notNull: false, tableName }, attributeDefinition));
|
|
140
|
+
if (attributeDefinition instanceof Function)
|
|
141
|
+
return call(undefined, attributeName, false, false, attributeDefinition, `Sedentary.model: '${name}' model: '${attributeName}' attribute:`, "Wrong type, expected 'Attribute'");
|
|
142
|
+
if (!(attributeDefinition instanceof Object))
|
|
143
|
+
throw new Error(`Sedentary.model: '${name}' model: '${attributeName}' attribute: Wrong attribute type, expected 'Attribute'`);
|
|
144
|
+
const attributeDefaults = Object.assign({ defaultValue: undefined, fieldName: attributeName, notNull: false, unique: false }, attributeDefinition);
|
|
145
|
+
const { defaultValue, fieldName, notNull, unique, type } = attributeDefaults;
|
|
138
146
|
if (defaultValue === null)
|
|
139
|
-
throw new Error(`Sedentary.model: '${name}' model: '${
|
|
147
|
+
throw new Error(`Sedentary.model: '${name}' model: '${attributeName}' attribute: 'defaultValue' option: Does 'null' default value really makes sense?`);
|
|
140
148
|
if (typeof fieldName !== "string")
|
|
141
|
-
throw new Error(`Sedentary.model: '${name}' model: '${
|
|
142
|
-
if (
|
|
143
|
-
throw new Error(`Sedentary.model: '${name}' model: '${
|
|
149
|
+
throw new Error(`Sedentary.model: '${name}' model: '${attributeName}' attribute: 'fieldName' option: Wrong type, expected 'string'`);
|
|
150
|
+
if (typeof notNull !== "boolean")
|
|
151
|
+
throw new Error(`Sedentary.model: '${name}' model: '${attributeName}' attribute: 'notNull' option: Wrong type, expected 'boolean'`);
|
|
152
|
+
if (typeof unique !== "boolean")
|
|
153
|
+
throw new Error(`Sedentary.model: '${name}' model: '${attributeName}' attribute: 'unique' option: Wrong type, expected 'boolean'`);
|
|
154
|
+
if (type === undefined)
|
|
155
|
+
throw new Error(`Sedentary.model: '${name}' model: '${attributeName}' attribute: Missing 'type' option`);
|
|
144
156
|
if (type instanceof db_1.Type)
|
|
145
|
-
return new db_1.
|
|
157
|
+
return new db_1.Attribute(Object.assign({ attributeName, defaultValue, fieldName, notNull, tableName, unique }, type));
|
|
146
158
|
if (type instanceof Function)
|
|
147
|
-
return call(defaultValue, fieldName, notNull, unique, type, `Sedentary.model: '${name}' model: '${
|
|
148
|
-
throw new Error(`Sedentary.model: '${name}' model: '${
|
|
159
|
+
return call(defaultValue, fieldName, notNull, unique, type, `Sedentary.model: '${name}' model: '${attributeName}' attribute: 'type' option:`, "Wrong type, expected 'Type'");
|
|
160
|
+
throw new Error(`Sedentary.model: '${name}' model: '${attributeName}' attribute: 'type' option: Wrong type, expected 'Type'`);
|
|
149
161
|
})();
|
|
150
162
|
const { base, defaultValue } = ret;
|
|
151
163
|
if (defaultValue !== undefined) {
|
|
152
164
|
if (base === Date && !(defaultValue instanceof Date))
|
|
153
|
-
throw new Error(`Sedentary.model: '${name}' model: '${
|
|
165
|
+
throw new Error(`Sedentary.model: '${name}' model: '${attributeName}' attribute: 'defaultValue' option: Wrong type, expected 'Date'`);
|
|
154
166
|
if (base === Number && typeof defaultValue !== "number")
|
|
155
|
-
throw new Error(`Sedentary.model: '${name}' model: '${
|
|
167
|
+
throw new Error(`Sedentary.model: '${name}' model: '${attributeName}' attribute: 'defaultValue' option: Wrong type, expected 'number'`);
|
|
156
168
|
if (base === String && typeof defaultValue !== "string")
|
|
157
|
-
throw new Error(`Sedentary.model: '${name}' model: '${
|
|
169
|
+
throw new Error(`Sedentary.model: '${name}' model: '${attributeName}' attribute: 'defaultValue' option: Wrong type, expected 'string'`);
|
|
158
170
|
}
|
|
159
171
|
return ret;
|
|
160
172
|
})();
|
|
161
|
-
if (primaryKey ===
|
|
173
|
+
if (primaryKey === attributeName) {
|
|
162
174
|
notNull = true;
|
|
163
175
|
unique = true;
|
|
164
176
|
}
|
|
165
177
|
if (defaultValue)
|
|
166
178
|
notNull = true;
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
179
|
+
const attribute = new db_1.Attribute({ attributeName, base, defaultValue, fieldName, foreignKey, notNull, size, tableName, type, unique });
|
|
180
|
+
aarray.push(attribute);
|
|
181
|
+
if (foreignKey)
|
|
182
|
+
constraints.push({ attribute, constraintName: `fkey_${fieldName}_${foreignKey.tableName}_${foreignKey.fieldName}`, type: "f" });
|
|
183
|
+
if (unique)
|
|
184
|
+
constraints.push({ attribute, constraintName: `${tableName}_${fieldName}_unique`, type: "u" });
|
|
170
185
|
}
|
|
171
186
|
if (indexes) {
|
|
172
|
-
const flds =
|
|
187
|
+
const flds = attributes;
|
|
173
188
|
if (!(indexes instanceof Object))
|
|
174
189
|
throw new Error(`Sedentary.model: '${name}' model: 'indexes' option: Wrong type, expected 'Object'`);
|
|
175
|
-
for (const
|
|
176
|
-
if (
|
|
177
|
-
throw new Error(`Sedentary.model: '${name}' model: '${
|
|
178
|
-
const idx = indexes[
|
|
179
|
-
const
|
|
180
|
-
if (typeof
|
|
181
|
-
throw new Error(`Sedentary.model: '${name}' model: '${
|
|
182
|
-
if (!(
|
|
183
|
-
throw new Error(`Sedentary.model: '${name}' model: '${
|
|
190
|
+
for (const indexName in indexes) {
|
|
191
|
+
if (aarray.filter(({ fieldName, unique }) => unique && `${tableName}_${fieldName}_unique` === indexName).length !== 0)
|
|
192
|
+
throw new Error(`Sedentary.model: '${name}' model: '${indexName}' index: index name already inferred by the unique constraint on an attribute`);
|
|
193
|
+
const idx = indexes[indexName];
|
|
194
|
+
const checkAttribute = (attribute, l) => {
|
|
195
|
+
if (typeof attribute !== "string")
|
|
196
|
+
throw new Error(`Sedentary.model: '${name}' model: '${indexName}' index: #${l + 1} attribute: Wrong type, expected 'string'`);
|
|
197
|
+
if (!(attribute in flds))
|
|
198
|
+
throw new Error(`Sedentary.model: '${name}' model: '${indexName}' index: #${l + 1} attribute: Unknown attribute '${attribute}'`);
|
|
184
199
|
};
|
|
185
|
-
let
|
|
200
|
+
let attributes;
|
|
186
201
|
let type = "btree";
|
|
187
202
|
let unique = false;
|
|
188
203
|
if (idx instanceof Array) {
|
|
189
|
-
idx.forEach(
|
|
190
|
-
|
|
204
|
+
idx.forEach(checkAttribute);
|
|
205
|
+
attributes = idx;
|
|
191
206
|
}
|
|
192
207
|
else if (typeof idx === "string") {
|
|
193
|
-
|
|
194
|
-
|
|
208
|
+
checkAttribute(idx, 0);
|
|
209
|
+
attributes = [idx];
|
|
195
210
|
}
|
|
196
211
|
else if (idx instanceof Object) {
|
|
197
212
|
for (const k in idx)
|
|
198
|
-
if (["
|
|
199
|
-
throw new Error(`Sedentary.model: '${name}' model: '${
|
|
200
|
-
({
|
|
201
|
-
if (!
|
|
202
|
-
throw new Error(`Sedentary.model: '${name}' model: '${
|
|
203
|
-
if (
|
|
204
|
-
|
|
205
|
-
else if (typeof
|
|
206
|
-
|
|
207
|
-
|
|
213
|
+
if (!["attributes", "type", "unique"].includes(k))
|
|
214
|
+
throw new Error(`Sedentary.model: '${name}' model: '${indexName}' index: Unknown index option '${k}'`);
|
|
215
|
+
({ attributes, type, unique } = Object.assign({ type: "btree", unique: false }, idx));
|
|
216
|
+
if (!attributes)
|
|
217
|
+
throw new Error(`Sedentary.model: '${name}' model: '${indexName}' index: Missing 'attributes' option`);
|
|
218
|
+
if (attributes instanceof Array)
|
|
219
|
+
attributes.forEach(checkAttribute);
|
|
220
|
+
else if (typeof attributes === "string") {
|
|
221
|
+
checkAttribute(attributes, 0);
|
|
222
|
+
attributes = [attributes];
|
|
208
223
|
}
|
|
209
224
|
else
|
|
210
|
-
throw new Error(`Sedentary.model: '${name}' model: '${
|
|
225
|
+
throw new Error(`Sedentary.model: '${name}' model: '${indexName}' index: 'attributes' option: Wrong type, expected 'FieldNames'`);
|
|
211
226
|
if (typeof type !== "string")
|
|
212
|
-
throw new Error(`Sedentary.model: '${name}' model: '${
|
|
213
|
-
if (["btree", "hash"].
|
|
214
|
-
throw new Error(`Sedentary.model: '${name}' model: '${
|
|
227
|
+
throw new Error(`Sedentary.model: '${name}' model: '${indexName}' index: 'type' option: Wrong type, expected 'string'`);
|
|
228
|
+
if (!["btree", "hash"].includes(type))
|
|
229
|
+
throw new Error(`Sedentary.model: '${name}' model: '${indexName}' index: 'type' option: Wrong value, expected 'btree' or 'hash'`);
|
|
215
230
|
if (typeof unique !== "boolean")
|
|
216
|
-
throw new Error(`Sedentary.model: '${name}' model: '${
|
|
231
|
+
throw new Error(`Sedentary.model: '${name}' model: '${indexName}' index: 'unique' option: Wrong type, expected 'boolean'`);
|
|
217
232
|
}
|
|
218
233
|
else
|
|
219
|
-
throw new Error(`Sedentary.model: '${name}' model: '${
|
|
220
|
-
iarray.push({ fields
|
|
234
|
+
throw new Error(`Sedentary.model: '${name}' model: '${indexName}' index: Wrong type, expected 'Object'`);
|
|
235
|
+
iarray.push({ fields: attributes, indexName, type, unique });
|
|
221
236
|
}
|
|
222
237
|
}
|
|
223
|
-
this.db.addTable(new db_1.Table({ constraints,
|
|
238
|
+
this.db.addTable(new db_1.Table({ constraints, attributes: aarray, indexes: iarray, parent, primaryKey, sync, tableName }));
|
|
224
239
|
this.models[name] = true;
|
|
225
240
|
const init = parent
|
|
226
241
|
? options.init
|
|
@@ -231,7 +246,7 @@ class Sedentary {
|
|
|
231
246
|
: parent.init
|
|
232
247
|
: options.init;
|
|
233
248
|
const flds = {};
|
|
234
|
-
for (const key in
|
|
249
|
+
for (const key in attributes)
|
|
235
250
|
flds[key] = null;
|
|
236
251
|
class Class {
|
|
237
252
|
constructor() {
|
|
@@ -251,15 +266,19 @@ class Sedentary {
|
|
|
251
266
|
return resolve([new Class()]);
|
|
252
267
|
reject(new Error("boh"));
|
|
253
268
|
}, 10));
|
|
254
|
-
Object.defineProperty(load, "name", { value: name + "
|
|
255
|
-
const meta = { tableName, primaryKey, init, methods };
|
|
256
|
-
Object.defineProperty(Class, "
|
|
269
|
+
Object.defineProperty(load, "name", { value: name + ".load" });
|
|
270
|
+
const meta = { base: Number, type: "meta", tableName, primaryKey, init, methods };
|
|
271
|
+
Object.defineProperty(Class, "isModel", { value: () => true });
|
|
257
272
|
Object.defineProperty(Class, "load", { value: load });
|
|
258
273
|
Object.defineProperty(Class, "meta", { value: new db_1.Meta(meta) });
|
|
274
|
+
Object.defineProperty(Class, "name", { value: name });
|
|
259
275
|
Object.defineProperty(Class.prototype.save, "name", { value: name + ".save" });
|
|
260
276
|
Object.assign(Class, new db_1.Meta(meta));
|
|
261
|
-
Object.assign(Class, Object.assign(Object.assign({}, fields), { isModel: () => true }));
|
|
262
277
|
Object.assign(Class.prototype, methods);
|
|
278
|
+
for (const attribute of aarray)
|
|
279
|
+
Object.defineProperty(Class, attribute.attributeName, { value: attribute });
|
|
280
|
+
for (const key of ["attributeName", "base", "fieldName", "size", "type", "unique"])
|
|
281
|
+
Object.defineProperty(Class, key, { value: pk[key] });
|
|
263
282
|
return Class;
|
|
264
283
|
}
|
|
265
284
|
checkSize(size, message) {
|
|
@@ -273,12 +292,11 @@ class Sedentary {
|
|
|
273
292
|
exports.Sedentary = Sedentary;
|
|
274
293
|
exports.Package = Sedentary;
|
|
275
294
|
const db = new Sedentary("gino");
|
|
276
|
-
const Users = db.model("User", { foo: db.INT(), bar: db.VARCHAR() }, {});
|
|
277
|
-
|
|
295
|
+
const Users = db.model("User", { foo: db.INT(), bar: { type: db.VARCHAR(), unique: true } }, {});
|
|
296
|
+
class Item extends db.model("Item", {
|
|
278
297
|
num: db.FKEY(Users),
|
|
279
298
|
str: db.VARCHAR()
|
|
280
|
-
}
|
|
281
|
-
class Item extends db.model("Item", fields, {
|
|
299
|
+
}, {
|
|
282
300
|
init: function () {
|
|
283
301
|
this.num = 0;
|
|
284
302
|
this.str = "0";
|
|
@@ -311,7 +329,7 @@ class Next extends db.model("Next", { a: db.INT, b: db.INT }, {
|
|
|
311
329
|
primaryKey: "a"
|
|
312
330
|
}) {
|
|
313
331
|
}
|
|
314
|
-
class Current extends db.model("Current", { b: db.FKEY(Next) }, {
|
|
332
|
+
class Current extends db.model("Current", { b: { type: db.FKEY(Next), unique: true } }, {
|
|
315
333
|
init: function () {
|
|
316
334
|
this.b = 24;
|
|
317
335
|
}
|