masterrecord 0.0.33 → 0.0.35
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/Entity/entityModel.js +4 -1
- package/Entity/entityTrackerModel.js +8 -14
- package/Masterrecord.js +1 -1
- package/Migrations/cli.js +8 -9
- package/Migrations/migrationSQLiteQuery.js +17 -17
- package/Migrations/migrations.js +23 -22
- package/QueryLanguage/queryMethods.js +132 -43
- package/QueryLanguage/queryScript.js +35 -13
- package/QueryLanguage/selectManager.js +66 -0
- package/SQLLiteEngine.js +195 -23
- package/Tools.js +10 -1
- package/context.js +65 -56
- package/deleteManager.js +12 -2
- package/insertManager.js +7 -5
- package/package.json +5 -5
- package/QueryLanguage/queryManager.js +0 -66
package/SQLLiteEngine.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Version 0.0.
|
|
1
|
+
// Version 0.0.6
|
|
2
2
|
var tools = require('masterrecord/Tools');
|
|
3
3
|
|
|
4
4
|
class SQLLiteEngine {
|
|
@@ -36,7 +36,12 @@ class SQLLiteEngine {
|
|
|
36
36
|
queryString.query = query.raw;
|
|
37
37
|
}
|
|
38
38
|
else{
|
|
39
|
-
|
|
39
|
+
if(typeof query === 'string'){
|
|
40
|
+
queryString.query = query;
|
|
41
|
+
}
|
|
42
|
+
else{
|
|
43
|
+
queryString = this.buildQuery(query, entity, context);
|
|
44
|
+
}
|
|
40
45
|
}
|
|
41
46
|
if(queryString.query){
|
|
42
47
|
console.log("SQL:", queryString.query);
|
|
@@ -58,10 +63,14 @@ class SQLLiteEngine {
|
|
|
58
63
|
queryString.query = query.raw;
|
|
59
64
|
}
|
|
60
65
|
else{
|
|
61
|
-
|
|
66
|
+
if(query.count === undefined){
|
|
67
|
+
query.count = "none";
|
|
68
|
+
}
|
|
69
|
+
queryString.entity = this.getEntity(entity.__name, query.entityMap);
|
|
70
|
+
queryString.query = `SELECT ${this.buildCount(query, entity)} ${this.buildFrom(query, entity)} ${this.buildWhere(query, entity)}`
|
|
62
71
|
}
|
|
63
72
|
if(queryString.query){
|
|
64
|
-
var queryCount =
|
|
73
|
+
var queryCount = queryString.query
|
|
65
74
|
console.log("SQL:", queryCount );
|
|
66
75
|
var queryReturn = this.db.prepare(queryCount ).get();
|
|
67
76
|
return queryReturn;
|
|
@@ -80,6 +89,7 @@ class SQLLiteEngine {
|
|
|
80
89
|
selectQuery.query = query.raw;
|
|
81
90
|
}
|
|
82
91
|
else{
|
|
92
|
+
|
|
83
93
|
selectQuery = this.buildQuery(query, entity, context);
|
|
84
94
|
}
|
|
85
95
|
if(selectQuery.query){
|
|
@@ -94,17 +104,49 @@ class SQLLiteEngine {
|
|
|
94
104
|
}
|
|
95
105
|
}
|
|
96
106
|
|
|
107
|
+
changeNullQuery(query){
|
|
108
|
+
if(query.where){
|
|
109
|
+
var whereClaus;
|
|
110
|
+
whereClaus = query.where.expr.replace("=== null", "is null");
|
|
111
|
+
if(whereClaus === query.where.expr){
|
|
112
|
+
whereClaus = query.where.expr.replace("!= null", "is not null");
|
|
113
|
+
}
|
|
114
|
+
query.where.expr = whereClaus;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
buildCount(query, mainQuery){
|
|
120
|
+
var entity = this.getEntity(query.parentName, query.entityMap);
|
|
121
|
+
if(query.count){
|
|
122
|
+
if(query.count !== "none"){
|
|
123
|
+
return `COUNT(${entity}.${query.count.selectFields[0]})`
|
|
124
|
+
}
|
|
125
|
+
else{
|
|
126
|
+
return `COUNT(*)`
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
else{
|
|
130
|
+
return ""
|
|
131
|
+
}
|
|
132
|
+
}
|
|
97
133
|
|
|
98
|
-
buildQuery(query, entity, context){
|
|
134
|
+
buildQuery(query, entity, context, limit){
|
|
99
135
|
|
|
100
136
|
var queryObject = {};
|
|
101
137
|
queryObject.entity = this.getEntity(entity.__name, query.entityMap);
|
|
102
138
|
queryObject.select = this.buildSelect(query, entity);
|
|
139
|
+
queryObject.count = this.buildCount(query, entity);
|
|
103
140
|
queryObject.from = this.buildFrom(query, entity);
|
|
104
141
|
queryObject.include = this.buildInclude(query, entity, context, queryObject);
|
|
105
142
|
queryObject.where = this.buildWhere(query, entity);
|
|
143
|
+
queryObject.and = this.buildAnd(query, entity);
|
|
144
|
+
queryObject.take = this.buildTake(query);
|
|
145
|
+
queryObject.skip = this.buildSkip(query);
|
|
146
|
+
queryObject.orderBy = this.buildOrderBy(query);
|
|
106
147
|
|
|
107
|
-
|
|
148
|
+
|
|
149
|
+
var queryString = `${queryObject.select} ${queryObject.count} ${queryObject.from} ${queryObject.include} ${queryObject.where} ${queryObject.and} ${queryObject.orderBy} ${queryObject.take} ${queryObject.skip}`;
|
|
108
150
|
return {
|
|
109
151
|
query : queryString,
|
|
110
152
|
entity : this.getEntity(entity.__name, query.entityMap)
|
|
@@ -112,8 +154,108 @@ class SQLLiteEngine {
|
|
|
112
154
|
|
|
113
155
|
}
|
|
114
156
|
|
|
157
|
+
buildOrderBy(query){
|
|
158
|
+
// ORDER BY column1, column2, ... ASC|DESC;
|
|
159
|
+
var $that = this;
|
|
160
|
+
var orderByType = "ASC";
|
|
161
|
+
var orderByEntity = query.orderBy;
|
|
162
|
+
var strQuery = "";
|
|
163
|
+
if(orderByEntity === false){
|
|
164
|
+
orderByType = "DESC";
|
|
165
|
+
orderByEntity = query.orderByDesc;
|
|
166
|
+
}
|
|
167
|
+
if(orderByEntity){
|
|
168
|
+
var entity = this.getEntity(query.parentName, query.entityMap);
|
|
169
|
+
var fieldList = "";
|
|
170
|
+
for (const item in orderByEntity.selectFields) {
|
|
171
|
+
fieldList += `${entity}.${orderByEntity.selectFields[item]}, `;
|
|
172
|
+
};
|
|
173
|
+
fieldList = fieldList.replace(/,\s*$/, "");
|
|
174
|
+
strQuery = "ORDER BY";
|
|
175
|
+
strQuery += ` ${fieldList} ${orderByType}`;
|
|
176
|
+
}
|
|
177
|
+
return strQuery;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
buildTake(query){
|
|
181
|
+
if(query.take){
|
|
182
|
+
return `LIMIT ${query.take}`
|
|
183
|
+
}
|
|
184
|
+
else{
|
|
185
|
+
return "";
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
buildSkip(query){
|
|
190
|
+
if(query.skip){
|
|
191
|
+
return `OFFSET ${query.skip}`
|
|
192
|
+
}
|
|
193
|
+
else{
|
|
194
|
+
return "";
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
buildAnd(query, mainQuery){
|
|
199
|
+
// loop through the AND
|
|
200
|
+
// loop update ther where .expr
|
|
201
|
+
var andEntity = query.and;
|
|
202
|
+
var strQuery = "";
|
|
203
|
+
var $that = this;
|
|
204
|
+
var str = "";
|
|
205
|
+
|
|
206
|
+
if(andEntity){
|
|
207
|
+
var entity = this.getEntity(query.parentName, query.entityMap);
|
|
208
|
+
var andList = [];
|
|
209
|
+
for (let entityPart in andEntity) { // loop through list of and's
|
|
210
|
+
var itemEntity = andEntity[entityPart]; // get the entityANd
|
|
211
|
+
for (let table in itemEntity[query.parentName]) { // find the main table
|
|
212
|
+
var item = itemEntity[query.parentName][table];
|
|
213
|
+
for (let exp in item.expressions) {
|
|
214
|
+
var field = tools.capitalizeFirstLetter(item.expressions[exp].field);
|
|
215
|
+
if(mainQuery[field]){
|
|
216
|
+
if(mainQuery[field].isNavigational){
|
|
217
|
+
entity = $that.getEntity(field, query.entityMap);
|
|
218
|
+
field = item.fields[1];
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
if(item.expressions[exp].arg === "null"){
|
|
222
|
+
if(item.expressions[exp].func === "="){
|
|
223
|
+
item.expressions[exp].func = "is"
|
|
224
|
+
}
|
|
225
|
+
if(item.expressions[exp].func === "!="){
|
|
226
|
+
item.expressions[exp].func = "is not"
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
if(strQuery === ""){
|
|
230
|
+
if(item.expressions[exp].arg === "null"){
|
|
231
|
+
strQuery = `${entity}.${field} ${item.expressions[exp].func} ${item.expressions[exp].arg}`;
|
|
232
|
+
}else{
|
|
233
|
+
strQuery = `${entity}.${field} ${item.expressions[exp].func} '${item.expressions[exp].arg}'`;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
else{
|
|
237
|
+
if(item.expressions[exp].arg === "null"){
|
|
238
|
+
strQuery = `${strQuery} and ${entity}.${field} ${item.expressions[exp].func} ${item.expressions[exp].arg}`;
|
|
239
|
+
}else{
|
|
240
|
+
strQuery = `${strQuery} and ${entity}.${field} ${item.expressions[exp].func} '${item.expressions[exp].arg}'`;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
andList.push(strQuery);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if(andList.length > 0){
|
|
251
|
+
str = `and ${andList.join(" and ")}`;
|
|
252
|
+
}
|
|
253
|
+
return str
|
|
254
|
+
}
|
|
255
|
+
|
|
115
256
|
buildWhere(query, mainQuery){
|
|
116
257
|
var whereEntity = query.where;
|
|
258
|
+
|
|
117
259
|
var strQuery = "";
|
|
118
260
|
var $that = this;
|
|
119
261
|
if(whereEntity){
|
|
@@ -128,11 +270,28 @@ class SQLLiteEngine {
|
|
|
128
270
|
field = item.fields[1];
|
|
129
271
|
}
|
|
130
272
|
}
|
|
273
|
+
if(item.expressions[exp].arg === "null"){
|
|
274
|
+
if(item.expressions[exp].func === "="){
|
|
275
|
+
item.expressions[exp].func = "is"
|
|
276
|
+
}
|
|
277
|
+
if(item.expressions[exp].func === "!="){
|
|
278
|
+
item.expressions[exp].func = "is not"
|
|
279
|
+
}
|
|
280
|
+
}
|
|
131
281
|
if(strQuery === ""){
|
|
132
|
-
|
|
282
|
+
if(item.expressions[exp].arg === "null"){
|
|
283
|
+
strQuery = `WHERE ${entity}.${field} ${item.expressions[exp].func} ${item.expressions[exp].arg}`;
|
|
284
|
+
}else{
|
|
285
|
+
strQuery = `WHERE ${entity}.${field} ${item.expressions[exp].func} '${item.expressions[exp].arg}'`;
|
|
286
|
+
}
|
|
133
287
|
}
|
|
134
288
|
else{
|
|
135
|
-
|
|
289
|
+
if(item.expressions[exp].arg === "null"){
|
|
290
|
+
strQuery = `${strQuery} and ${entity}.${field} ${item.expressions[exp].func} ${item.expressions[exp].arg}`;
|
|
291
|
+
}else{
|
|
292
|
+
strQuery = `${strQuery} and ${entity}.${field} ${item.expressions[exp].func} '${item.expressions[exp].arg}'`;
|
|
293
|
+
}
|
|
294
|
+
|
|
136
295
|
}
|
|
137
296
|
}
|
|
138
297
|
}
|
|
@@ -250,7 +409,7 @@ class SQLLiteEngine {
|
|
|
250
409
|
getEntity(name, maps){
|
|
251
410
|
for (let item in maps) {
|
|
252
411
|
var map = maps[item];
|
|
253
|
-
if(tools.capitalizeFirstLetter(name) === map.name){
|
|
412
|
+
if(tools.capitalizeFirstLetter(name) === tools.capitalizeFirstLetter(map.name)){
|
|
254
413
|
return map.entity
|
|
255
414
|
}
|
|
256
415
|
}
|
|
@@ -264,21 +423,16 @@ class SQLLiteEngine {
|
|
|
264
423
|
for (var ent in entity) {
|
|
265
424
|
if(!ent.startsWith("_")){
|
|
266
425
|
if(!entity[ent].foreignKey){
|
|
267
|
-
if(
|
|
268
|
-
|
|
269
|
-
entitiesList.push(`'${entity[ent].relationshipTable}'`);
|
|
270
|
-
}
|
|
271
|
-
else{
|
|
272
|
-
entitiesList.push(entity[ent].relationshipTable);
|
|
273
|
-
}
|
|
426
|
+
if($that.chechUnsupportedWords(ent)){
|
|
427
|
+
entitiesList.push(`'${ent}'`);
|
|
274
428
|
}
|
|
275
429
|
else{
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
}
|
|
430
|
+
entitiesList.push(ent);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
else{
|
|
434
|
+
if(entity[ent].type === 'belongsTo'){
|
|
435
|
+
entitiesList.push(`${entity[ent].foreignKey}`);
|
|
282
436
|
}
|
|
283
437
|
}
|
|
284
438
|
}
|
|
@@ -354,7 +508,7 @@ class SQLLiteEngine {
|
|
|
354
508
|
if((fieldColumn !== undefined && fieldColumn !== null && fieldColumn !== "" ) && typeof(fieldColumn) !== "object"){
|
|
355
509
|
switch(modelEntity[column].type){
|
|
356
510
|
case "belongsTo" :
|
|
357
|
-
column = modelEntity[column].
|
|
511
|
+
column = modelEntity[column].foreignKey === undefined ? column : modelEntity[column].foreignKey;
|
|
358
512
|
break;
|
|
359
513
|
case "string" :
|
|
360
514
|
fieldColumn = `'${$that._santizeSingleQuotes(fields[column])}'`;
|
|
@@ -368,6 +522,24 @@ class SQLLiteEngine {
|
|
|
368
522
|
values = values === null ? `${fieldColumn},` : `${values} ${fieldColumn},`;
|
|
369
523
|
|
|
370
524
|
}
|
|
525
|
+
else{
|
|
526
|
+
switch(modelEntity[column].type){
|
|
527
|
+
case "belongsTo" :
|
|
528
|
+
var fieldObject = tools.findTrackedObject(fields.__context.__trackedEntities, column );
|
|
529
|
+
if( Object.keys(fieldObject).length > 0){
|
|
530
|
+
var primaryKey = tools.getPrimaryKeyObject(fieldObject.__entity);
|
|
531
|
+
fieldColumn = fieldObject[primaryKey];
|
|
532
|
+
column = modelEntity[column].foreignKey;
|
|
533
|
+
columns = columns === null ? `'${column}',` : `${columns} '${column}',`;
|
|
534
|
+
values = values === null ? `${fieldColumn},` : `${values} ${fieldColumn},`;
|
|
535
|
+
}else{
|
|
536
|
+
console.log("Cannot find belings to relationship")
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
break;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
}
|
|
371
543
|
}
|
|
372
544
|
}
|
|
373
545
|
return {tableName: modelEntity.__name, columns: columns.replace(/,\s*$/, ""), values: values.replace(/,\s*$/, "")};
|
package/Tools.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
// Version 0.0.1
|
|
1
2
|
class Tools{
|
|
2
3
|
|
|
3
4
|
static findEntity(name, entityList){
|
|
4
5
|
return entityList[name];
|
|
5
6
|
}
|
|
6
7
|
|
|
7
|
-
|
|
8
8
|
// this will remove everthing from back slash amount
|
|
9
9
|
static removeBackwardSlashSection(string, amount, type){
|
|
10
10
|
type = type === undefined ? "\\" : type;
|
|
@@ -50,6 +50,15 @@ class Tools{
|
|
|
50
50
|
return new type(validModel, classModel);
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
static findTrackedObject(obj, name){
|
|
54
|
+
for (const property in obj) {
|
|
55
|
+
if(obj[property].__name === name){
|
|
56
|
+
return obj[property];
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return {};
|
|
60
|
+
}
|
|
61
|
+
|
|
53
62
|
static clearAllProto(proto){
|
|
54
63
|
if(proto.__proto__ ){
|
|
55
64
|
proto.__proto__ = null;
|
package/context.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Version 0.0.
|
|
1
|
+
// Version 0.0.5
|
|
2
2
|
|
|
3
3
|
var modelBuilder = require('./Entity/EntityModelBuilder');
|
|
4
4
|
var query = require('masterrecord/QueryLanguage/queryMethods');
|
|
@@ -8,7 +8,7 @@ var MYSQLEngine = require('masterrecord/MYSQLEngine');
|
|
|
8
8
|
var insertManager = require('./InsertManager');
|
|
9
9
|
var deleteManager = require('./DeleteManager');
|
|
10
10
|
var globSearch = require("glob");
|
|
11
|
-
|
|
11
|
+
var fs = require('fs');
|
|
12
12
|
|
|
13
13
|
class context {
|
|
14
14
|
_isModelValid = {
|
|
@@ -21,7 +21,7 @@ class context {
|
|
|
21
21
|
__relationshipModels = [];
|
|
22
22
|
__enviornment = "";
|
|
23
23
|
__name = "";
|
|
24
|
-
|
|
24
|
+
isSQLite = false;
|
|
25
25
|
isMySQL = false;
|
|
26
26
|
|
|
27
27
|
constructor(){
|
|
@@ -41,6 +41,7 @@ class context {
|
|
|
41
41
|
*/
|
|
42
42
|
__SQLiteInit(env, sqlName){
|
|
43
43
|
try{
|
|
44
|
+
|
|
44
45
|
const sqlite3 = require(sqlName);
|
|
45
46
|
let DBAddress = env.completeConnection;
|
|
46
47
|
var db = new sqlite3(DBAddress, env);
|
|
@@ -65,6 +66,7 @@ class context {
|
|
|
65
66
|
*/
|
|
66
67
|
__mysqlInit(env, sqlName){
|
|
67
68
|
try{
|
|
69
|
+
|
|
68
70
|
const mysql = require(sqlName);
|
|
69
71
|
const connection = mysql.createConnection(env);
|
|
70
72
|
connection.connect();
|
|
@@ -78,8 +80,6 @@ class context {
|
|
|
78
80
|
}
|
|
79
81
|
}
|
|
80
82
|
|
|
81
|
-
|
|
82
|
-
|
|
83
83
|
__clearErrorHandler(){
|
|
84
84
|
this._isModelValid = {
|
|
85
85
|
isValid: true,
|
|
@@ -121,22 +121,26 @@ class context {
|
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
useSqlite(rootFolderLocation){
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
124
|
+
this.isSQLite = true;
|
|
125
|
+
var root = process.cwd();
|
|
126
|
+
var envType = this.__enviornment;
|
|
127
|
+
var contextName = this.__name;
|
|
128
|
+
var file = this.__findSettings(root, rootFolderLocation, envType);
|
|
129
|
+
var settings = require(file.file);
|
|
130
|
+
var options = settings[contextName];
|
|
131
|
+
if(options === undefined){
|
|
132
|
+
console.log("settings missing context name settings");
|
|
133
|
+
throw error("settings missing context name settings");
|
|
134
|
+
}
|
|
135
|
+
this.validateSQLiteOptions(options);
|
|
136
|
+
options.completeConnection = `${file.rootFolder}${options.connection}`;
|
|
137
|
+
var dbDirectory = options.completeConnection.substr(0, options.completeConnection.lastIndexOf("\/"));
|
|
138
|
+
if (!fs.existsSync(dbDirectory)){
|
|
139
|
+
fs.mkdirSync(dbDirectory);
|
|
140
|
+
}
|
|
141
|
+
this.db = this.__SQLiteInit(options, "better-sqlite3");
|
|
142
|
+
this._SQLEngine.setDB(this.db, "better-sqlite3");
|
|
143
|
+
return this;
|
|
140
144
|
}
|
|
141
145
|
|
|
142
146
|
validateSQLiteOptions(options){
|
|
@@ -175,41 +179,47 @@ class context {
|
|
|
175
179
|
saveChanges(){
|
|
176
180
|
try{
|
|
177
181
|
var tracked = this.__trackedEntities;
|
|
178
|
-
// start transaction
|
|
179
|
-
if(this.isSQite){
|
|
180
|
-
this._SQLEngine.startTransaction();
|
|
181
|
-
for (var model in tracked) {
|
|
182
|
-
var currentModel = tracked[model];
|
|
183
|
-
switch(currentModel.__state) {
|
|
184
|
-
case "insert":
|
|
185
|
-
var insert = new insertManager(this._SQLEngine, this._isModelValid, this.__entities);
|
|
186
|
-
insert.init(currentModel);
|
|
187
|
-
|
|
188
|
-
break;
|
|
189
|
-
case "modified":
|
|
190
|
-
if(currentModel.__dirtyFields.length > 0){
|
|
191
|
-
var cleanCurrentModel = tools.removePrimarykeyandVirtual(currentModel, currentModel._entity);
|
|
192
|
-
// build columns equal to value string
|
|
193
|
-
var argu = this._SQLEngine._buildSQLEqualTo(cleanCurrentModel);
|
|
194
|
-
var primaryKey = tools.getPrimaryKeyObject(cleanCurrentModel.__entity);
|
|
195
|
-
var sqlUpdate = {tableName: cleanCurrentModel.__entity.__name, arg: argu, primaryKey : primaryKey, primaryKeyValue : cleanCurrentModel[primaryKey] };
|
|
196
|
-
this._SQLEngine.update(sqlUpdate);
|
|
197
|
-
}
|
|
198
|
-
else{
|
|
199
|
-
console.log("Tracked entity modified with no values being changed");
|
|
200
|
-
}
|
|
201
182
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
183
|
+
if(tracked.length > 0){
|
|
184
|
+
// start transaction
|
|
185
|
+
if(this.isSQLite){
|
|
186
|
+
this._SQLEngine.startTransaction();
|
|
187
|
+
for (var model in tracked) {
|
|
188
|
+
var currentModel = tracked[model];
|
|
189
|
+
switch(currentModel.__state) {
|
|
190
|
+
case "insert":
|
|
191
|
+
var insert = new insertManager(this._SQLEngine, this._isModelValid, this.__entities);
|
|
192
|
+
insert.init(currentModel);
|
|
193
|
+
|
|
194
|
+
break;
|
|
195
|
+
case "modified":
|
|
196
|
+
if(currentModel.__dirtyFields.length > 0){
|
|
197
|
+
var cleanCurrentModel = tools.removePrimarykeyandVirtual(currentModel, currentModel._entity);
|
|
198
|
+
// build columns equal to value string
|
|
199
|
+
var argu = this._SQLEngine._buildSQLEqualTo(cleanCurrentModel);
|
|
200
|
+
var primaryKey = tools.getPrimaryKeyObject(cleanCurrentModel.__entity);
|
|
201
|
+
var sqlUpdate = {tableName: cleanCurrentModel.__entity.__name, arg: argu, primaryKey : primaryKey, primaryKeyValue : cleanCurrentModel[primaryKey] };
|
|
202
|
+
this._SQLEngine.update(sqlUpdate);
|
|
203
|
+
}
|
|
204
|
+
else{
|
|
205
|
+
console.log("Tracked entity modified with no values being changed");
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// code block
|
|
209
|
+
break;
|
|
210
|
+
case "delete":
|
|
211
|
+
var deleteObject = new deleteManager(this._SQLEngine, this.__entities);
|
|
212
|
+
deleteObject.init(currentModel);
|
|
213
|
+
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
this.__clearErrorHandler();
|
|
218
|
+
this._SQLEngine.endTransaction();
|
|
210
219
|
}
|
|
211
|
-
|
|
212
|
-
|
|
220
|
+
}
|
|
221
|
+
else{
|
|
222
|
+
console.log("save changes has no tracked entities");
|
|
213
223
|
}
|
|
214
224
|
}
|
|
215
225
|
|
|
@@ -227,12 +237,11 @@ class context {
|
|
|
227
237
|
|
|
228
238
|
|
|
229
239
|
_execute(query){
|
|
230
|
-
if(this.
|
|
240
|
+
if(this.isSQLite){
|
|
231
241
|
this._SQLEngine._execute(query);
|
|
232
242
|
}
|
|
233
243
|
}
|
|
234
244
|
|
|
235
|
-
// TODO: WHY WE HAVE DOUBLE TRACKED OBJECTS - LOOP THROUGH ALL TRACKED OBJECTS
|
|
236
245
|
__track(model){
|
|
237
246
|
this.__trackedEntities.push(model);
|
|
238
247
|
return model;
|
package/deleteManager.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
// version 0.0.2
|
|
1
2
|
var tools = require('./Tools');
|
|
2
|
-
|
|
3
3
|
class DeleteManager{
|
|
4
4
|
constructor(sqlEngine, entities){
|
|
5
5
|
this._SQLEngine = sqlEngine;
|
|
@@ -24,7 +24,17 @@ class DeleteManager{
|
|
|
24
24
|
for (const property of entityKeys) {
|
|
25
25
|
// cascade delete
|
|
26
26
|
if(currentModel.__entity[property].type === "hasOne" || currentModel.__entity[property].type === "hasMany"){
|
|
27
|
-
|
|
27
|
+
var curModel = currentModel[property];
|
|
28
|
+
if(curModel === null){
|
|
29
|
+
// check if state is nullable - if so and nothing comes back dont call cascadeDelete
|
|
30
|
+
var prp = currentModel.__entity[property];
|
|
31
|
+
if(!prp.nullable){
|
|
32
|
+
throw "No relationship record found - please set hasOne or hasMany to nullable. "
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
else{
|
|
36
|
+
$that.cascadeDelete( currentModel[property]);
|
|
37
|
+
}
|
|
28
38
|
}
|
|
29
39
|
}
|
|
30
40
|
this._SQLEngine.delete(currentModel);
|
package/insertManager.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
|
|
2
|
+
// version 0.0.4
|
|
2
3
|
var tools = require('./Tools');
|
|
4
|
+
|
|
3
5
|
class InsertManager {
|
|
4
|
-
|
|
6
|
+
|
|
5
7
|
constructor(sqlEngine, errorModel, allEntities ){
|
|
6
8
|
this._SQLEngine = sqlEngine;
|
|
7
9
|
this._errorModel = errorModel;
|
|
@@ -80,7 +82,7 @@ class InsertManager {
|
|
|
80
82
|
if(modelEntity[entity].type === "belongsTo"){
|
|
81
83
|
var foreignKey = modelEntity[entity].foreignKey === undefined ? modelEntity[entity].name : modelEntity[entity].foreignKey;
|
|
82
84
|
var newPropertyModel = currentModel[foreignKey];
|
|
83
|
-
// check if model is a
|
|
85
|
+
// check if model is a an object. If so insert the child first then the parent.
|
|
84
86
|
if(typeof newPropertyModel === 'object'){
|
|
85
87
|
newPropertyModel.__entity = tools.getEntity(entity, $that._allEntities);
|
|
86
88
|
var propertyCleanCurrentModel = tools.removePrimarykeyandVirtual(newPropertyModel, newPropertyModel.__entity);
|
|
@@ -110,11 +112,11 @@ class InsertManager {
|
|
|
110
112
|
}
|
|
111
113
|
|
|
112
114
|
// SKIP belongs too
|
|
113
|
-
if(currentEntity.type !== "belongsTo"){
|
|
115
|
+
if(currentEntity.type !== "belongsTo" && currentEntity.type !== "hasMany"){
|
|
114
116
|
// primary is always null in an insert so validation insert must be null
|
|
115
117
|
if(currentEntity.nullable === false && !currentEntity.primary){
|
|
116
118
|
// if it doesnt have a get method then call error
|
|
117
|
-
if(currentEntity.
|
|
119
|
+
if(currentEntity.set === undefined){
|
|
118
120
|
if(currentModel[entity] === undefined || currentModel[entity] === null || currentModel[entity] === "" ){
|
|
119
121
|
this._errorModel.isValid = false;
|
|
120
122
|
var errorMessage = `Entity ${currentModel.__entity.__name} column ${entity} is a required Field`;
|
|
@@ -123,7 +125,7 @@ class InsertManager {
|
|
|
123
125
|
}
|
|
124
126
|
}
|
|
125
127
|
else{
|
|
126
|
-
currentRealModel[entity] = currentEntity.
|
|
128
|
+
currentRealModel[entity] = currentEntity.set(currentModel[entity]);
|
|
127
129
|
}
|
|
128
130
|
}
|
|
129
131
|
}
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "masterrecord",
|
|
3
3
|
"dependencies": {
|
|
4
|
-
"better-sqlite3": "^
|
|
5
|
-
"commander": "^
|
|
6
|
-
"glob" : "^
|
|
7
|
-
"deep-object-diff" : "^1.1.
|
|
4
|
+
"better-sqlite3": "^8.6.0",
|
|
5
|
+
"commander": "^11.0.0",
|
|
6
|
+
"glob" : "^10.3.4",
|
|
7
|
+
"deep-object-diff" : "^1.1.9"
|
|
8
8
|
},
|
|
9
|
-
"version": "0.0.
|
|
9
|
+
"version": "0.0.35",
|
|
10
10
|
"description": "An Object-relational mapping for the Master framework. Master Record connects classes to relational database tables to establish a database with almost zero-configuration ",
|
|
11
11
|
"homepage": "https://github.com/Tailor/MasterRecord#readme",
|
|
12
12
|
"repository": {
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
// ALL THIS SHOULD DO IS BUILD A SQL QUERY
|
|
2
|
-
// version 1.0.1
|
|
3
|
-
|
|
4
|
-
class queryManager{
|
|
5
|
-
constructor( query) {
|
|
6
|
-
|
|
7
|
-
/*
|
|
8
|
-
queryObject
|
|
9
|
-
{
|
|
10
|
-
"where": where user.id = 1
|
|
11
|
-
"raw": "select * from tablename where user.id = 2" OR false,
|
|
12
|
-
"builder": builderObject,
|
|
13
|
-
"select" : "*",
|
|
14
|
-
"from" : from tablename
|
|
15
|
-
}
|
|
16
|
-
*/
|
|
17
|
-
this._query = query;
|
|
18
|
-
this._queryBuilder = query.builder;
|
|
19
|
-
this._context = query.builder.__context;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
single(){
|
|
23
|
-
var entityValue = this._context._SQLEngine.get(this._query.getScript());
|
|
24
|
-
var sing = this._queryBuilder.__execute(entityValue, this._queryBuilder);
|
|
25
|
-
return sing;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
//
|
|
29
|
-
select(query){
|
|
30
|
-
// this will come after the where
|
|
31
|
-
this._query.select = "select " + query;
|
|
32
|
-
return this;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
count(){
|
|
36
|
-
// trying to match string select and relace with select Count(*);
|
|
37
|
-
var res = this._query.select.replace("select *", "select Count(*)");
|
|
38
|
-
var entityValue = this._context._SQLEngine.get(res);
|
|
39
|
-
var val = entityValue[Object.keys(entityValue)[0]];
|
|
40
|
-
return val;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
toList(){
|
|
44
|
-
var entityValue = this._context._SQLEngine.all(this._query);
|
|
45
|
-
var toLi = this._queryBuilder.__executeList(entityValue, this._queryBuilder);
|
|
46
|
-
return toLi;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
module.exports = queryManager;
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
/*
|
|
55
|
-
|
|
56
|
-
LINQ Extension Methods
|
|
57
|
-
First()
|
|
58
|
-
FirstOrDefault()
|
|
59
|
-
SingleOrDefault()
|
|
60
|
-
Count()
|
|
61
|
-
Min()
|
|
62
|
-
Max()
|
|
63
|
-
Last()
|
|
64
|
-
LastOrDefault()
|
|
65
|
-
Average()
|
|
66
|
-
*/
|