sedentary 0.0.15 → 0.0.19

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.js CHANGED
@@ -1,11 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Package = exports.Sedentary = exports.Type = exports.Entry = void 0;
3
+ exports.Sedentary2 = exports.Package = exports.Sedentary = exports.Type = exports.EntryBase = void 0;
4
4
  const db_1 = require("./lib/db");
5
5
  const log_1 = require("./lib/log");
6
6
  const minidb_1 = require("./lib/minidb");
7
7
  var db_2 = require("./lib/db");
8
- Object.defineProperty(exports, "Entry", { enumerable: true, get: function () { return db_2.Entry; } });
8
+ Object.defineProperty(exports, "EntryBase", { enumerable: true, get: function () { return db_2.EntryBase; } });
9
9
  Object.defineProperty(exports, "Type", { enumerable: true, get: function () { return db_2.Type; } });
10
10
  const allowedOption = ["indexes", "init", "int8id", "methods", "parent", "primaryKey", "sync", "tableName", "type"];
11
11
  const reservedNames = [
@@ -37,9 +37,9 @@ class Sedentary {
37
37
  DATETIME() {
38
38
  return new db_1.Type({ base: Date, type: "DATETIME" });
39
39
  }
40
- FKEY(attribute) {
40
+ FKEY(attribute, options) {
41
41
  const { attributeName, base, fieldName, size, tableName, type } = attribute;
42
- return new db_1.Type({ base, foreignKey: { attributeName, fieldName, tableName }, size, type });
42
+ return new db_1.Type({ base, foreignKey: { attributeName, fieldName, options, tableName }, size, type });
43
43
  }
44
44
  INT(size) {
45
45
  const message = "Sedentary.INT: 'size' argument: Wrong value, expected 2 or 4";
@@ -56,6 +56,13 @@ class Sedentary {
56
56
  size = size ? this.checkSize(size, message) : undefined;
57
57
  return new db_1.Type({ base: String, size, type: "VARCHAR" });
58
58
  }
59
+ checkSize(size, message) {
60
+ const str = size.toString();
61
+ const parsed = parseInt(str, 10);
62
+ if (str !== parsed.toString())
63
+ throw new Error(message);
64
+ return parsed;
65
+ }
59
66
  async connect() {
60
67
  try {
61
68
  this.log("Connecting...");
@@ -74,113 +81,139 @@ class Sedentary {
74
81
  await this.db.end();
75
82
  this.log("Connection closed");
76
83
  }
77
- model(name, attributes, options) {
78
- if (typeof name !== "string")
84
+ model2(modelName, methods) {
85
+ const ret = function () {
86
+ this.save();
87
+ };
88
+ Object.defineProperty(ret, "name", { value: name });
89
+ if (methods)
90
+ Object.assign(ret.prototype, methods);
91
+ return ret;
92
+ }
93
+ model(modelName, attributes, options, methods) {
94
+ if (typeof modelName !== "string")
79
95
  throw new Error("Sedentary.model: 'name' argument: Wrong type, expected 'string'");
80
- if (this.models[name])
81
- throw new Error(`Sedentary.model: '${name}' model: Model already defined`);
96
+ if (this.models[modelName])
97
+ throw new Error(`Sedentary.model: '${modelName}' model: Model already defined`);
82
98
  if (!attributes)
83
99
  attributes = {};
84
100
  if (!(attributes instanceof Object))
85
- throw new Error(`Sedentary.model: '${name}' model: 'attributes' argument: Wrong type, expected 'Object'`);
101
+ throw new Error(`Sedentary.model: '${modelName}' model: 'attributes' argument: Wrong type, expected 'Object'`);
86
102
  if (!options)
87
103
  options = {};
88
104
  if (!(options instanceof Object))
89
- throw new Error(`Sedentary.model: '${name}' model: 'options' argument: Wrong type, expected 'Object'`);
105
+ throw new Error(`Sedentary.model: '${modelName}' model: 'options' argument: Wrong type, expected 'Object'`);
90
106
  for (const k in options)
91
107
  if (!allowedOption.includes(k))
92
- throw new Error(`Sedentary.model: '${name}' model: 'options' argument: Unknown '${k}' option`);
108
+ throw new Error(`Sedentary.model: '${modelName}' model: 'options' argument: Unknown '${k}' option`);
93
109
  if (options.int8id && options.parent)
94
- throw new Error(`Sedentary.model: '${name}' model: 'int8id' and 'parent' options conflict each other`);
110
+ throw new Error(`Sedentary.model: '${modelName}' model: 'int8id' and 'parent' options conflict each other`);
95
111
  if (options.int8id && options.primaryKey)
96
- throw new Error(`Sedentary.model: '${name}' model: 'int8id' and 'primaryKey' options conflict each other`);
112
+ throw new Error(`Sedentary.model: '${modelName}' model: 'int8id' and 'primaryKey' options conflict each other`);
97
113
  if (options.parent && options.primaryKey)
98
- throw new Error(`Sedentary.model: '${name}' model: 'parent' and 'primaryKey' options conflict each other`);
114
+ throw new Error(`Sedentary.model: '${modelName}' model: 'parent' and 'primaryKey' options conflict each other`);
99
115
  let autoIncrement = true;
100
- const { indexes, int8id, parent, primaryKey, sync, tableName } = Object.assign({ sync: this.sync, tableName: name }, options);
101
- let { methods } = options;
116
+ const { indexes, int8id, parent, primaryKey, sync, tableName } = Object.assign({ sync: this.sync, tableName: modelName }, options);
102
117
  let aarray = int8id
103
- ? [new db_1.Attribute(Object.assign(Object.assign({}, this.INT8()), { attributeName: "id", fieldName: "id", notNull: true, tableName, unique: true }))]
104
- : [new db_1.Attribute(Object.assign(Object.assign({}, this.INT(4)), { attributeName: "id", fieldName: "id", notNull: true, tableName, unique: true }))];
118
+ ? [new db_1.Attribute(Object.assign(Object.assign({}, this.INT8()), { attributeName: "id", fieldName: "id", modelName, notNull: true, tableName, unique: true }))]
119
+ : [new db_1.Attribute(Object.assign(Object.assign({}, this.INT(4)), { attributeName: "id", fieldName: "id", modelName, notNull: true, tableName, unique: true }))];
105
120
  let constraints = [{ attribute: aarray[0], constraintName: `${tableName}_id_unique`, type: "u" }];
106
121
  const iarray = [];
107
122
  const pk = aarray[0];
108
123
  if (methods && !(methods instanceof Object))
109
- throw new Error(`Sedentary.model: '${name}' model: 'methods' option: Wrong type, expected 'Object'`);
124
+ throw new Error(`Sedentary.model: '${modelName}' model: 'methods' option: Wrong type, expected 'Object'`);
125
+ const originalMethods = methods;
110
126
  if (parent) {
111
- methods = (methods ? Object.assign(Object.assign({}, (parent.methods || {})), methods) : parent.methods);
112
127
  try {
113
128
  if (!parent.isModel())
114
129
  throw new Error();
115
130
  }
116
131
  catch (e) {
117
- throw new Error(`Sedentary.model: '${name}' model: 'parent' option: Wrong type, expected 'Model'`);
132
+ throw new Error(`Sedentary.model: '${modelName}' model: 'parent' option: Wrong type, expected 'Model'`);
118
133
  }
134
+ methods = (methods ? Object.assign(Object.assign({}, (parent.methods || {})), methods) : parent.methods);
119
135
  }
120
136
  if (primaryKey && typeof primaryKey !== "string")
121
- throw new Error(`Sedentary.model: '${name}' model: 'primaryKey' option: Wrong type, expected 'string'`);
137
+ throw new Error(`Sedentary.model: '${modelName}' model: 'primaryKey' option: Wrong type, expected 'string'`);
122
138
  if (primaryKey && !Object.keys(attributes).includes(primaryKey))
123
- throw new Error(`Sedentary.model: '${name}' model: 'primaryKey' option: Attribute '${primaryKey}' does not exists`);
139
+ throw new Error(`Sedentary.model: '${modelName}' model: 'primaryKey' option: Attribute '${primaryKey}' does not exists`);
124
140
  if (parent || primaryKey) {
125
141
  autoIncrement = false;
126
142
  aarray = [];
127
143
  constraints = [];
128
144
  }
129
- for (const attributeName in attributes) {
145
+ for (const attributeName of Object.keys(attributes).sort()) {
130
146
  if (reservedNames.includes(attributeName))
131
- throw new Error(`Sedentary.model: '${name}' model: '${attributeName}' attribute: Reserved name`);
147
+ throw new Error(`Sedentary.model: '${modelName}' model: '${attributeName}' attribute: Reserved name`);
132
148
  const call = (defaultValue, fieldName, notNull, unique, func, message1, message2) => {
133
149
  if (func === this.FKEY)
134
150
  throw new Error(`${message1} 'this.FKEY' can't be used directly`);
135
151
  if (func !== this.DATETIME && func !== this.INT && func !== this.INT8 && func !== this.VARCHAR)
136
152
  throw new Error(`${message1} ${message2}`);
137
- return new db_1.Attribute(Object.assign({ attributeName, defaultValue, fieldName, notNull, tableName, unique }, func()));
153
+ return new db_1.Attribute(Object.assign({ attributeName, defaultValue, fieldName, modelName, notNull, tableName, unique }, func()));
138
154
  };
139
155
  const attributeDefinition = attributes[attributeName];
140
156
  let { base, defaultValue, fieldName, foreignKey, notNull, size, type, unique } = (() => {
141
157
  const ret = (() => {
142
158
  if (attributeDefinition instanceof db_1.Type)
143
- return new db_1.Attribute(Object.assign({ attributeName, fieldName: attributeName, notNull: false, tableName }, attributeDefinition));
159
+ return new db_1.Attribute(Object.assign({ attributeName, fieldName: attributeName, modelName, notNull: false, tableName }, attributeDefinition));
144
160
  if (attributeDefinition instanceof Function)
145
- return call(undefined, attributeName, false, false, attributeDefinition, `Sedentary.model: '${name}' model: '${attributeName}' attribute:`, "Wrong type, expected 'Attribute'");
161
+ return call(undefined, attributeName, false, false, attributeDefinition, `Sedentary.model: '${modelName}' model: '${attributeName}' attribute:`, "Wrong type, expected 'Attribute'");
146
162
  if (!(attributeDefinition instanceof Object))
147
- throw new Error(`Sedentary.model: '${name}' model: '${attributeName}' attribute: Wrong attribute type, expected 'Attribute'`);
163
+ throw new Error(`Sedentary.model: '${modelName}' model: '${attributeName}' attribute: Wrong attribute type, expected 'Attribute'`);
148
164
  const attributeDefaults = Object.assign({ defaultValue: undefined, fieldName: attributeName, notNull: false, unique: false }, attributeDefinition);
149
165
  const { defaultValue, fieldName, notNull, unique, type } = attributeDefaults;
150
166
  if (defaultValue === null)
151
- throw new Error(`Sedentary.model: '${name}' model: '${attributeName}' attribute: 'defaultValue' option: Does 'null' default value really makes sense?`);
167
+ throw new Error(`Sedentary.model: '${modelName}' model: '${attributeName}' attribute: 'defaultValue' option: Does 'null' default value really makes sense?`);
152
168
  if (typeof fieldName !== "string")
153
- throw new Error(`Sedentary.model: '${name}' model: '${attributeName}' attribute: 'fieldName' option: Wrong type, expected 'string'`);
169
+ throw new Error(`Sedentary.model: '${modelName}' model: '${attributeName}' attribute: 'fieldName' option: Wrong type, expected 'string'`);
154
170
  if (typeof notNull !== "boolean")
155
- throw new Error(`Sedentary.model: '${name}' model: '${attributeName}' attribute: 'notNull' option: Wrong type, expected 'boolean'`);
171
+ throw new Error(`Sedentary.model: '${modelName}' model: '${attributeName}' attribute: 'notNull' option: Wrong type, expected 'boolean'`);
156
172
  if (typeof unique !== "boolean")
157
- throw new Error(`Sedentary.model: '${name}' model: '${attributeName}' attribute: 'unique' option: Wrong type, expected 'boolean'`);
173
+ throw new Error(`Sedentary.model: '${modelName}' model: '${attributeName}' attribute: 'unique' option: Wrong type, expected 'boolean'`);
158
174
  if (type === undefined)
159
- throw new Error(`Sedentary.model: '${name}' model: '${attributeName}' attribute: Missing 'type' option`);
175
+ throw new Error(`Sedentary.model: '${modelName}' model: '${attributeName}' attribute: Missing 'type' option`);
160
176
  if (type instanceof db_1.Type)
161
- return new db_1.Attribute(Object.assign({ attributeName, defaultValue, fieldName, notNull, tableName, unique }, type));
177
+ return new db_1.Attribute(Object.assign({ attributeName, defaultValue, fieldName, modelName, notNull, tableName, unique }, type));
162
178
  if (type instanceof Function)
163
- return call(defaultValue, fieldName, notNull, unique, type, `Sedentary.model: '${name}' model: '${attributeName}' attribute: 'type' option:`, "Wrong type, expected 'Type'");
164
- throw new Error(`Sedentary.model: '${name}' model: '${attributeName}' attribute: 'type' option: Wrong type, expected 'Type'`);
179
+ return call(defaultValue, fieldName, notNull, unique, type, `Sedentary.model: '${modelName}' model: '${attributeName}' attribute: 'type' option:`, "Wrong type, expected 'Type'");
180
+ throw new Error(`Sedentary.model: '${modelName}' model: '${attributeName}' attribute: 'type' option: Wrong type, expected 'Type'`);
165
181
  })();
166
182
  const { base, defaultValue } = ret;
167
183
  if (defaultValue !== undefined) {
168
184
  if (base === Date && !(defaultValue instanceof Date))
169
- throw new Error(`Sedentary.model: '${name}' model: '${attributeName}' attribute: 'defaultValue' option: Wrong type, expected 'Date'`);
185
+ throw new Error(`Sedentary.model: '${modelName}' model: '${attributeName}' attribute: 'defaultValue' option: Wrong type, expected 'Date'`);
170
186
  if (base === Number && typeof defaultValue !== "number")
171
- throw new Error(`Sedentary.model: '${name}' model: '${attributeName}' attribute: 'defaultValue' option: Wrong type, expected 'number'`);
187
+ throw new Error(`Sedentary.model: '${modelName}' model: '${attributeName}' attribute: 'defaultValue' option: Wrong type, expected 'number'`);
172
188
  if (base === String && typeof defaultValue !== "string")
173
- throw new Error(`Sedentary.model: '${name}' model: '${attributeName}' attribute: 'defaultValue' option: Wrong type, expected 'string'`);
189
+ throw new Error(`Sedentary.model: '${modelName}' model: '${attributeName}' attribute: 'defaultValue' option: Wrong type, expected 'string'`);
174
190
  }
175
191
  return ret;
176
192
  })();
193
+ if (foreignKey) {
194
+ if (!foreignKey.options)
195
+ foreignKey.options = {};
196
+ if (!(foreignKey.options instanceof Object))
197
+ throw new Error(`Sedentary.FKEY: '${modelName}' model: '${attributeName}' attribute: Wrong options type, expected 'Object'`);
198
+ for (const k in foreignKey.options)
199
+ if (!["onDelete", "onUpdate"].includes(k))
200
+ throw new Error(`Sedentary.FKEY: '${modelName}' model: '${attributeName}' attribute: Unknown option '${k}'`);
201
+ for (const onChange of ["onDelete", "onUpdate"]) {
202
+ const actions = ["cascade", "no action", "restrict", "set default", "set null"];
203
+ let action = foreignKey.options[onChange];
204
+ if (!action)
205
+ action = foreignKey.options[onChange] = "no action";
206
+ if (action && !actions.includes(action))
207
+ throw new Error(`Sedentary.FKEY: '${modelName}' model: '${attributeName}' attribute: '${onChange}' option: Wrong value, expected ${actions.map(_ => `'${_}'`).join(" | ")}`);
208
+ }
209
+ }
177
210
  if (primaryKey === attributeName) {
178
211
  notNull = true;
179
212
  unique = true;
180
213
  }
181
214
  if (defaultValue)
182
215
  notNull = true;
183
- const attribute = new db_1.Attribute({ attributeName, base, defaultValue, fieldName, foreignKey, notNull, size, tableName, type, unique });
216
+ const attribute = new db_1.Attribute({ attributeName, base, defaultValue, fieldName, foreignKey, modelName, notNull, size, tableName, type, unique });
184
217
  aarray.push(attribute);
185
218
  if (foreignKey)
186
219
  constraints.push({ attribute, constraintName: `fkey_${fieldName}_${foreignKey.tableName}_${foreignKey.fieldName}`, type: "f" });
@@ -190,16 +223,16 @@ class Sedentary {
190
223
  if (indexes) {
191
224
  const flds = attributes;
192
225
  if (!(indexes instanceof Object))
193
- throw new Error(`Sedentary.model: '${name}' model: 'indexes' option: Wrong type, expected 'Object'`);
226
+ throw new Error(`Sedentary.model: '${modelName}' model: 'indexes' option: Wrong type, expected 'Object'`);
194
227
  for (const indexName in indexes) {
195
228
  if (aarray.filter(({ fieldName, unique }) => unique && `${tableName}_${fieldName}_unique` === indexName).length !== 0)
196
- throw new Error(`Sedentary.model: '${name}' model: '${indexName}' index: index name already inferred by the unique constraint on an attribute`);
229
+ throw new Error(`Sedentary.model: '${modelName}' model: '${indexName}' index: index name already inferred by the unique constraint on an attribute`);
197
230
  const idx = indexes[indexName];
198
231
  const checkAttribute = (attribute, l) => {
199
232
  if (typeof attribute !== "string")
200
- throw new Error(`Sedentary.model: '${name}' model: '${indexName}' index: #${l + 1} attribute: Wrong type, expected 'string'`);
233
+ throw new Error(`Sedentary.model: '${modelName}' model: '${indexName}' index: #${l + 1} attribute: Wrong type, expected 'string'`);
201
234
  if (!(attribute in flds))
202
- throw new Error(`Sedentary.model: '${name}' model: '${indexName}' index: #${l + 1} attribute: Unknown attribute '${attribute}'`);
235
+ throw new Error(`Sedentary.model: '${modelName}' model: '${indexName}' index: #${l + 1} attribute: Unknown attribute '${attribute}'`);
203
236
  };
204
237
  let attributes;
205
238
  let type = "btree";
@@ -215,10 +248,10 @@ class Sedentary {
215
248
  else if (idx instanceof Object) {
216
249
  for (const k in idx)
217
250
  if (!["attributes", "type", "unique"].includes(k))
218
- throw new Error(`Sedentary.model: '${name}' model: '${indexName}' index: Unknown index option '${k}'`);
251
+ throw new Error(`Sedentary.model: '${modelName}' model: '${indexName}' index: Unknown index option '${k}'`);
219
252
  ({ attributes, type, unique } = Object.assign({ type: "btree", unique: false }, idx));
220
253
  if (!attributes)
221
- throw new Error(`Sedentary.model: '${name}' model: '${indexName}' index: Missing 'attributes' option`);
254
+ throw new Error(`Sedentary.model: '${modelName}' model: '${indexName}' index: Missing 'attributes' option`);
222
255
  if (attributes instanceof Array)
223
256
  attributes.forEach(checkAttribute);
224
257
  else if (typeof attributes === "string") {
@@ -226,21 +259,21 @@ class Sedentary {
226
259
  attributes = [attributes];
227
260
  }
228
261
  else
229
- throw new Error(`Sedentary.model: '${name}' model: '${indexName}' index: 'attributes' option: Wrong type, expected 'FieldNames'`);
262
+ throw new Error(`Sedentary.model: '${modelName}' model: '${indexName}' index: 'attributes' option: Wrong type, expected 'FieldNames'`);
230
263
  if (typeof type !== "string")
231
- throw new Error(`Sedentary.model: '${name}' model: '${indexName}' index: 'type' option: Wrong type, expected 'string'`);
264
+ throw new Error(`Sedentary.model: '${modelName}' model: '${indexName}' index: 'type' option: Wrong type, expected 'string'`);
232
265
  if (!["btree", "hash"].includes(type))
233
- throw new Error(`Sedentary.model: '${name}' model: '${indexName}' index: 'type' option: Wrong value, expected 'btree' or 'hash'`);
266
+ throw new Error(`Sedentary.model: '${modelName}' model: '${indexName}' index: 'type' option: Wrong value, expected 'btree' or 'hash'`);
234
267
  if (typeof unique !== "boolean")
235
- throw new Error(`Sedentary.model: '${name}' model: '${indexName}' index: 'unique' option: Wrong type, expected 'boolean'`);
268
+ throw new Error(`Sedentary.model: '${modelName}' model: '${indexName}' index: 'unique' option: Wrong type, expected 'boolean'`);
236
269
  }
237
270
  else
238
- throw new Error(`Sedentary.model: '${name}' model: '${indexName}' index: Wrong type, expected 'Object'`);
271
+ throw new Error(`Sedentary.model: '${modelName}' model: '${indexName}' index: Wrong type, expected 'Object'`);
239
272
  iarray.push({ fields: attributes, indexName, type, unique });
240
273
  }
241
274
  }
242
275
  this.db.tables.push(new db_1.Table({ autoIncrement, constraints, attributes: aarray, indexes: iarray, parent, sync, tableName }));
243
- this.models[name] = true;
276
+ this.models[modelName] = true;
244
277
  const init = parent
245
278
  ? options.init
246
279
  ? function () {
@@ -249,9 +282,6 @@ class Sedentary {
249
282
  }
250
283
  : parent.init
251
284
  : options.init;
252
- const flds = {};
253
- for (const key in attributes)
254
- flds[key] = null;
255
285
  class Class {
256
286
  constructor() {
257
287
  if (init)
@@ -260,7 +290,7 @@ class Sedentary {
260
290
  save() {
261
291
  return new Promise((resolve, reject) => {
262
292
  const save = () => reject(new Error("eh no"));
263
- Object.defineProperty(save, "name", { value: name + ".save" });
293
+ Object.defineProperty(save, "name", { value: modelName + ".save" });
264
294
  setTimeout(save, 10);
265
295
  });
266
296
  }
@@ -270,28 +300,73 @@ class Sedentary {
270
300
  return resolve([new Class()]);
271
301
  reject(new Error("boh"));
272
302
  }, 10));
273
- Object.defineProperty(load, "name", { value: name + ".load" });
274
- const meta = { base: Number, type: "meta", tableName, primaryKey, init, methods };
303
+ Object.defineProperty(load, "name", { value: modelName + ".load" });
304
+ const metaAttributes = aarray.reduce((ret, curr) => {
305
+ ret[curr.attributeName] = curr;
306
+ return ret;
307
+ }, {});
308
+ const metaForeignKeys = aarray
309
+ .filter(_ => _.foreignKey)
310
+ .reduce((ret, curr) => {
311
+ ret[curr.attributeName] = curr;
312
+ return ret;
313
+ }, {});
314
+ const meta = new db_1.Meta({ base: Number, attributes: metaAttributes, foreignKeys: metaForeignKeys, modelName, parent: parent, type: "meta", tableName, primaryKey, init, methods });
315
+ for (const foreignKey in metaForeignKeys) {
316
+ if (foreignKey + "Load" in metaAttributes)
317
+ throw new Error(`Sedentary.model: '${modelName}' model: '${foreignKey}' attribute: '${foreignKey}Load' inferred methods conflicts with an attribute`);
318
+ if (originalMethods && foreignKey + "Load" in originalMethods)
319
+ throw new Error(`Sedentary.model: '${modelName}' model: '${foreignKey}' attribute: '${foreignKey}Load' inferred methods conflicts with a method`);
320
+ }
321
+ if (originalMethods)
322
+ for (const method in originalMethods)
323
+ if (method in metaAttributes)
324
+ throw new Error(`Sedentary.model: '${modelName}' model: '${method}' method: conflicts with an attribute`);
325
+ const checkParent = (parent) => {
326
+ if (!parent)
327
+ return;
328
+ for (const attribute in metaAttributes) {
329
+ if (attribute in parent.attributes)
330
+ throw new Error(`Sedentary.model: '${modelName}' model: '${attribute}' attribute: conflicts with an attribute of '${parent.modelName}' model`);
331
+ if (parent.methods && attribute in parent.methods)
332
+ throw new Error(`Sedentary.model: '${modelName}' model: '${attribute}' attribute: conflicts with a method of '${parent.modelName}' model`);
333
+ for (const foreignKey in parent.foreignKeys)
334
+ if (attribute === foreignKey + "Load")
335
+ throw new Error(`Sedentary.model: '${modelName}' model: '${attribute}' attribute: conflicts with an inferred methods of '${parent.modelName}' model`);
336
+ }
337
+ for (const foreignKey in metaForeignKeys) {
338
+ if (foreignKey + "Load" in parent.attributes)
339
+ throw new Error(`Sedentary.model: '${modelName}' model: '${foreignKey}' attribute: '${foreignKey}Load' inferred methods conflicts with an attribute of '${parent.modelName}' model`);
340
+ if (parent.methods && foreignKey + "Load" in parent.methods)
341
+ throw new Error(`Sedentary.model: '${modelName}' model: '${foreignKey}' attribute: '${foreignKey}Load' inferred methods conflicts with a method of '${parent.modelName}' model`);
342
+ }
343
+ if (originalMethods) {
344
+ for (const method in originalMethods) {
345
+ if (method in parent.attributes)
346
+ throw new Error(`Sedentary.model: '${modelName}' model: '${method}' method: conflicts with an attribute of '${parent.modelName}' model`);
347
+ for (const foreignKey in parent.foreignKeys)
348
+ if (foreignKey + "Load" === method)
349
+ throw new Error(`Sedentary.model: '${modelName}' model: '${method}' method: conflicts with an inferred methods of '${parent.modelName}' model`);
350
+ if (parent.methods && method in parent.methods)
351
+ throw new Error(`Sedentary.model: '${modelName}' model: '${method}' method: conflicts with a method of '${parent.modelName}' model`);
352
+ }
353
+ }
354
+ checkParent(parent.parent);
355
+ };
356
+ checkParent(parent);
275
357
  Object.defineProperty(Class, "isModel", { value: () => true });
276
358
  Object.defineProperty(Class, "load", { value: load });
277
- Object.defineProperty(Class, "meta", { value: new db_1.Meta(meta) });
278
- Object.defineProperty(Class, "name", { value: name });
279
- Object.defineProperty(Class.prototype.save, "name", { value: name + ".save" });
280
- Object.assign(Class, new db_1.Meta(meta));
359
+ Object.defineProperty(Class, "meta", { value: meta });
360
+ Object.defineProperty(Class, "name", { value: modelName });
361
+ Object.defineProperty(Class.prototype.save, "name", { value: modelName + ".save" });
362
+ Object.assign(Class, meta);
281
363
  Object.assign(Class.prototype, methods);
282
364
  for (const attribute of aarray)
283
365
  Object.defineProperty(Class, attribute.attributeName, { value: attribute });
284
- for (const key of ["attributeName", "base", "fieldName", "size", "type", "unique"])
366
+ for (const key of ["attributeName", "base", "fieldName", "modelName", "size", "type", "unique"])
285
367
  Object.defineProperty(Class, key, { value: pk[key] });
286
368
  return Class;
287
369
  }
288
- checkSize(size, message) {
289
- const str = size.toString();
290
- const parsed = parseInt(str, 10);
291
- if (str !== parsed.toString())
292
- throw new Error(message);
293
- return parsed;
294
- }
295
370
  }
296
371
  exports.Sedentary = Sedentary;
297
372
  exports.Package = Sedentary;
@@ -302,13 +377,15 @@ class Item extends db.model("Item", {
302
377
  str: db.VARCHAR()
303
378
  }, {
304
379
  init: function () {
305
- this.num = 0;
380
+ this.num = "0";
306
381
  this.str = "0";
307
382
  },
308
- int8id: true,
383
+ int8id: true
384
+ /*
309
385
  methods: {
310
- prova: () => "ok"
386
+ prova: (): string => "ok"
311
387
  }
388
+ */
312
389
  }) {
313
390
  }
314
391
  class Super extends db.model("Super", {
@@ -316,14 +393,17 @@ class Super extends db.model("Super", {
316
393
  n: db.FKEY(Item),
317
394
  s: db.FKEY(Users.bar)
318
395
  }, {
319
- parent: Item,
320
- init: async function () {
321
- this.n = "23";
322
- this.id = "0";
323
- this.num = 0;
324
- const a = this.nLoad ? await this.nLoad() : { prova: () => null };
325
- a.prova();
396
+ parent: Item
397
+ /*
398
+ init: async function() {
399
+ this.n = "23";
400
+ this.id = 0;
401
+ this.num = 0;
402
+ const a = this.nLoad ? await this.nLoad() : { prova: (): null => null };
403
+ a.prova();
404
+ this.prova();
326
405
  }
406
+ */
327
407
  }) {
328
408
  }
329
409
  class Next extends db.model("Next", { a: db.INT, b: db.INT }, {
@@ -339,9 +419,9 @@ class Current extends db.model("Current", { b: { type: db.FKEY(Next), unique: tr
339
419
  }
340
420
  }) {
341
421
  }
342
- class Last extends db.model("Last", { b: db.FKEY(Current.b) }, {
422
+ class Last extends db.model("Last", { c: db.FKEY(Current.b) }, {
343
423
  init: function () {
344
- this.b = 24;
424
+ this.c = 24;
345
425
  },
346
426
  parent: Next
347
427
  }) {
@@ -353,7 +433,49 @@ class Last extends db.model("Last", { b: db.FKEY(Current.b) }, {
353
433
  }
354
434
  catch (e) {
355
435
  console.log(Item.load, item.save, await Item.load(true), item, e.message);
356
- console.log(new Next(), Next.load, await Next.load(true), new Last(), item.prova());
436
+ //console.log(new Next(), Next.load, await Next.load(true), new Last(), item.prova());
357
437
  }
358
438
  return true;
359
439
  })();
440
+ function model(modelName, attributes, options, methods) {
441
+ const model = function () { };
442
+ Object.defineProperty(model, "name", { value: modelName });
443
+ if (methods)
444
+ Object.assign(model.prototype, methods);
445
+ return model;
446
+ }
447
+ const T1 = model("T1", {});
448
+ const t1 = new T1();
449
+ t1.id = 0;
450
+ console.log(t1);
451
+ const T2 = model("T2", { a: db.INT, b: db.VARCHAR }, { int8id: true }, {
452
+ test: function (repeat = true) {
453
+ if (repeat)
454
+ this.b = this.test(false);
455
+ this.c = this.a = 0;
456
+ return "test";
457
+ }
458
+ });
459
+ const t2 = new T2();
460
+ //t2.id = "0";
461
+ const tt2 = (t) => console.log(t, t.test(), t.a, t.b);
462
+ tt2(t2);
463
+ class Sedentary2 {
464
+ model(modelName, methods) {
465
+ const ret = function () { };
466
+ Object.defineProperty(ret, "name", { value: modelName });
467
+ if (methods)
468
+ Object.assign(ret.prototype, methods);
469
+ ret.prototype.save = () => new Promise(resolve => resolve(false));
470
+ return ret;
471
+ }
472
+ }
473
+ exports.Sedentary2 = Sedentary2;
474
+ const db2 = new Sedentary2();
475
+ const T22 = db2.model("T2", {
476
+ c: function () {
477
+ this.id = "0";
478
+ this.c();
479
+ return 0;
480
+ }
481
+ });
package/lib/db.d.ts CHANGED
@@ -1,8 +1,12 @@
1
1
  export declare type Natural = Date | Record<string, unknown> | boolean | number | string;
2
- export declare class Entry {
3
- init(): void;
2
+ export declare class EntryBase {
4
3
  save(): Promise<boolean>;
5
4
  }
5
+ export declare type ForeignKeyActions = "cascade" | "no action" | "restrict" | "set default" | "set null";
6
+ export interface ForeignKeyOptions {
7
+ onDelete?: ForeignKeyActions;
8
+ onUpdate?: ForeignKeyActions;
9
+ }
6
10
  export declare class Type<N extends Natural, E> {
7
11
  base: unknown;
8
12
  entry?: E;
@@ -12,16 +16,25 @@ export declare class Type<N extends Natural, E> {
12
16
  foreignKey?: {
13
17
  attributeName: string;
14
18
  fieldName: string;
19
+ options?: ForeignKeyOptions;
15
20
  tableName: string;
16
21
  };
17
22
  constructor(from: Type<N, E>);
18
23
  }
19
24
  export declare class Meta<N extends Natural, E> extends Type<N, E> {
25
+ attributes: {
26
+ [key: string]: unknown;
27
+ };
28
+ foreignKeys: {
29
+ [key: string]: unknown;
30
+ };
20
31
  init: () => void;
21
32
  isModel?: () => boolean;
22
33
  methods: {
23
34
  [key: string]: () => unknown;
24
35
  };
36
+ modelName: string;
37
+ parent?: Meta<Natural, E>;
25
38
  primaryKey: string;
26
39
  tableName: string;
27
40
  constructor(from: Meta<N, E>);
@@ -30,6 +43,7 @@ export declare class Attribute<N extends Natural, E> extends Type<N, E> {
30
43
  attributeName: string;
31
44
  defaultValue?: unknown;
32
45
  fieldName: string;
46
+ modelName: string;
33
47
  notNull: boolean;
34
48
  tableName: string;
35
49
  unique?: boolean;
package/lib/db.js CHANGED
@@ -1,13 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DB = exports.Table = exports.Attribute = exports.Meta = exports.Type = exports.Entry = void 0;
4
- class Entry {
5
- init() { }
3
+ exports.DB = exports.Table = exports.Attribute = exports.Meta = exports.Type = exports.EntryBase = void 0;
4
+ /**/
5
+ class EntryBase {
6
6
  async save() {
7
7
  return false;
8
8
  }
9
9
  }
10
- exports.Entry = Entry;
10
+ exports.EntryBase = EntryBase;
11
11
  class Type {
12
12
  constructor(from) {
13
13
  Object.assign(this, from);
@@ -29,7 +29,7 @@ exports.Attribute = Attribute;
29
29
  function autoImplement() {
30
30
  return class {
31
31
  constructor(defaults) {
32
- Object.assign(this, defaults || {});
32
+ Object.assign(this, defaults);
33
33
  }
34
34
  };
35
35
  }