fix(core): update
This commit is contained in:
parent
c6cbff1308
commit
25803330de
1313
package-lock.json
generated
1313
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
35
package.json
35
package.json
@ -21,26 +21,27 @@
|
||||
},
|
||||
"homepage": "https://gitlab.com/pushrocks/smartdata#README",
|
||||
"dependencies": {
|
||||
"@pushrocks/lik": "^3.0.4",
|
||||
"@pushrocks/smartlog": "^2.0.9",
|
||||
"@pushrocks/smartpromise": "^2.0.5",
|
||||
"@pushrocks/smartstring": "^3.0.5",
|
||||
"@types/lodash": "^4.14.119",
|
||||
"@types/mongodb": "^3.1.18",
|
||||
"lodash": "^4.17.11",
|
||||
"mongodb": "^3.1.10",
|
||||
"@pushrocks/lik": "^3.0.11",
|
||||
"@pushrocks/smartlog": "^2.0.19",
|
||||
"@pushrocks/smartpromise": "^3.0.2",
|
||||
"@pushrocks/smartstring": "^3.0.10",
|
||||
"@pushrocks/smartunique": "^3.0.1",
|
||||
"@types/lodash": "^4.14.138",
|
||||
"@types/mongodb": "^3.3.1",
|
||||
"lodash": "^4.17.15",
|
||||
"mongodb": "^3.3.2",
|
||||
"runtime-type-checks": "0.0.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@gitzone/tsbuild": "^2.1.4",
|
||||
"@gitzone/tstest": "^1.0.18",
|
||||
"@pushrocks/qenv": "^3.0.2",
|
||||
"@pushrocks/tapbundle": "^3.0.7",
|
||||
"@types/node": "^10.12.18",
|
||||
"@gitzone/tsbuild": "^2.1.17",
|
||||
"@gitzone/tstest": "^1.0.24",
|
||||
"@pushrocks/qenv": "^4.0.4",
|
||||
"@pushrocks/tapbundle": "^3.0.13",
|
||||
"@types/mongodb-memory-server": "^1.8.0",
|
||||
"@types/node": "^12.7.3",
|
||||
"@types/shortid": "0.0.29",
|
||||
"mongodb-memory-server": "^2.9.1",
|
||||
"shortid": "^2.2.14",
|
||||
"tslint": "^5.12.0",
|
||||
"tslint-config-prettier": "^1.17.0"
|
||||
"mongodb-memory-server": "^5.2.0",
|
||||
"tslint": "^5.19.0",
|
||||
"tslint-config-prettier": "^1.18.0"
|
||||
}
|
||||
}
|
||||
|
67
test/test.ts
67
test/test.ts
@ -1,22 +1,39 @@
|
||||
import { tap, expect } from '@pushrocks/tapbundle';
|
||||
import * as smartpromise from '@pushrocks/smartpromise';
|
||||
import { Qenv } from '@pushrocks/qenv';
|
||||
|
||||
let testQenv = new Qenv(process.cwd(), process.cwd() + '/.nogit/');
|
||||
const testQenv = new Qenv(process.cwd(), process.cwd() + '/.nogit/');
|
||||
|
||||
// the tested module
|
||||
import * as smartdata from '../ts/index';
|
||||
import { smartstring } from '../ts/smartdata.plugins';
|
||||
import * as shortid from 'shortid';
|
||||
import * as smartunique from '@pushrocks/smartunique';
|
||||
|
||||
import * as mongoPlugin from 'mongodb-memory-server';
|
||||
|
||||
// =======================================
|
||||
// Connecting to the database server
|
||||
// =======================================
|
||||
|
||||
let testDb = new smartdata.SmartdataDb({
|
||||
mongoDbName: process.env.MONGO_DBNAME,
|
||||
mongoDbUrl: process.env.MONGO_URL,
|
||||
mongoDbPass: process.env.MONGO_PASS
|
||||
let testDb: smartdata.SmartdataDb;
|
||||
let smartdataOptions: smartdata.ISmartdataOptions;
|
||||
let mongod: mongoPlugin.MongoMemoryServer;
|
||||
|
||||
tap.test('should create a testinstance as database', async () => {
|
||||
mongod = new mongoPlugin.MongoMemoryServer();
|
||||
smartdataOptions = {
|
||||
mongoDbName: await mongod.getDbName(),
|
||||
mongoDbPass: '',
|
||||
mongoDbUrl: await mongod.getConnectionString()
|
||||
};
|
||||
console.log(smartdataOptions);
|
||||
});
|
||||
|
||||
tap.test('should create a smartdb', async () => {
|
||||
testDb = new smartdata.SmartdataDb({
|
||||
mongoDbName: testQenv.getEnvVarOnDemand('MONGO_DBNAME'),
|
||||
mongoDbUrl: testQenv.getEnvVarOnDemand('MONGO_URL'),
|
||||
mongoDbPass: testQenv.getEnvVarOnDemand('MONGO_PASS')
|
||||
});
|
||||
});
|
||||
|
||||
tap.test('should establish a connection to the rethink Db cluster', async () => {
|
||||
@ -31,11 +48,19 @@ tap.test('should establish a connection to the rethink Db cluster', async () =>
|
||||
// Collections
|
||||
// ------
|
||||
|
||||
@smartdata.Collection(testDb)
|
||||
@smartdata.Collection(() => {
|
||||
return testDb;
|
||||
})
|
||||
class Car extends smartdata.SmartDataDbDoc<Car> {
|
||||
@smartdata.unI() index: string = shortid();
|
||||
@smartdata.svDb() color: string;
|
||||
@smartdata.svDb() brand: string;
|
||||
@smartdata.unI()
|
||||
public index: string = smartunique.shortId();
|
||||
|
||||
@smartdata.svDb()
|
||||
public color: string;
|
||||
|
||||
@smartdata.svDb()
|
||||
public brand: string;
|
||||
|
||||
constructor(colorArg: string, brandArg: string) {
|
||||
super();
|
||||
this.color = colorArg;
|
||||
@ -46,20 +71,38 @@ class Car extends smartdata.SmartDataDbDoc<Car> {
|
||||
tap.test('should save the car to the db', async () => {
|
||||
const myCar = new Car('red', 'Volvo');
|
||||
await myCar.save();
|
||||
|
||||
const myCar2 = new Car('red', 'Renault');
|
||||
await myCar2.save();
|
||||
});
|
||||
|
||||
tap.test('expect to get instance of Car', async () => {
|
||||
let myCars = await Car.getInstances<Car>({
|
||||
const myCars = await Car.getInstances<Car>({
|
||||
brand: 'Volvo'
|
||||
});
|
||||
expect(myCars[0].color).to.equal('red');
|
||||
});
|
||||
|
||||
tap.test('expect to get instance of Car and update it', async () => {
|
||||
const myCar = await Car.getInstance<Car>({
|
||||
brand: 'Volvo'
|
||||
});
|
||||
expect(myCar.color).to.equal('red');
|
||||
myCar.color = 'blue';
|
||||
await myCar.save();
|
||||
|
||||
});
|
||||
|
||||
tap.test('should be able to update an instance of car', async () => {});
|
||||
|
||||
tap.test('should be able to delete an instance of car', async () => {});
|
||||
|
||||
// =======================================
|
||||
// close the database connection
|
||||
// =======================================
|
||||
tap.test('should close the database connection', async tools => {
|
||||
await testDb.close();
|
||||
await mongod.stop();
|
||||
});
|
||||
|
||||
tap.start({ throwOnError: true });
|
||||
|
@ -36,11 +36,11 @@ export class SmartdataCollection<T> {
|
||||
/**
|
||||
* the collection that is used
|
||||
*/
|
||||
mongoDbCollection: plugins.mongodb.Collection;
|
||||
objectValidation: IDocValidationFunc<T> = null;
|
||||
collectionName: string;
|
||||
smartdataDb: SmartdataDb;
|
||||
uniqueIndexes: string[] = [];
|
||||
public mongoDbCollection: plugins.mongodb.Collection;
|
||||
public objectValidation: IDocValidationFunc<T> = null;
|
||||
public collectionName: string;
|
||||
public smartdataDb: SmartdataDb;
|
||||
public uniqueIndexes: string[] = [];
|
||||
|
||||
constructor(collectedClassArg: T & SmartDataDbDoc<T>, smartDataDbArg: SmartdataDb) {
|
||||
// tell the collection where it belongs
|
||||
@ -54,7 +54,7 @@ export class SmartdataCollection<T> {
|
||||
/**
|
||||
* makes sure a collection exists within MongoDb that maps to the SmartdataCollection
|
||||
*/
|
||||
async init() {
|
||||
public async init() {
|
||||
if (!this.mongoDbCollection) {
|
||||
// connect this instance to a MongoDB collection
|
||||
const availableMongoDbCollections = await this.smartdataDb.mongoDb.collections();
|
||||
@ -65,15 +65,15 @@ export class SmartdataCollection<T> {
|
||||
await this.smartdataDb.mongoDb.createCollection(this.collectionName);
|
||||
}
|
||||
this.mongoDbCollection = await this.smartdataDb.mongoDb.collection(this.collectionName);
|
||||
console.log(`Successfully initiated Collection ${this.collectionName}`);
|
||||
// console.log(`Successfully initiated Collection ${this.collectionName}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* mark unique index
|
||||
*/
|
||||
markUniqueIndexes(keyArrayArg: string[] = []) {
|
||||
for (let key of keyArrayArg) {
|
||||
public markUniqueIndexes(keyArrayArg: string[] = []) {
|
||||
for (const key of keyArrayArg) {
|
||||
if (!this.uniqueIndexes.includes(key)) {
|
||||
this.mongoDbCollection.createIndex(key, {
|
||||
unique: true
|
||||
@ -87,14 +87,14 @@ export class SmartdataCollection<T> {
|
||||
/**
|
||||
* adds a validation function that all newly inserted and updated objects have to pass
|
||||
*/
|
||||
addDocValidation(funcArg: IDocValidationFunc<T>) {
|
||||
public addDocValidation(funcArg: IDocValidationFunc<T>) {
|
||||
this.objectValidation = funcArg;
|
||||
}
|
||||
|
||||
/**
|
||||
* finds an object in the DbCollection
|
||||
*/
|
||||
async find(filterObject: any): Promise<any> {
|
||||
public async find(filterObject: any): Promise<any> {
|
||||
await this.init();
|
||||
const result = await this.mongoDbCollection.find(filterObject).toArray();
|
||||
return result;
|
||||
@ -103,7 +103,7 @@ export class SmartdataCollection<T> {
|
||||
/**
|
||||
* create an object in the database
|
||||
*/
|
||||
async insert(dbDocArg: T & SmartDataDbDoc<T>): Promise<any> {
|
||||
public async insert(dbDocArg: T & SmartDataDbDoc<T>): Promise<any> {
|
||||
await this.init();
|
||||
await this.checkDoc(dbDocArg);
|
||||
this.markUniqueIndexes(dbDocArg.uniqueIndexes);
|
||||
@ -120,7 +120,17 @@ export class SmartdataCollection<T> {
|
||||
await this.checkDoc(dbDocArg);
|
||||
const identifiableObject = await dbDocArg.createIdentifiableObject();
|
||||
const saveableObject = await dbDocArg.createSavableObject();
|
||||
this.mongoDbCollection.updateOne(identifiableObject, saveableObject);
|
||||
console.log(identifiableObject);
|
||||
console.log(saveableObject);
|
||||
const updateableObject: any = {};
|
||||
for (const key of Object.keys(saveableObject)) {
|
||||
if (identifiableObject[key]) {
|
||||
continue;
|
||||
}
|
||||
updateableObject[key] = saveableObject[key];
|
||||
}
|
||||
console.log(updateableObject);
|
||||
this.mongoDbCollection.updateOne(identifiableObject, { $set: updateableObject }, {upsert: true});
|
||||
}
|
||||
|
||||
public async delete(dbDocArg: T & SmartDataDbDoc<T>): Promise<any> {
|
||||
|
@ -44,7 +44,7 @@ export class SmartdataDb {
|
||||
/**
|
||||
* connects to the database that was specified during instance creation
|
||||
*/
|
||||
async init(): Promise<any> {
|
||||
public async init(): Promise<any> {
|
||||
let finalConnectionUrl = this.smartdataOptions.mongoDbUrl;
|
||||
if (this.smartdataOptions.mongoDbPass) {
|
||||
finalConnectionUrl = mongoHelpers.addPassword(
|
||||
@ -52,7 +52,7 @@ export class SmartdataDb {
|
||||
this.smartdataOptions.mongoDbPass
|
||||
);
|
||||
}
|
||||
console.log(finalConnectionUrl);
|
||||
console.log(`connection Url: ${finalConnectionUrl}`);
|
||||
this.mongoDbClient = await plugins.mongodb.MongoClient.connect(finalConnectionUrl, {
|
||||
useNewUrlParser: true
|
||||
});
|
||||
@ -64,7 +64,7 @@ export class SmartdataDb {
|
||||
/**
|
||||
* closes the connection to the databse
|
||||
*/
|
||||
async close(): Promise<any> {
|
||||
public async close(): Promise<any> {
|
||||
await this.mongoDbClient.close();
|
||||
this.status = 'disconnected';
|
||||
plugins.smartlog.defaultLogger.log(
|
||||
@ -75,7 +75,7 @@ export class SmartdataDb {
|
||||
|
||||
// handle table to class distribution
|
||||
|
||||
addTable(SmartdataCollectionArg: SmartdataCollection<any>) {
|
||||
public addTable(SmartdataCollectionArg: SmartdataCollection<any>) {
|
||||
this.smartdataCollectionMap.add(SmartdataCollectionArg);
|
||||
}
|
||||
|
||||
@ -84,8 +84,8 @@ export class SmartdataDb {
|
||||
* @param nameArg
|
||||
* @returns DbTable
|
||||
*/
|
||||
async getSmartdataCollectionByName<T>(nameArg: string): Promise<SmartdataCollection<T>> {
|
||||
let resultCollection = this.smartdataCollectionMap.find(dbTableArg => {
|
||||
public async getSmartdataCollectionByName<T>(nameArg: string): Promise<SmartdataCollection<T>> {
|
||||
const resultCollection = this.smartdataCollectionMap.find(dbTableArg => {
|
||||
return dbTableArg.collectionName === nameArg;
|
||||
});
|
||||
return resultCollection;
|
||||
|
@ -45,32 +45,32 @@ export class SmartDataDbDoc<T> {
|
||||
/**
|
||||
* the collection object an Doc belongs to
|
||||
*/
|
||||
collection: SmartdataCollection<T>;
|
||||
public collection: SmartdataCollection<T>;
|
||||
|
||||
/**
|
||||
* how the Doc in memory was created, may prove useful later.
|
||||
*/
|
||||
creationStatus: TDocCreation = 'new';
|
||||
public creationStatus: TDocCreation = 'new';
|
||||
|
||||
/**
|
||||
* unique indexes
|
||||
*/
|
||||
uniqueIndexes: string[];
|
||||
public uniqueIndexes: string[];
|
||||
|
||||
/**
|
||||
* an array of saveable properties of a doc
|
||||
*/
|
||||
saveableProperties: string[];
|
||||
public saveableProperties: string[];
|
||||
|
||||
/**
|
||||
* name
|
||||
*/
|
||||
name: string;
|
||||
public name: string;
|
||||
|
||||
/**
|
||||
* primary id in the database
|
||||
*/
|
||||
dbDocUniqueId: string;
|
||||
public dbDocUniqueId: string;
|
||||
|
||||
/**
|
||||
* class constructor
|
||||
@ -89,8 +89,8 @@ export class SmartDataDbDoc<T> {
|
||||
}
|
||||
}
|
||||
|
||||
static async getInstances<T>(filterArg): Promise<T[]> {
|
||||
let self: any = this; // fool typesystem
|
||||
public static async getInstances<T>(filterArg): Promise<T[]> {
|
||||
const self: any = this; // fool typesystem
|
||||
let referenceMongoDBCollection: SmartdataCollection<T>;
|
||||
|
||||
if (self.smartdataCollection) {
|
||||
@ -100,9 +100,10 @@ export class SmartDataDbDoc<T> {
|
||||
}
|
||||
const foundDocs = await referenceMongoDBCollection.find(filterArg);
|
||||
const returnArray = [];
|
||||
for (let item of foundDocs) {
|
||||
let newInstance = new this();
|
||||
for (let key in item) {
|
||||
for (const item of foundDocs) {
|
||||
const newInstance = new this();
|
||||
newInstance.creationStatus = 'db';
|
||||
for (const key in item) {
|
||||
if (key !== 'id') {
|
||||
newInstance[key] = item[key];
|
||||
}
|
||||
@ -113,7 +114,7 @@ export class SmartDataDbDoc<T> {
|
||||
}
|
||||
|
||||
static async getInstance<T>(filterArg): Promise<T> {
|
||||
let result = await this.getInstances<T>(filterArg);
|
||||
const result = await this.getInstances<T>(filterArg);
|
||||
if (result && result.length > 0) {
|
||||
return result[0];
|
||||
}
|
||||
@ -123,15 +124,15 @@ export class SmartDataDbDoc<T> {
|
||||
* saves this instance but not any connected items
|
||||
* may lead to data inconsistencies, but is faster
|
||||
*/
|
||||
async save() {
|
||||
public async save() {
|
||||
// tslint:disable-next-line: no-this-assignment
|
||||
let self: any = this;
|
||||
const self: any = this;
|
||||
switch (this.creationStatus) {
|
||||
case 'db':
|
||||
await this.collection.update(self);
|
||||
break;
|
||||
case 'new':
|
||||
let writeResult = await this.collection.insert(self);
|
||||
const writeResult = await this.collection.insert(self);
|
||||
this.creationStatus = 'db';
|
||||
break;
|
||||
default:
|
||||
@ -142,20 +143,20 @@ export class SmartDataDbDoc<T> {
|
||||
/**
|
||||
* deletes a document from the database
|
||||
*/
|
||||
async delete() {}
|
||||
public async delete() {}
|
||||
|
||||
/**
|
||||
* also store any referenced objects to DB
|
||||
* better for data consistency
|
||||
*/
|
||||
saveDeep(savedMapArg: Objectmap<SmartDataDbDoc<any>> = null) {
|
||||
public saveDeep(savedMapArg: Objectmap<SmartDataDbDoc<any>> = null) {
|
||||
if (!savedMapArg) {
|
||||
savedMapArg = new Objectmap<SmartDataDbDoc<any>>();
|
||||
}
|
||||
savedMapArg.add(this);
|
||||
this.save();
|
||||
for (let propertyKey in this) {
|
||||
let property: any = this[propertyKey];
|
||||
for (const propertyKey of Object.keys(this)) {
|
||||
const property: any = this[propertyKey];
|
||||
if (property instanceof SmartDataDbDoc && !savedMapArg.checkForObject(property)) {
|
||||
property.saveDeep(savedMapArg);
|
||||
}
|
||||
|
@ -4,5 +4,6 @@ import * as lodash from 'lodash';
|
||||
import * as mongodb from 'mongodb';
|
||||
import * as smartq from '@pushrocks/smartpromise';
|
||||
import * as smartstring from '@pushrocks/smartstring';
|
||||
import * as smartunique from '@pushrocks/smartunique';
|
||||
|
||||
export { assert, smartlog, lodash, smartq, mongodb, smartstring };
|
||||
export { assert, smartlog, lodash, smartq, mongodb, smartstring, smartunique };
|
||||
|
Loading…
Reference in New Issue
Block a user