masterrecord 0.0.23 → 0.0.25

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/Masterrecord.js CHANGED
@@ -1,179 +1,233 @@
1
-
2
- // https://github.com/kriasoft/node-sqlite
3
- // https://www.learnentityframeworkcore.com/dbset/deleting-data
4
- // version 1.0.14
5
-
6
- var modelBuilder = require('masterrecord/Entity/EntityModelBuilder');
7
- var query = require('masterrecord/QueryLanguage/queryBuilder');
8
- var tools = require('./Tools');
9
- var SQLEngine = require('./SQLEngine');
10
-
11
- class Context {
12
-
13
- _isModelValid = {
14
- isValid: true,
15
- errors: []
16
- }
17
- __allContexts = [];
18
- __trackedEntities = [];
19
- __relationshipModels = []
20
-
21
- constructor(){
22
- this._SQLEngine = new SQLEngine();
23
- }
24
-
25
- __SQLiteInit(env, sqlName){
26
- const sqlite3 = require(sqlName);
27
- let DBAddress = `${env.connection}${env.env}.sqlite3`;
28
- var db = new sqlite3(DBAddress, env);
29
- db.__name = sqlName;
30
- return db;
31
- }
32
-
33
- /*
34
- expected model {
35
- "type": "better-sqlite3",
36
- "connection" : "/db/",
37
- "password": "",
38
- "username": ""
39
- }
40
-
41
- */
42
- setup(rootFolderLocation, env){
43
- if(env.type !== undefined){
44
- switch(env.type) {
45
- case "better-sqlite3":
46
- env.connection = rootFolderLocation + env.connection;
47
- this.db = this.__SQLiteInit(env, env.type);
48
- this._SQLEngine.setDB(this.db);
49
- return this;
50
- break;
51
- }
52
- }
53
- }
54
-
55
- returnCopywithoutPrimaryKeyAndVirtual(currentModel){
56
- var newCurrentModel = Object.create(currentModel);
57
- for(var entity in newCurrentModel.__entity) {
58
- var currentEntity = newCurrentModel.__entity[entity];
59
- if (newCurrentModel.__entity.hasOwnProperty(entity)) {
60
- if(currentEntity.primary === true){
61
- newCurrentModel[`__primaryKey`] = newCurrentModel[entity];
62
- delete newCurrentModel[`_${entity}`];
63
- }
64
- }
65
- if(currentEntity.virtual === true){
66
- // skip it from the insert
67
- delete newCurrentModel[`_${entity}`];
68
- }
69
-
70
- }
71
- return newCurrentModel;
72
- }
73
-
74
- // loop through all the enitities and check if required
75
- validateEntity(currentModel){
76
- for(var entity in currentModel.__entity) {
77
- var currentEntity = currentModel.__entity[entity];
78
- if (currentModel.__entity.hasOwnProperty(entity)) {
79
- // TODO: // check if types are correct
80
- if(currentEntity.default){
81
- if(!currentModel[entity]){
82
- currentModel[entity] = currentEntity.default;
83
- }
84
- }
85
-
86
- if(currentEntity.required === true){
87
- if(!currentModel[entity]){
88
- this._isModelValid.isValid = false;
89
- this._isModelValid.errors.push( `Entity ${entity} is a required Field`);
90
- console.log(`Entity ${entity} is a required Field`);
91
- }
92
- }
93
- }
94
-
95
- }
96
- }
97
-
98
- dbset(model){
99
- var validModel = modelBuilder.init(model);
100
- validModel.__name = model.name;
101
- this.__allContexts.push(validModel);
102
- this.createNewInstance(validModel);
103
- }
104
-
105
- createNewInstance(validModel){
106
- this[validModel.__name] = new query(validModel, this);
107
- }
108
-
109
- modelState(){
110
- return this._isModelValid;
111
- }
112
-
113
- saveChanges(){
114
-
115
- for (var model in this.__trackedEntities) {
116
- var currentModel = this.__trackedEntities[model];
117
- // validate required fields
118
- this.validateEntity(currentModel);
119
- if(this._isModelValid.valid === false){
120
- // everything great
121
- console.log(JSON.stringify(this._isModelValid.valid.errors));
122
- }
123
-
124
- try{
125
- switch(currentModel.__state) {
126
- case "modified":
127
- if(currentModel.__dirtyFields.length <= 0){
128
- throw "Tracked entity modified with no values being changed";
129
- }
130
- var cleanCurrentModel = this.returnCopywithoutPrimaryKeyAndVirtual(currentModel);
131
- // build columns equal to value string
132
- var argu = tools.buildSQLEqualTo(cleanCurrentModel);
133
- var primaryKey = tools.getPrimaryKeyObject(cleanCurrentModel.__entity);
134
- var sqlUpdate = {tableName: cleanCurrentModel.__entity.__name, arg: argu, primaryKey : primaryKey, value : cleanCurrentModel[`__primaryKey`] };
135
- this._SQLEngine.update(sqlUpdate);
136
- // code block
137
- break;
138
- case "insert":
139
-
140
- var cleanCurrentModel = this.returnCopywithoutPrimaryKeyAndVirtual(currentModel);
141
- var insertObj = tools.getInsertObj(cleanCurrentModel);
142
- var sqlUpdate = {tableName: cleanCurrentModel.__entity.__name, columns: insertObj.columns, values: insertObj.values };
143
- this._SQLEngine.insert(sqlUpdate);
144
- break;
145
- case "delete":
146
- var primaryKey = tools.getPrimaryKeyObject(currentModel.__entity);
147
- var sqlUpdate = {tableName: currentModel.__entity.__name, primaryKey : primaryKey, value : currentModel[primaryKey] };
148
- this._SQLEngine.delete(sqlUpdate);
149
- break;
150
- }
151
- }
152
- catch(error){
153
- this.__trackedEntities = [];
154
- console.log("error", error);
155
- }
156
- }
157
- this.__trackedEntities = [];
158
- return true;
159
- }
160
-
161
- __Track(model){
162
- this.__trackedEntities.push(model);
163
- return model;
164
- }
165
-
166
- __FindTracked(id){
167
- if(id){
168
- for (var model in this.__trackedEntities) {
169
- if(this.__trackedEntities[model].__ID === id){
170
- return this.__trackedEntities[model];
171
- }
172
- }
173
- }
174
- return null;
175
- }
176
- }
177
-
178
-
179
- module.exports = Context;
1
+
2
+ // https://github.com/kriasoft/node-sqlite
3
+ // https://www.learnentityframeworkcore.com/dbset/deleting-data
4
+ // version 1.0.14
5
+
6
+ var modelBuilder = require('./Entity/EntityModelBuilder');
7
+ var query = require('masterrecord/QueryLanguage/queryMethods');
8
+ var tools = require('./Tools');
9
+ var SQLLiteEngine = require('masterrecord/SQLLiteEngine');
10
+ var MYSQLEngine = require('masterrecord/MYSQLEngine');
11
+ var insertManager = require('./InsertManager');
12
+ var deleteManager = require('./DeleteManager');
13
+
14
+ class Context {
15
+ _isModelValid = {
16
+ isValid: true,
17
+ errors: []
18
+ };
19
+ __entities = [];
20
+ __builderEntities = [];
21
+ __trackedEntities = [];
22
+ __relationshipModels = [];
23
+
24
+ constructor(){
25
+ // TODO when we build the sql engine it depends on the which type.
26
+
27
+ this._SQLEngine = "";
28
+ this.__name = this.constructor.name;
29
+ }
30
+
31
+ /*
32
+ SQLite expected model
33
+ {
34
+ "type": "better-sqlite3",
35
+ "connection" : "/db/",
36
+ "password": "",
37
+ "username": ""
38
+ }
39
+ */
40
+ __SQLiteInit(env, sqlName){
41
+ try{
42
+ const sqlite3 = require(sqlName);
43
+ let DBAddress = `${env.completeConnection}${env.env}.sqlite3`;
44
+ var db = new sqlite3(DBAddress, env);
45
+ db.__name = sqlName;
46
+ this._SQLEngine = new SQLLiteEngine();
47
+ return db;
48
+ }
49
+ catch (e) {
50
+ console.log("error SQL", e);
51
+ }
52
+ }
53
+
54
+ /*
55
+ mysql expected model
56
+ {
57
+ "type": "mysql",
58
+ host : 'localhost',
59
+ user : 'me',
60
+ password : 'secret',
61
+ database : 'my_db'
62
+ }
63
+ */
64
+ __mysqlInit(env, sqlName){
65
+ try{
66
+ const mysql = require(sqlName);
67
+ const connection = mysql.createConnection(env);
68
+ connection.connect();
69
+ db.__name = sqlName;
70
+ this._SQLEngine = new MYSQLEngine();
71
+ return connection;
72
+
73
+ }
74
+ catch (e) {
75
+ console.log("error SQL", e);
76
+ }
77
+ }
78
+
79
+
80
+
81
+ __clearErrorHandler(){
82
+ this._isModelValid = {
83
+ isValid: true,
84
+ errors: []
85
+ };
86
+ };
87
+
88
+ setup(options, rootFolderLocation){
89
+
90
+ if(options !== undefined){
91
+ if(options.type !== undefined){
92
+ switch(options.type) {
93
+ case "better-sqlite3":
94
+ options.completeConnection = rootFolderLocation + options.connection;
95
+ this.db = this.__SQLiteInit(options, options.type);
96
+ this._SQLEngine.setDB(this.db, "better-sqlite3");
97
+ return this;
98
+ break;
99
+ case "mysql":
100
+ this.db = this.__mysqlInit(options, options.type);
101
+ this._SQLEngine.setDB(this.db, "mysql");
102
+ return this;
103
+ break;
104
+ }
105
+ }
106
+ else{
107
+ console.log("database type not defined - Master Record");
108
+ }
109
+ }
110
+ else{
111
+ console.log("database information not added - Master Record");
112
+ }
113
+
114
+ }
115
+
116
+ dbset(model, name){
117
+ var validModel = modelBuilder.create(model);
118
+ validModel.__name = name === undefined ? model.name : name;
119
+ this.__entities.push(validModel); // model object
120
+ var buildMod = tools.createNewInstance(validModel, query, this);
121
+ this.__builderEntities.push(buildMod); // query builder entites
122
+ this[validModel.__name] = buildMod;
123
+ }
124
+
125
+ modelState(){
126
+ return this._isModelValid;
127
+ }
128
+
129
+ saveChanges(){
130
+ try{
131
+ var tracked = this.__trackedEntities;
132
+ // start transaction
133
+ this._SQLEngine.startTransaction();
134
+ for (var model in tracked) {
135
+ var currentModel = tracked[model];
136
+ switch(currentModel.__state) {
137
+ case "insert":
138
+ var insert = new insertManager(this._SQLEngine, this._isModelValid, this.__entities);
139
+ insert.init(currentModel);
140
+
141
+ break;
142
+ case "modified":
143
+ if(currentModel.__dirtyFields.length > 0){
144
+ var cleanCurrentModel = tools.removePrimarykeyandVirtual(currentModel, currentModel._entity);
145
+ // build columns equal to value string
146
+ var argu = this._SQLEngine._buildSQLEqualTo(cleanCurrentModel);
147
+ var primaryKey = tools.getPrimaryKeyObject(cleanCurrentModel.__entity);
148
+ var sqlUpdate = {tableName: cleanCurrentModel.__entity.__name, arg: argu, primaryKey : primaryKey, primaryKeyValue : cleanCurrentModel[primaryKey] };
149
+ this._SQLEngine.update(sqlUpdate);
150
+ }
151
+ else{
152
+ console.log("Tracked entity modified with no values being changed");
153
+ }
154
+
155
+ // code block
156
+ break;
157
+ case "delete":
158
+ var deleteObject = new deleteManager(this._SQLEngine, this.__entities);
159
+ deleteObject.init(currentModel);
160
+
161
+ break;
162
+ }
163
+ }
164
+ this.__clearErrorHandler();
165
+ this._SQLEngine.endTransaction();
166
+ }
167
+
168
+ catch(error){
169
+ this.__clearErrorHandler();
170
+ this._SQLEngine.errorTransaction();
171
+ console.log("error", error);
172
+ this.__clearTracked();
173
+ throw error;
174
+ }
175
+
176
+ this.__clearTracked();
177
+ return true;
178
+ }
179
+
180
+ // TODO: WHY WE HAVE DOUBLE TRACKED OBJECTS - LOOP THROUGH ALL TRACKED OBJECTS
181
+ __track(model){
182
+ this.__trackedEntities.push(model);
183
+ return model;
184
+ }
185
+
186
+ __findTracked(id){
187
+ if(id){
188
+ for (var model in this.__trackedEntities) {
189
+ if(this.__trackedEntities[model].__ID === id){
190
+ return this.__trackedEntities[model];
191
+ }
192
+ }
193
+ }
194
+ return null;
195
+ }
196
+
197
+ __clearTracked(){
198
+ this.__trackedEntities = [];
199
+ }
200
+ }
201
+
202
+
203
+ module.exports = Context;
204
+
205
+ /*
206
+
207
+ //Create new standard
208
+ var standard = new Standard();
209
+ standard.StandardName = "Standard1";
210
+
211
+ //create three new teachers
212
+ var teacher1 = new Teacher();
213
+ teacher1.TeacherName = "New Teacher1";
214
+
215
+ var teacher2 = new Teacher();
216
+ teacher2.TeacherName = "New Teacher2";
217
+
218
+ var teacher3 = new Teacher();
219
+ teacher3.TeacherName = "New Teacher3";
220
+
221
+ //add teachers for new standard
222
+ standard.Teachers.Add(teacher1);
223
+ standard.Teachers.Add(teacher2);
224
+ standard.Teachers.Add(teacher3);
225
+
226
+ using (var dbCtx = new SchoolDBEntities())
227
+ {
228
+ //add standard entity into standards entitySet
229
+ dbCtx.Standards.Add(standard);
230
+ //Save whole entity graph to the database
231
+ dbCtx.SaveChanges();
232
+ }
233
+ */
package/Migrations/cli.js CHANGED
@@ -1,106 +1,107 @@
1
- #!/usr/bin/env node
2
- // https://docs.microsoft.com/en-us/ef/ef6/modeling/code-first/migrations/
3
- const program = require('commander');
4
- let fs = require('fs');
5
- let path = require('path');
6
- var Migration = require('./migrations');
7
-
8
- const [,, ...args] = process.argv
9
-
10
- program
11
- .version('0.0.1')
12
- .option('-v, --version', '0.0.1')
13
- .description('A ORM framework that facilitates the creation and use of business objects whose data requires persistent storage to a database');
14
-
15
- // Instructions : to run command you must go to folder where contaxt file is located and run command with context file name.
16
- program
17
- .command('enable-migrations <contextFileName>')
18
- .alias('am')
19
- .description('Enables the migration in your project by creating a Configuration class called ContextModelSnapShot.json')
20
- .action(function(contextFileName){
21
- // location of folder where command is being executed..
22
- var executedLocation = process.cwd();
23
- // go back 1 folder level
24
- let previousFolder = path.join(executedLocation, '../');
25
- var migrationsDirectory = `${previousFolder}/Migrations`;
26
- if (!fs.existsSync(migrationsDirectory)){
27
- fs.mkdirSync(migrationsDirectory);
28
- }
29
-
30
- var content = {
31
- contextLocation: `${executedLocation}/${contextFileName}.js`,
32
- migrationLocation: `${executedLocation}/Migrations`,
33
- schema : {}
34
- };
35
- const jsonContent = JSON.stringify(content, null, 2);
36
- try{
37
- // will replace the whole file if it exist
38
- fs.writeFileSync(`${migrationsDirectory}/ContextSnapShot.json`, jsonContent);
39
- }catch (e){
40
- console.log("Cannot write file ", e);
41
- }
42
- });
43
-
44
- program
45
- .command('add-migration <name>')
46
- .alias('am')
47
- .description('Creates a new migration class')
48
- .action(function(name){
49
-
50
- try{
51
- var contextSnapshot = fs.readFileSync(`./ContextSnapShot.json`, 'utf8');
52
- var migration = new Migration();
53
- var context = require(contextSnapshot.contextLocation);
54
- var newEntity = migration.EDMModelDiffer(contextSnapshot.schema, context);
55
- if(newEntity !== -1){
56
- var migrationDate = Date.now();
57
- migration.migrationCodeGenerator(name, newEntity, migrationDate);
58
- console.log(`migration ${name}_${migrationDate} created`);
59
- }
60
- }catch (e){
61
- console.log("Cannot read or find file ", e);
62
- }
63
-
64
- });
65
-
66
- // will use the database settings to call and get the schema_migration table
67
- // we will get the list of all migrations that have been ran
68
- // we will compare that list with the folder of migrations to see if we ran everything
69
- // the migrations we missed we will call the up method
70
- // the up method will run the create database functions
71
- // then update the database.js schema
72
-
73
- program
74
- .command('update-database <databaseSettingLocation> <migrationFolderLocation> ')
75
- .alias('ud')
76
- .description('Apply pending migrations to database')
77
- .action(function(cmd){
78
- var dir = process.cwd();
79
- console.log("starting server");
80
- require(dir + '/server.js');
81
- //return "node c:\node\server.js"
82
- });
83
-
84
- // we will find the migration folder inside the nearest app folder if no migration folder is location is added
85
- program
86
- .command('remove-migration <name> <migrationFolderLocation>')
87
- .alias('rm')
88
- .description('Removes the last migration that has not been applied')
89
- .action(function(name){
90
- // find migration file using name and delete it.
91
- });
92
-
93
-
94
- // we will find the migration folder inside the nearest app folder if no migration folder is location is added
95
- program
96
- .command('revert-migration <name> <migrationFolderLocation>')
97
- .alias('rm')
98
- .description('Reverts back to the last migration with given name')
99
- .action(function(cmd){
100
- var dir = process.cwd();
101
- console.log("starting server");
102
- require(dir + '/server.js');
103
- //return "node c:\node\server.js"
104
- });
105
-
1
+ #!/usr/bin/env node
2
+ // https://docs.microsoft.com/en-us/ef/ef6/modeling/code-first/migrations/
3
+ const program = require('commander');
4
+ let fs = require('fs');
5
+ let path = require('path');
6
+ var Migration = require('./migrations');
7
+
8
+ const [,, ...args] = process.argv
9
+
10
+ program
11
+ .version('0.0.1')
12
+ .option('-v, --version', '0.0.1')
13
+ .description('A ORM framework that facilitates the creation and use of business objects whose data requires persistent storage to a database');
14
+
15
+ // Instructions : to run command you must go to folder where context file is located and run command with context file name.
16
+ program
17
+ .command('enable-migrations <contextFileName>')
18
+ .alias('am')
19
+ .description('Enables the migration in your project by creating a Configuration class called ContextModelSnapShot.json')
20
+ .action(function(contextFileName){
21
+ // location of folder where command is being executed..
22
+ var executedLocation = process.cwd();
23
+ // go back 1 folder level
24
+ let previousFolder = path.join(executedLocation, '../');
25
+ var migrationsDirectory = `${previousFolder}/Migrations`;
26
+ if (!fs.existsSync(migrationsDirectory)){
27
+ fs.mkdirSync(migrationsDirectory);
28
+ }
29
+
30
+ var content = {
31
+ contextLocation: `${executedLocation}/${contextFileName}.js`,
32
+ migrationLocation: `${executedLocation}/Migrations`,
33
+ schema : {}
34
+ };
35
+ const jsonContent = JSON.stringify(content, null, 2);
36
+ try{
37
+ // will replace the whole file if it exist
38
+ fs.writeFileSync(`${migrationsDirectory}/ContextSnapShot.json`, jsonContent);
39
+ }catch (e){
40
+ console.log("Cannot write file ", e);
41
+ }
42
+ });
43
+
44
+ // Instructions : to run command you must go to folder where migration file is located.
45
+ program
46
+ .command('add-migration <name>')
47
+ .alias('am')
48
+ .description('Creates a new migration class')
49
+ .action(function(name){
50
+
51
+ try{
52
+ var contextSnapshot = fs.readFileSync(`./ContextSnapShot.json`, 'utf8');
53
+ var migration = new Migration();
54
+ var context = require(contextSnapshot.contextLocation);
55
+ var newEntity = migration.EDMModelDiffer(contextSnapshot.schema, context);
56
+ if(newEntity.length > 0){
57
+ var migrationDate = Date.now();
58
+ migration.migrationCodeGenerator(name, newEntity, migrationDate);
59
+ console.log(`migration ${name}_${migrationDate} created`);
60
+ }
61
+ }catch (e){
62
+ console.log("Cannot read or find file ", e);
63
+ }
64
+
65
+ });
66
+
67
+ // will use the database settings to call and get the schema_migration table
68
+ // we will get the list of all migrations that have been ran
69
+ // we will compare that list with the folder of migrations to see if we ran everything
70
+ // the migrations we missed we will call the up method
71
+ // the up method will run the create database functions
72
+ // then update the database.js schema
73
+
74
+ program
75
+ .command('update-database <databaseSettingLocation> <migrationFolderLocation> ')
76
+ .alias('ud')
77
+ .description('Apply pending migrations to database')
78
+ .action(function(cmd){
79
+ var dir = process.cwd();
80
+ console.log("starting server");
81
+ require(dir + '/server.js');
82
+ //return "node c:\node\server.js"
83
+ });
84
+
85
+ // we will find the migration folder inside the nearest app folder if no migration folder is location is added
86
+ program
87
+ .command('remove-migration <name> <migrationFolderLocation>')
88
+ .alias('rm')
89
+ .description('Removes the last migration that has not been applied')
90
+ .action(function(name){
91
+ // find migration file using name and delete it.
92
+ });
93
+
94
+
95
+ // we will find the migration folder inside the nearest app folder if no migration folder is location is added
96
+ program
97
+ .command('revert-migration <name> <migrationFolderLocation>')
98
+ .alias('rm')
99
+ .description('Reverts back to the last migration with given name')
100
+ .action(function(cmd){
101
+ var dir = process.cwd();
102
+ console.log("starting server");
103
+ require(dir + '/server.js');
104
+ //return "node c:\node\server.js"
105
+ });
106
+
106
107
  program.parse(process.argv);