masterrecord 0.0.34 → 0.0.36

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.
@@ -17,7 +17,7 @@
17
17
 
18
18
  */
19
19
 
20
- // version 0.0.2
20
+ // version 0.0.3
21
21
  class EntityModel {
22
22
 
23
23
  constructor(name){
@@ -137,9 +137,11 @@ class EntityModel {
137
137
  this.obj.foreignTable = foreignTable;
138
138
  this.obj.foreignKey = foreignKey;
139
139
  this.obj.isNavigational = true;
140
+ this.obj.nullable = false;
140
141
  return this;
141
142
  }
142
143
 
144
+ // DB must have a record or exception will be thrown unless set to nullable
143
145
  hasOne(foreignTable, foreignKey){
144
146
  if(foreignKey === undefined){
145
147
  foreignKey = `${this.obj.name.toLowerCase()}_id`;
@@ -148,6 +150,7 @@ class EntityModel {
148
150
  this.obj.foreignTable = foreignTable;
149
151
  this.obj.foreignKey = foreignKey;
150
152
  this.obj.isNavigational = true;
153
+ this.obj.nullable = false;
151
154
  return this;
152
155
  }
153
156
 
@@ -1,3 +1,5 @@
1
+
2
+ // version : 0.0.1
1
3
  var tools = require('../Tools');
2
4
  class EntityTrackerModel {
3
5
 
@@ -108,21 +110,13 @@ class EntityTrackerModel {
108
110
 
109
111
  if(currentEntity[entityField].type === "belongsTo"){
110
112
  if(currentEntity[entityField].lazyLoading){
111
- var priKey = tools.getPrimaryKeyObject(this.__entity);
112
- var currentValue = this.__proto__[`_${entityField}`];
113
- if(currentValue){
114
- // CHECK to see if you got the info already
115
- if(typeof currentValue === 'object'){
116
- currentValue = currentValue[priKey];
117
- }
118
- }
119
- else{
120
- var idValue = currentEntity[entityField].foreignTable;
121
- currentValue = this.__proto__[`_${idValue}`];
122
- }
113
+ // TODO: UPDATE THIS CODE TO USE SOMETHING ELSE - THIS WILL NOT WORK WHEN USING DIFFERENT DATABASES BECAUSE THIS IS USING SQLITE CODE.
114
+
115
+ var priKey = tools.getPrimaryKeyObject(ent.__entity);
123
116
 
124
- //var modelValue = ent.raw(`select * from ${ent.__entity.__name} where ${priKey} = ${ currentValue }`).single();
125
- var modelValue = ent.where(`r => r. ${priKey} == ${ currentValue }`)
117
+ var idValue = currentEntity[entityField].foreignKey;
118
+ var currentValue = this.__proto__[`_${idValue}`];
119
+ var modelValue = ent.where(`r => r.${priKey} == ${ currentValue }`).single();
126
120
  this[entityField] = modelValue;
127
121
  }
128
122
  else{
package/Masterrecord.js CHANGED
@@ -1,7 +1,7 @@
1
1
 
2
2
  // https://github.com/kriasoft/node-sqlite
3
3
  // https://www.learnentityframeworkcore.com/dbset/deleting-data
4
- // version 1.0.19
4
+ // version 1.0.20
5
5
  var context = require("./context");
6
6
  var schema = require("./Migrations/schema");
7
7
 
@@ -1,6 +1,5 @@
1
- // ALL THIS SHOULD DO IS BUILD A SQL QUERY
2
- // version 1.0.222
3
- // TODO: change name of queryManager to select manager;
1
+
2
+ // version 0.0.7
4
3
  var entityTrackerModel = require('masterrecord/Entity/entityTrackerModel');
5
4
  var tools = require('masterrecord/Tools');
6
5
  var queryScript = require('masterrecord/QueryLanguage/queryScript');
@@ -45,12 +44,91 @@ class queryMethods{
45
44
  this.__queryObject.reset();
46
45
  }
47
46
 
48
- raw(query){
49
47
 
48
+ // do join on two tables = inner join
49
+ join(){
50
+
51
+ }
52
+
53
+ groupBy(){
54
+
55
+ }
56
+
57
+ contains(){
58
+ // https://entityframework.net/knowledge-base/3491721/linq-to-entities---where-in-clause-in-query
59
+ }
60
+
61
+ // do join on two tables = inner join
62
+ _____leftJoin(){
63
+
64
+ }
65
+
66
+ ______orderByCount(query, ...args){
67
+ var str = query.toString();
68
+ if(args){
69
+ for(let argument in args){
70
+ var item = args[argument];
71
+ str = str.replace("$$", item);
72
+ }
73
+ }
74
+ this.__queryObject.orderByCount(str, this.__entity.__name);
75
+ return this;
76
+ }
77
+
78
+ ______orderByCountDescending(query, ...args){
79
+ var str = query.toString();
80
+ if(args){
81
+ for(let argument in args){
82
+ var item = args[argument];
83
+ str = str.replace("$$", item);
84
+ }
85
+ }
86
+ this.__queryObject.orderByCountDesc(str, this.__entity.__name);
87
+ return this;
88
+ }
89
+
90
+ orderBy(query, ...args){
91
+ var str = query.toString();
92
+ if(args){
93
+ for(let argument in args){
94
+ var item = args[argument];
95
+ str = str.replace("$$", item);
96
+ }
97
+ }
98
+ this.__queryObject.orderBy(str, this.__entity.__name);
99
+ return this;
100
+ }
101
+
102
+ orderByDescending(query, ...args){
103
+ var str = query.toString();
104
+ if(args){
105
+ for(let argument in args){
106
+ var item = args[argument];
107
+ str = str.replace("$$", item);
108
+ }
109
+ }
110
+ this.__queryObject.orderByDesc(str, this.__entity.__name);
111
+ return this;
112
+ }
113
+
114
+ raw(query){
50
115
  this.__queryObject.raw(query);
51
116
  return this;
52
117
  }
53
118
 
119
+ /* WHERE and AND work together its a way to add to the WHERE CLAUSE DYNAMICALLY */
120
+ and(query, ...args){
121
+ var str = query.toString();
122
+ if(args){
123
+ for(let argument in args){
124
+ var item = args[argument];
125
+ str = str.replace("$$", item);
126
+ }
127
+ }
128
+ this.__queryObject.and(str, this.__entity.__name);
129
+ return this;
130
+ }
131
+
54
132
  where(query, ...args){
55
133
  var str = query.toString();
56
134
  if(args){
@@ -90,65 +168,68 @@ class queryMethods{
90
168
  return this;
91
169
  }
92
170
 
93
-
94
-
95
- // do join on two tables = inner join
96
- join(){
97
-
98
- }
99
-
100
- skip(){
101
-
102
- }
103
-
104
- limit(){
105
-
171
+ take(number){
172
+ this.__queryObject.script.take = number;
173
+ return this;
106
174
  }
107
175
 
108
- oderBy(){
109
-
176
+ skip(number){
177
+ this.__queryObject.script.skip = number;
178
+ return this;
110
179
  }
111
180
 
112
- groupBy(){
113
-
114
- }
181
+
182
+ // ------------------------------- FUNCTIONS THAT MAKE THE SQL CALL START FROM HERE ON -----------------------------------------------------
183
+ // ---------------------------------------------------------------------------------------------------------------------------------------
115
184
 
116
- contains(){
117
- // https://entityframework.net/knowledge-base/3491721/linq-to-entities---where-in-clause-in-query
118
- }
185
+ count(query, ...args){
186
+ if(query){
187
+ var str = query.toString();
188
+ if(args){
189
+ for(let argument in args){
190
+ var item = args[argument];
191
+ str = str.replace("$$", item);
192
+ }
193
+ }
194
+ this.__queryObject.count(str, this.__entity.__name);
195
+ }
119
196
 
120
- count(){
121
- // trying to match string select and relace with select Count(*);
122
- var entityValue = this.__context._SQLEngine.getCount(this.__queryObject, this.__entity, this.__context);
123
- var val = entityValue[Object.keys(entityValue)[0]];
124
- this.__reset();
125
- return val;
197
+ if(this.__context.isSQLite){
198
+ // trying to match string select and relace with select Count(*);
199
+ var entityValue = this.__context._SQLEngine.getCount(this.__queryObject, this.__entity, this.__context);
200
+ var val = entityValue[Object.keys(entityValue)[0]];
201
+ this.__reset();
202
+ return val;
203
+ }
126
204
  }
127
205
 
128
206
  single(){
129
- var entityValue = this.__context._SQLEngine.get(this.__queryObject.script, this.__entity, this.__context);
130
- var sing = this.__singleEntityBuilder(entityValue, this._queryBuilder);
131
- this.__reset();
132
- return sing;
207
+ if(this.__context.isSQLite){
208
+ var entityValue = this.__context._SQLEngine.get(this.__queryObject.script, this.__entity, this.__context);
209
+ var sing = this.__singleEntityBuilder(entityValue, this._queryBuilder);
210
+ this.__reset();
211
+ return sing;
212
+ }
133
213
  }
134
214
 
135
215
  toList(){
136
- var entityValue = this.__context._SQLEngine.all(this.__queryObject.script, this.__entity, this.__context);
137
- var toLi = this.__multipleEntityBuilder(entityValue, this._queryBuilder);
138
- this.__reset();
139
- return toLi;
140
- }
141
-
142
- asQueryable(){
143
- // returns the sql created and does not make a call to DB
216
+ if(this.__context.isSQLite){
217
+ var entityValue = this.__context._SQLEngine.all(this.__queryObject.script, this.__entity, this.__context);
218
+ var toLi = this.__multipleEntityBuilder(entityValue, this._queryBuilder);
219
+ this.__reset();
220
+ return toLi;
221
+ }
144
222
  }
145
223
 
224
+ // ------------------------------- FUNCTIONS THAT UPDATE SQL START FROM HERE -----------------------------------------------------
225
+ // ---------------------------------------------------------------------------------------------------------------------------------------
146
226
  add(entityValue){
147
227
  // This will call context API to REMOVE entity to update list
148
228
  tools.clearAllProto(entityValue);
149
229
  entityValue.__state = "insert";
150
230
  entityValue.__entity = this.__entity;
151
231
  entityValue.__context = this.__context;
232
+ entityValue.__name = this.__entity.__name;
152
233
  this.__context.__track(entityValue);
153
234
  }
154
235
 
@@ -158,6 +239,14 @@ class queryMethods{
158
239
  entityValue.__context = this.__context;
159
240
  }
160
241
 
242
+ removeRange(entityValues){
243
+ for (const property in entityValues) {
244
+ entityValues[property].__state = "delete";
245
+ entityValues[property].__entity = this.__entity;
246
+ entityValues[property].__context = this.__context;
247
+ }
248
+ }
249
+
161
250
  track(entityValue){
162
251
  entityValue.__state = "track";
163
252
  tools.clearAllProto(entityValue);
@@ -1,4 +1,4 @@
1
- // version 1.0.1
1
+ // version 0.0.2
2
2
 
3
3
  const LOG_OPERATORS_REGEX = /(\|\|)|(&&)/;
4
4
  var tools = require('../Tools');
@@ -10,10 +10,15 @@ class queryScript{
10
10
  script = {
11
11
  select : false,
12
12
  where: false,
13
+ and : [],
13
14
  include : [],
14
15
  raw: false,
15
16
  entity : "",
16
- entityMap : []
17
+ entityMap : [],
18
+ take : 0,
19
+ skip: 0,
20
+ orderBy : false,
21
+ orderByDesc : false
17
22
  };
18
23
 
19
24
 
@@ -21,10 +26,15 @@ class queryScript{
21
26
  this.script = {
22
27
  select : false,
23
28
  where: false,
29
+ and : [],
24
30
  include : [],
25
31
  raw: false,
26
32
  entity : "",
27
- entityMap : []
33
+ entityMap : [],
34
+ take : 0,
35
+ skip: 0,
36
+ orderBy : false,
37
+ orderByDesc : false
28
38
  };
29
39
  }
30
40
 
@@ -37,7 +47,23 @@ class queryScript{
37
47
  return this.script;
38
48
  }
39
49
 
50
+ orderBy(text, entityName){
51
+ this.buildScript(text, "orderBy", this.script, entityName);
52
+ return this.script;
53
+ }
54
+
55
+ orderByDesc(text, entityName){
56
+ this.buildScript(text, "orderByDesc", this.script, entityName);
57
+ return this.script;
58
+ }
59
+
60
+ and(text, entityName){
61
+ this.buildScript(text, "and", this.script, entityName);
62
+ return this.script;
63
+ }
64
+
40
65
  where(text, entityName){
66
+
41
67
  this.buildScript(text, "where", this.script, entityName);
42
68
  return this.script;
43
69
  }
@@ -52,13 +78,9 @@ class queryScript{
52
78
  return this.script;
53
79
  }
54
80
 
55
- count(queryString){
56
- var matched = queryString.match(/(?<=select)(.*?)from/gmi );
57
- matched[0] = matched[0].replace("from", "");
58
- var cleanQuery = queryString.replace(/^(.*?)from/gmi, "");
59
- var str = `Select Count(${matched[0]}) from ${cleanQuery}`
60
-
61
- return str;
81
+ count(text, entityName){
82
+ this.buildScript(text, "count", this.script, entityName);
83
+ return this.script;
62
84
  }
63
85
 
64
86
  buildScript(text, type, obj, entityName){
@@ -96,7 +118,7 @@ class queryScript{
96
118
  }
97
119
 
98
120
  this.describeExpressionParts(cachedExpr[entityName], cachedExpr.selectFields[0], obj.entityMap);
99
- if(type === "include"){
121
+ if(type === "include" || type === "and"){
100
122
  obj[type].push(cachedExpr)
101
123
  }
102
124
  else{
@@ -130,8 +152,8 @@ class queryScript{
130
152
  if (!fields.includes(field)) fields.push(field);
131
153
  });
132
154
 
133
- desc.expr = exprStr.trim()
134
- desc.selectFields = fields
155
+ desc.expr = exprStr.trim();
156
+ desc.selectFields = fields;
135
157
  return desc;
136
158
  }
137
159
  else{
@@ -0,0 +1,66 @@
1
+
2
+ // // version 0.0.2
3
+
4
+ // class selectManager{
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 = selectManager;
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
+ */
package/SQLLiteEngine.js CHANGED
@@ -1,4 +1,4 @@
1
- // Version 0.0.1
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
- queryString = this.buildQuery(query, entity, context);
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
- queryString = this.buildQuery(query, entity, context);
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 = queryObject.count(queryString.query)
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
- var queryString = `${queryObject.select} ${queryObject.from} ${queryObject.include} ${queryObject.where}`;
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
- strQuery = `WHERE ${entity}.${field} ${item.expressions[exp].func} '${item.expressions[exp].arg}'`;
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
- strQuery = `${strQuery} and ${entity}.${field} ${item.expressions[exp].func} '${item.expressions[exp].arg}'`;
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(entity[ent].relationshipTable){
268
- if($that.chechUnsupportedWords(entity[ent].relationshipTable)){
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
- if($that.chechUnsupportedWords(ent)){
277
- entitiesList.push(`'${ent}'`);
278
- }
279
- else{
280
- entitiesList.push(ent);
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].relationshipTable === undefined ? column : modelEntity[column].relationshipTable;
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.3
1
+ // Version 0.0.5
2
2
 
3
3
  var modelBuilder = require('./Entity/EntityModelBuilder');
4
4
  var query = require('masterrecord/QueryLanguage/queryMethods');
@@ -21,7 +21,7 @@ class context {
21
21
  __relationshipModels = [];
22
22
  __enviornment = "";
23
23
  __name = "";
24
- isSQite = false;
24
+ isSQLite = false;
25
25
  isMySQL = false;
26
26
 
27
27
  constructor(){
@@ -80,8 +80,6 @@ class context {
80
80
  }
81
81
  }
82
82
 
83
-
84
-
85
83
  __clearErrorHandler(){
86
84
  this._isModelValid = {
87
85
  isValid: true,
@@ -123,7 +121,7 @@ class context {
123
121
  }
124
122
 
125
123
  useSqlite(rootFolderLocation){
126
- this.isSQite = true;
124
+ this.isSQLite = true;
127
125
  var root = process.cwd();
128
126
  var envType = this.__enviornment;
129
127
  var contextName = this.__name;
@@ -181,41 +179,47 @@ class context {
181
179
  saveChanges(){
182
180
  try{
183
181
  var tracked = this.__trackedEntities;
184
- // start transaction
185
- if(this.isSQite){
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
182
 
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
- }
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();
216
219
  }
217
- this.__clearErrorHandler();
218
- this._SQLEngine.endTransaction();
220
+ }
221
+ else{
222
+ console.log("save changes has no tracked entities");
219
223
  }
220
224
  }
221
225
 
@@ -233,12 +237,11 @@ class context {
233
237
 
234
238
 
235
239
  _execute(query){
236
- if(this.isSQite){
240
+ if(this.isSQLite){
237
241
  this._SQLEngine._execute(query);
238
242
  }
239
243
  }
240
244
 
241
- // TODO: WHY WE HAVE DOUBLE TRACKED OBJECTS - LOOP THROUGH ALL TRACKED OBJECTS
242
245
  __track(model){
243
246
  this.__trackedEntities.push(model);
244
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
- $that.cascadeDelete( currentModel[property]);
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
- // TODO: WE are using the relationshipTable and the object name stick to one so that hasMany doesnt have to give a name
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 value because if so then skip we dont need to make an ajax call
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.get === undefined){
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.get(currentModel[entity]);
128
+ currentRealModel[entity] = currentEntity.set(currentModel[entity]);
127
129
  }
128
130
  }
129
131
  }
package/package.json CHANGED
@@ -1,19 +1,19 @@
1
1
  {
2
2
  "name": "masterrecord",
3
3
  "dependencies": {
4
- "better-sqlite3": "^7.6.2",
5
- "commander": "^9.4.0",
6
- "glob" : "^8.0.3",
7
- "deep-object-diff" : "^1.1.7"
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.34",
9
+ "version": "0.0.36",
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": {
13
13
  "type": "git",
14
14
  "url": "git+https://github.com/Tailor/Masterrecord.git"
15
15
  },
16
- "main": "MasterRecord.js",
16
+ "main": "Masterrecord.js",
17
17
  "scripts": {
18
18
  "test": "echo \"Error: no test specified\" && exit 1"
19
19
  },
@@ -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
- */