nails-boilerplate 1.3.1 → 2.0.1
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/lib/nails.js +11 -28
- package/package.json +1 -1
- package/spec/mongodb_connector.util.js +2 -2
- package/lib/model.js +0 -167
- package/lib/mongodb_connector.js +0 -100
- package/lib/sqlite3_connector.js +0 -88
- package/spec/model.spec.js +0 -95
- package/spec/mongodb_connector.spec.js +0 -66
package/lib/nails.js
CHANGED
|
@@ -15,14 +15,10 @@ import { EventEmitter } from 'node:events';
|
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
import Controller from './controller.js';
|
|
18
|
-
import Model from './model.js';
|
|
19
18
|
import ModelV2 from './model_v2.js';
|
|
20
19
|
import Router from './router.js';
|
|
21
20
|
|
|
22
21
|
import express_app from './application.js';
|
|
23
|
-
import DbConnector from './database_connector.js';
|
|
24
|
-
|
|
25
|
-
const models = {};
|
|
26
22
|
|
|
27
23
|
// TODO: add key value pairs to express app singleton.
|
|
28
24
|
var application = {};
|
|
@@ -42,7 +38,6 @@ export default async function nails(app_config) {
|
|
|
42
38
|
nails.application = express_app;
|
|
43
39
|
nails.Controller = Controller;
|
|
44
40
|
nails.Model = ModelV2;
|
|
45
|
-
nails.ModelDeprecated = Model;
|
|
46
41
|
nails.events = new EventEmitter();
|
|
47
42
|
|
|
48
43
|
async function configure( app_config ) {
|
|
@@ -75,26 +70,14 @@ async function configure( app_config ) {
|
|
|
75
70
|
console.log("Initializing DB connection...");
|
|
76
71
|
var DBConnector = await get_dbconnector(app_config.db.connector);
|
|
77
72
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
console.log("Generating model superclass...");
|
|
87
|
-
await DBConnector.connect(app_config.db);
|
|
88
|
-
ModelV2.setConnector(DBConnector);
|
|
89
|
-
await init_models_v2(app_config.config.MODELS_ROOT);
|
|
90
|
-
DBConnector.afterInitialization();
|
|
91
|
-
} else {
|
|
92
|
-
console.log("Instantiating DBConnector...");
|
|
93
|
-
// Try to instantiate DBConnector
|
|
94
|
-
let dbConnector = new DBConnector();
|
|
95
|
-
await dbConnector.connect(app_config.db);
|
|
96
|
-
ModelV2.setConnector(dbConnector);
|
|
97
|
-
}
|
|
73
|
+
console.log("Instantiating DBConnector and Connecting to DB...");
|
|
74
|
+
// Try to instantiate DBConnector
|
|
75
|
+
let dbConnector = new DBConnector();
|
|
76
|
+
await dbConnector.connect(app_config.db);
|
|
77
|
+
console.log("Generating model superclass...");
|
|
78
|
+
ModelV2.setConnector(dbConnector);
|
|
79
|
+
await init_models_v2(app_config.config.MODELS_ROOT);
|
|
80
|
+
await dbConnector.afterInitialization();
|
|
98
81
|
console.log("DB Connection complete");
|
|
99
82
|
|
|
100
83
|
// init Controllers
|
|
@@ -151,9 +134,9 @@ function startServer(config) {
|
|
|
151
134
|
async function init_controllers(controller_lib) {
|
|
152
135
|
await init_app_lib(Controller, controller_lib);
|
|
153
136
|
}
|
|
154
|
-
async function init_models(model_lib) {
|
|
155
|
-
|
|
156
|
-
}
|
|
137
|
+
// async function init_models(model_lib) {
|
|
138
|
+
// await init_app_lib(Model, model_lib);
|
|
139
|
+
// }
|
|
157
140
|
async function init_app_lib(superclass, abs_path) {
|
|
158
141
|
console.log('attempting to import:', abs_path);
|
|
159
142
|
if (!fs.existsSync(abs_path))
|
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import MongooseConnector from '../lib/mongoose_connector.js';
|
|
2
2
|
import {MongoMemoryServer} from 'mongodb-memory-server';
|
|
3
3
|
|
|
4
4
|
let singularInstanceCreated = false;
|
|
@@ -19,7 +19,7 @@ class MongoDBConnectorUtil {
|
|
|
19
19
|
const dbConfig =
|
|
20
20
|
{uri: uri, port: port, database: dbName, dbPath: dbPath};
|
|
21
21
|
//console.log(JSON.stringify(dbConfig));
|
|
22
|
-
return new
|
|
22
|
+
return new MongooseConnector(dbConfig);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
async cleanup() {
|
package/lib/model.js
DELETED
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
// This is the base definition for a model / collection
|
|
2
|
-
// ideally used as a wrapper for database integration
|
|
3
|
-
// should use promise objects to allow for method chaining
|
|
4
|
-
// eventful. emits ready event passing itself
|
|
5
|
-
// start with mongodb
|
|
6
|
-
import util from 'util';
|
|
7
|
-
import controller_base from './controller.js';
|
|
8
|
-
// var controller_base = require('./controller.js');
|
|
9
|
-
// var util = require('util');
|
|
10
|
-
|
|
11
|
-
/** TODO: what persistence methods does a model need?
|
|
12
|
-
* save/post => saves record to db
|
|
13
|
-
* fetch/get => updates model from database
|
|
14
|
-
* patch/put(?) => only changes specific methods and saves to database...
|
|
15
|
-
* destroy/delete => remove model from db
|
|
16
|
-
*
|
|
17
|
-
** On Constructor:
|
|
18
|
-
*
|
|
19
|
-
* get => get a single model by id
|
|
20
|
-
* find => get a collection of models by parameters
|
|
21
|
-
*/
|
|
22
|
-
/** TODO: define a collection
|
|
23
|
-
*
|
|
24
|
-
* will likely want to put collection constructor as attribute on Model
|
|
25
|
-
* f/e Model.Collection
|
|
26
|
-
*
|
|
27
|
-
** Persistence methods:
|
|
28
|
-
*
|
|
29
|
-
* save/post => save collection in database by batch command
|
|
30
|
-
* will want to minimize number of db requests, but can probably
|
|
31
|
-
* start with saving each individually for now
|
|
32
|
-
* fetch/get => updates collection from database
|
|
33
|
-
* a collection should have a saved query attribute which
|
|
34
|
-
* was used to get the collection. Will make updating easy.
|
|
35
|
-
*/
|
|
36
|
-
|
|
37
|
-
// init references to model base objects for use by controllers
|
|
38
|
-
// and models
|
|
39
|
-
controller_base.prototype.models = {};
|
|
40
|
-
Model.prototype.models = {};
|
|
41
|
-
|
|
42
|
-
var model_prot = Model.prototype;
|
|
43
|
-
var db;
|
|
44
|
-
|
|
45
|
-
var NAME_REQUIRED_ERROR = function() {
|
|
46
|
-
return new Error(
|
|
47
|
-
'FATAL ERROR::: Named function required for Model constructor method'
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export default function Model(){
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
Model.extend = function(constructor) {
|
|
55
|
-
//console.log('extending', constructor.name);
|
|
56
|
-
if ( !constructor.name ) throw NAME_REQUIRED_ERROR();
|
|
57
|
-
//model_proto = model_proto || new Model();
|
|
58
|
-
constructor.prototype.__proto__ = model_prot;
|
|
59
|
-
|
|
60
|
-
// TODO: bind collection-specific methods to the constructor
|
|
61
|
-
//Model.set_db_access_methods(contructor);
|
|
62
|
-
|
|
63
|
-
// make models available to controller and other models
|
|
64
|
-
Model.prototype.models[constructor.name] = constructor;
|
|
65
|
-
controller_base.prototype.models[constructor.name] = constructor;
|
|
66
|
-
|
|
67
|
-
};
|
|
68
|
-
Model.set_connector = function(DBConnector, config) {
|
|
69
|
-
if (!config) {
|
|
70
|
-
this.prototype.connector = DBConnector;
|
|
71
|
-
} else {
|
|
72
|
-
this.prototype.connector = new DBConnector(config);
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
Model.set_db_access_methods = function(constructor) {
|
|
76
|
-
constructor.find = Model.find;
|
|
77
|
-
};
|
|
78
|
-
Model.find = function() {
|
|
79
|
-
var args = Array.prototype.slice.call(arguments, 0);
|
|
80
|
-
return this.connector.find.apply(connector, args);
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
Object.defineProperty(Model.prototype, 'id', {
|
|
84
|
-
get: function() {
|
|
85
|
-
return this.attributes[this.id_attribute];
|
|
86
|
-
},
|
|
87
|
-
set: function(new_val) {
|
|
88
|
-
this.set(this.id_attribute, new_val);
|
|
89
|
-
return new_val;
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
Object.defineProperty(Model.prototype, 'attributes', {
|
|
93
|
-
get: function() {
|
|
94
|
-
if (!this._attributes) this._attributes = {};
|
|
95
|
-
return this._attributes;
|
|
96
|
-
},
|
|
97
|
-
set: function(new_val) {
|
|
98
|
-
if (typeof new_val != 'object' && util.isArray(new_val))
|
|
99
|
-
throw 'Model#attributes cannot be set to non-object or array value';
|
|
100
|
-
this._extend_deeply(this.attributes, new_val, true);
|
|
101
|
-
return this.attributes;
|
|
102
|
-
}
|
|
103
|
-
});
|
|
104
|
-
Model.prototype.id_attribute = '_id';
|
|
105
|
-
Model.prototype.is_model = true;
|
|
106
|
-
/**
|
|
107
|
-
* returns the name of the collection or table in the db.
|
|
108
|
-
* override this by setting collection attribute on the model.
|
|
109
|
-
*/
|
|
110
|
-
Model.prototype._collection_name = function() {
|
|
111
|
-
return this.collection || this.constructor.name;
|
|
112
|
-
};
|
|
113
|
-
/**
|
|
114
|
-
* pointer to the database connector
|
|
115
|
-
*/
|
|
116
|
-
Model.prototype.connector = {};
|
|
117
|
-
|
|
118
|
-
Model.prototype.save = function() {
|
|
119
|
-
// this should create the model if it does not exist
|
|
120
|
-
// (uses an id to check existence)
|
|
121
|
-
// or it should update the model
|
|
122
|
-
if (this.id) return this.connector.put(this);
|
|
123
|
-
return this.connector.post(this);
|
|
124
|
-
};
|
|
125
|
-
Model.prototype.fetch = function() {
|
|
126
|
-
if (!this.id) throw 'cannot fetch model with id: ' + this.id.toString();
|
|
127
|
-
return this.connector.get(this);
|
|
128
|
-
// TODO: give model backbone-like sync event
|
|
129
|
-
};
|
|
130
|
-
/*
|
|
131
|
-
Model.prototype.patch = function() {
|
|
132
|
-
// should try to update the model's changed attributes if no
|
|
133
|
-
// arguments given. Otherwise should attempt to set attributes
|
|
134
|
-
// on model and then update
|
|
135
|
-
Model.connector.update(this);
|
|
136
|
-
};
|
|
137
|
-
*/
|
|
138
|
-
Model.prototype.destroy = function() {
|
|
139
|
-
// should delete the model from the database if it has been
|
|
140
|
-
// persisted
|
|
141
|
-
if (this.id) return false;
|
|
142
|
-
this.connector.delete(this);
|
|
143
|
-
};
|
|
144
|
-
Model.prototype.set = function(attr, val) {
|
|
145
|
-
this.attributes[attr] = val;
|
|
146
|
-
};
|
|
147
|
-
/**
|
|
148
|
-
* merge a hash of attributes into the current set
|
|
149
|
-
*/
|
|
150
|
-
Model.prototype._merge_attributes = function(attr) {
|
|
151
|
-
this._extend_deeply(this.attributes, attr);
|
|
152
|
-
};
|
|
153
|
-
Model.prototype._extend_deeply = function(obj0, obj1, should_prune) {
|
|
154
|
-
if (typeof obj0 != 'object' || typeof obj1 != 'object' ||
|
|
155
|
-
util.isArray(obj0) || util.isArray(obj1))
|
|
156
|
-
throw 'Attempting to extend a non-object entity';
|
|
157
|
-
for(var key in obj1) {
|
|
158
|
-
if (typeof obj0[key] == 'object' && typeof obj1[key] == 'object' && !util.isArray(obj0[key]))
|
|
159
|
-
this._extend_deeply(obj0[key], obj1[key], should_prune);
|
|
160
|
-
else obj0[key] = obj1[key];
|
|
161
|
-
}
|
|
162
|
-
if (!should_prune) return;
|
|
163
|
-
for (key in obj0) {
|
|
164
|
-
if (key in obj1) continue;
|
|
165
|
-
delete obj0[key];
|
|
166
|
-
}
|
|
167
|
-
};
|
package/lib/mongodb_connector.js
DELETED
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
// TODO: multiple async requests here... need to
|
|
2
|
-
// consider how this will be used by the models
|
|
3
|
-
import {EventEmitter} from 'node:events';
|
|
4
|
-
// var EventEmitter = require('events').EventEmitter;
|
|
5
|
-
// const MongoClient = require('mongodb').MongoClient;
|
|
6
|
-
import { MongoClient } from 'mongodb';
|
|
7
|
-
|
|
8
|
-
export default MongoDBConnector;
|
|
9
|
-
|
|
10
|
-
// TODO: need to deal with clustered databases...
|
|
11
|
-
|
|
12
|
-
MongoDBConnector.prototype.__proto__ = EventEmitter.prototype;
|
|
13
|
-
function MongoDBConnector(config) {
|
|
14
|
-
EventEmitter.call(this);
|
|
15
|
-
var url = config.url || 'mongodb://localhost';
|
|
16
|
-
var port = config.port || '27017';
|
|
17
|
-
var database = config.database || 'nails';
|
|
18
|
-
var uri =
|
|
19
|
-
config.uri ? config.uri : `${url}:${port}/${database}`;
|
|
20
|
-
this.exec_once_connected = [];
|
|
21
|
-
var that = this;
|
|
22
|
-
MongoClient.connect(uri)
|
|
23
|
-
.then(client => {
|
|
24
|
-
this._client = client;
|
|
25
|
-
this._db = client.db(database);
|
|
26
|
-
this.emit("connected");
|
|
27
|
-
}).catch(error => {
|
|
28
|
-
// TODO: better handling of the failed connection
|
|
29
|
-
console.error(error);
|
|
30
|
-
throw error;
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Need to implement these methods for a connector to work
|
|
36
|
-
*/
|
|
37
|
-
// maybe use rest methods as names for any database connector used...
|
|
38
|
-
MongoDBConnector.prototype.post = function(model_or_collection) {
|
|
39
|
-
if (model_or_collection.is_model)
|
|
40
|
-
return this._post_one(model_or_collection._collection_name(),
|
|
41
|
-
model_or_collection.attributes);
|
|
42
|
-
}
|
|
43
|
-
MongoDBConnector.prototype._post_one = function(collection_name, doc_attributes, callback) {
|
|
44
|
-
return this._db.collection(collection_name).insert(doc_attributes);
|
|
45
|
-
}
|
|
46
|
-
MongoDBConnector.prototype._post_many = function(collection) {
|
|
47
|
-
return this._db.collection(collection.name())
|
|
48
|
-
.save(collection.model_attributes());
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// update a record in the collection
|
|
52
|
-
MongoDBConnector.prototype.put = function(model_or_collection) {
|
|
53
|
-
if (model_or_collection.is_model)
|
|
54
|
-
return this._put_one(
|
|
55
|
-
model_or_collection._collection_name(),
|
|
56
|
-
model_or_collection.attributes);
|
|
57
|
-
}
|
|
58
|
-
MongoDBConnector.prototype._put_one = function(collection_name, doc) {
|
|
59
|
-
// TODO: replacing document completely is sow
|
|
60
|
-
// will want to only send changed attr
|
|
61
|
-
// TODO: write concerns?
|
|
62
|
-
return this._db.collection(collection_name).replaceOne({_id: doc._id}, doc);
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* _put_many will call _update on each individual object in collection
|
|
66
|
-
* if that object has changed
|
|
67
|
-
*/
|
|
68
|
-
MongoDBConnector.prototype._put_many = function(collection) {
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// return a single record from a collection
|
|
72
|
-
// or a collection of records if requested...
|
|
73
|
-
// if a model or collection is passed,
|
|
74
|
-
MongoDBConnector.prototype.get = function(model_or_collection) {
|
|
75
|
-
if (model_or_collection.is_model)
|
|
76
|
-
return this._get_one(model_or_collection._collection_name(), model_or_collection.id, null)
|
|
77
|
-
.then(doc => this._on_doc_response(model_or_collection, doc));
|
|
78
|
-
}
|
|
79
|
-
MongoDBConnector.prototype._get_one = function(collection_name, id, options) {
|
|
80
|
-
options = options || {};
|
|
81
|
-
return this._db.collection(collection_name).findOne(id, options);
|
|
82
|
-
}
|
|
83
|
-
MongoDBConnector.prototype._get_many = function(collection) {
|
|
84
|
-
return this._db.collection(collection.name()).find({
|
|
85
|
-
_id: collection.collect('_id')});
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// delete a record from a collection
|
|
89
|
-
MongoDBConnector.prototype.delete = function(model) {
|
|
90
|
-
return this._db.collection(model.collection_name())
|
|
91
|
-
.remove(model.attributes._id);
|
|
92
|
-
}
|
|
93
|
-
// MongoDBConnector.prototype._delete_one
|
|
94
|
-
// MongoDBConnector.prototype._delete_many
|
|
95
|
-
|
|
96
|
-
MongoDBConnector.prototype._on_doc_response = function(model_or_collection, doc) {
|
|
97
|
-
// move this to the promise catch block: if (err) return console.log('error retrieving from', collection_name, '\n', err);
|
|
98
|
-
delete doc._id;
|
|
99
|
-
model_or_collection._merge_attributes(doc);
|
|
100
|
-
}
|
package/lib/sqlite3_connector.js
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
// TODO: multiple async requests here... need to
|
|
2
|
-
// consider how this will be used by the models
|
|
3
|
-
import { EventEmitter } from 'events';
|
|
4
|
-
import DBClient from 'node:sqlite';
|
|
5
|
-
// var EventEmitter = require('events').EventEmitter;
|
|
6
|
-
// const DBClient = require('sqlite3');
|
|
7
|
-
import test from 'node:assert';
|
|
8
|
-
// const test = require('assert');
|
|
9
|
-
|
|
10
|
-
module.exports = SQLite3Connector;
|
|
11
|
-
|
|
12
|
-
// TODO: need to deal with clustered databases...
|
|
13
|
-
|
|
14
|
-
SQLite3Connector.prototype.__proto__ = EventEmitter.prototype;
|
|
15
|
-
function SQLite3Connector(config) {
|
|
16
|
-
EventEmitter.call(this);
|
|
17
|
-
var url = config.url || 'mongodb://localhost';
|
|
18
|
-
var port = config.port || '27017';
|
|
19
|
-
var database = config.database || 'nails';
|
|
20
|
-
this.exec_once_connected = [];
|
|
21
|
-
this._db = new DBClient.Database(config.filename);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Need to implement these methods for a connector to work
|
|
26
|
-
*/
|
|
27
|
-
// maybe use rest methods as names for any database connector used...
|
|
28
|
-
SQLite3Connector.prototype.post = function(model_or_collection) {
|
|
29
|
-
if (model_or_collection.is_model)
|
|
30
|
-
this._post_one(model_or_collection._collection_name(),
|
|
31
|
-
model_or_collection.attributes);
|
|
32
|
-
}
|
|
33
|
-
SQLite3Connector.prototype._post_one = function(collection_name, doc_attributes, callback) {
|
|
34
|
-
this._db.collection(collection_name).insert(doc_attributes);
|
|
35
|
-
}
|
|
36
|
-
SQLite3Connector.prototype._post_many = function(collection) {
|
|
37
|
-
this._db.collection(collection.name())
|
|
38
|
-
.save(collection.model_attributes());
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// update a record in the collection
|
|
42
|
-
SQLite3Connector.prototype.put = function(model_or_collection) {
|
|
43
|
-
if (model_or_collection.is_model)
|
|
44
|
-
this._put_one(model_or_collection._collection_name(), model_or_collection.attributes);
|
|
45
|
-
}
|
|
46
|
-
SQLite3Connector.prototype._put_one = function(collection_name, doc) {
|
|
47
|
-
// TODO: replacing document completely is sow
|
|
48
|
-
// will want to only send changed attr
|
|
49
|
-
// TODO: write concerns?
|
|
50
|
-
this._db.collection(collection_name).update({_id: doc._id}, doc);
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* _put_many will call _update on each individual object in collection
|
|
54
|
-
* if that object has changed
|
|
55
|
-
*/
|
|
56
|
-
SQLite3Connector.prototype._put_many = function(collection) {
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// return a single record from a collection
|
|
60
|
-
// or a collection of records if requested...
|
|
61
|
-
// if a model or collection is passed,
|
|
62
|
-
SQLite3Connector.prototype.get = function(model_or_collection) {
|
|
63
|
-
if (model_or_collection.is_model)
|
|
64
|
-
this._get_one(model_or_collection._collection_name(), model_or_collection.id, null,
|
|
65
|
-
this._on_doc_response.bind(model_or_collection));
|
|
66
|
-
}
|
|
67
|
-
SQLite3Connector.prototype._get_one = function(collection_name, id, options, callback) {
|
|
68
|
-
options = options || {};
|
|
69
|
-
this._db.collection(collection_name).findOne(id, options, callback);
|
|
70
|
-
}
|
|
71
|
-
SQLite3Connector.prototype._get_many = function(collection) {
|
|
72
|
-
return this._db.collection(collection.name()).find({
|
|
73
|
-
_id: collection.collect('_id')});
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// delete a record from a collection
|
|
77
|
-
SQLite3Connector.prototype.delete = function(model) {
|
|
78
|
-
return this._db.collection(model.collection_name())
|
|
79
|
-
.remove(model.attributes._id);
|
|
80
|
-
}
|
|
81
|
-
// SQLite3Connector.prototype._delete_one
|
|
82
|
-
// SQLite3Connector.prototype._delete_many
|
|
83
|
-
|
|
84
|
-
SQLite3Connector.prototype._on_doc_response = function(err, doc) {
|
|
85
|
-
if (err) return console.log('error retrieving from', collection_name, '\n', err);
|
|
86
|
-
delete doc._id;
|
|
87
|
-
this._merge_attributes(doc);
|
|
88
|
-
}
|
package/spec/model.spec.js
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import assert from 'assert';
|
|
2
|
-
import Model from '../lib/model.js';
|
|
3
|
-
import MongoDBConnectorUtil from './mongodb_connector.util.js';
|
|
4
|
-
|
|
5
|
-
var test_model = new Model();
|
|
6
|
-
var model_prot = Model.prototype;
|
|
7
|
-
describe('Model', function() {
|
|
8
|
-
var util;
|
|
9
|
-
beforeEach(function(done) {
|
|
10
|
-
util = new MongoDBConnectorUtil();
|
|
11
|
-
util.getTestConnector().then(connector => {
|
|
12
|
-
Model.set_connector(connector);
|
|
13
|
-
connector.on("connected", done);
|
|
14
|
-
});
|
|
15
|
-
});
|
|
16
|
-
afterEach(function(done) {
|
|
17
|
-
util.cleanup().then(() => done());
|
|
18
|
-
});
|
|
19
|
-
describe('#_merge_attributes', function() {
|
|
20
|
-
});
|
|
21
|
-
describe('#_extend_deeply', function() {
|
|
22
|
-
var attr0;
|
|
23
|
-
var attr1;
|
|
24
|
-
beforeEach(function() {
|
|
25
|
-
attr0 = {a:7, b:'test', c:null, o: {}};
|
|
26
|
-
attr1 = {a:8, c:'test0', o: {a:0}};
|
|
27
|
-
});
|
|
28
|
-
it('should rewrite non object attributes', function() {
|
|
29
|
-
model_prot._extend_deeply(attr0, attr1);
|
|
30
|
-
// these should change
|
|
31
|
-
assert(attr0.a == attr1.a);
|
|
32
|
-
assert(attr0.c == attr1.c);
|
|
33
|
-
// these should not
|
|
34
|
-
assert(attr0.b == attr0.b);
|
|
35
|
-
assert(attr0.o == attr0.o);
|
|
36
|
-
});
|
|
37
|
-
it('should merge two attributes if they are both non-array objects',
|
|
38
|
-
function() {
|
|
39
|
-
model_prot._extend_deeply(attr0, attr1);
|
|
40
|
-
assert(attr0.o.a == attr1.o.a);
|
|
41
|
-
});
|
|
42
|
-
it('should delete attributes not present in obj1 if prune is true',
|
|
43
|
-
function() {
|
|
44
|
-
model_prot._extend_deeply(attr0, attr1, true);
|
|
45
|
-
assert(!('b' in attr0));
|
|
46
|
-
});
|
|
47
|
-
it('should not delete attributes absent present in obj1 if prune is falsey', function() {
|
|
48
|
-
model_prot._extend_deeply(attr0, attr1);
|
|
49
|
-
assert(attr0.o.a == attr1.o.a);
|
|
50
|
-
});
|
|
51
|
-
});
|
|
52
|
-
describe('#save', function() {
|
|
53
|
-
it('should save a new model to the database and update id',
|
|
54
|
-
async function() {
|
|
55
|
-
var model0 = new Model();
|
|
56
|
-
var model_name = 'testname0';
|
|
57
|
-
model0.attributes = {
|
|
58
|
-
name: model_name
|
|
59
|
-
};
|
|
60
|
-
await model0.save();
|
|
61
|
-
assert.ok(model0.attributes._id);
|
|
62
|
-
assert.ok(model_name == model0.attributes.name);
|
|
63
|
-
});
|
|
64
|
-
it('should save changes to an existing model to the database',
|
|
65
|
-
async function() {
|
|
66
|
-
var model0 = new Model();
|
|
67
|
-
model0.attributes = {
|
|
68
|
-
name: 'testname1'
|
|
69
|
-
};
|
|
70
|
-
await model0.save();
|
|
71
|
-
model0.set('x', 5);
|
|
72
|
-
await model0.save();
|
|
73
|
-
var model1 = new Model();
|
|
74
|
-
model1.id = model0.id;
|
|
75
|
-
await model1.fetch();
|
|
76
|
-
assert.ok(model1.attributes.x == 5);
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
describe('#fetch', function() {
|
|
80
|
-
it('should retrieve attributes for this model id from the database',
|
|
81
|
-
async function() {
|
|
82
|
-
var model0 = new Model();
|
|
83
|
-
model0.set('x', 7);
|
|
84
|
-
await model0.save();
|
|
85
|
-
var model1 = new Model();
|
|
86
|
-
model1.id = model0.id;
|
|
87
|
-
await model1.fetch();
|
|
88
|
-
assert.ok(model1.attributes.x == 7);
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
describe('#attributes', function() {
|
|
92
|
-
it('should be a plain object');
|
|
93
|
-
it('should not change by reference if set to a different attributes hash');
|
|
94
|
-
});
|
|
95
|
-
});
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import assert from 'assert';
|
|
2
|
-
import MongoDBConnectorUtil from './mongodb_connector.util.js';
|
|
3
|
-
|
|
4
|
-
describe('MongoDBConnector', function() {
|
|
5
|
-
var util;
|
|
6
|
-
var mdbc;
|
|
7
|
-
beforeEach(function(done) {
|
|
8
|
-
util = new MongoDBConnectorUtil();
|
|
9
|
-
util.getTestConnector().then(connector => {
|
|
10
|
-
mdbc = connector;
|
|
11
|
-
connector.on("connected", done);
|
|
12
|
-
});
|
|
13
|
-
});
|
|
14
|
-
afterEach(function(done) {
|
|
15
|
-
util.cleanup().then(() => done());
|
|
16
|
-
});
|
|
17
|
-
it('should create a new connection to mongodb', function(done) {
|
|
18
|
-
assert.notEqual(mdbc._db, null);
|
|
19
|
-
done();
|
|
20
|
-
});
|
|
21
|
-
describe('#put', function() {
|
|
22
|
-
it('should be ok, updating the record in the database');
|
|
23
|
-
});
|
|
24
|
-
describe('Document retrieval', function() {
|
|
25
|
-
describe('#get', function() {
|
|
26
|
-
it('should return a single document when model is passed');
|
|
27
|
-
it('should return an array of docments when collection is passed');
|
|
28
|
-
});
|
|
29
|
-
describe('#_get_one', function() {
|
|
30
|
-
it('should return a single document with the matching _id', async function() {
|
|
31
|
-
var test_model = get_test_model('custom0');
|
|
32
|
-
var test_attr = test_model.attributes;
|
|
33
|
-
await mdbc._post_one(test_model.collection_name(), test_attr);
|
|
34
|
-
let doc = await mdbc._get_one(test_model.collection_name(),
|
|
35
|
-
test_model.attributes._id, null);
|
|
36
|
-
assert.ok(doc.custom_attr == test_attr.custom_attr);
|
|
37
|
-
assert.ok(doc._id.equals(test_attr._id));
|
|
38
|
-
return null;
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
describe('#_get_many', function() {
|
|
42
|
-
it('should return all documents matching the collection._query field');
|
|
43
|
-
});
|
|
44
|
-
});
|
|
45
|
-
describe('Document Creation', function(){
|
|
46
|
-
describe('#_post_one', function() {
|
|
47
|
-
it('should set an _id attribute on the given attributes hash', function(done) {
|
|
48
|
-
var test_model = get_test_model();
|
|
49
|
-
mdbc._post_one(test_model.collection_name(), test_model.attributes)
|
|
50
|
-
.then(() => {
|
|
51
|
-
assert.ok(test_model.attributes._id);
|
|
52
|
-
done();
|
|
53
|
-
});
|
|
54
|
-
});
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
|
-
});
|
|
58
|
-
function get_test_model(custom_attr) {
|
|
59
|
-
return {
|
|
60
|
-
collection_name: function() {return 'test_model'},
|
|
61
|
-
attributes: {
|
|
62
|
-
x: 'x',
|
|
63
|
-
custom_attr: custom_attr
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|