update ci
This commit is contained in:
@ -3,25 +3,18 @@ import { Objectmap } from 'lik'
|
||||
|
||||
import { DbCollection } from './smartdata.classes.dbcollection'
|
||||
|
||||
/**
|
||||
* interface - indicates the database type
|
||||
*/
|
||||
export type TDbType = 'mongodb' | 'nedb'
|
||||
|
||||
/**
|
||||
* interface - indicates the connection status of the db
|
||||
*/
|
||||
export type TConnectionStatus = 'disconnected' | 'connected' | 'failed'
|
||||
|
||||
export class Db {
|
||||
dbType: TDbType
|
||||
dbUrl: string
|
||||
db: plugins.mongodb.Db
|
||||
status: TConnectionStatus
|
||||
collections = new Objectmap<DbCollection<any>>()
|
||||
|
||||
constructor(dbUrlArg: string, dbTypeArg: TDbType = 'mongodb') {
|
||||
this.dbType = dbTypeArg
|
||||
constructor (dbUrlArg: string) {
|
||||
this.dbUrl = dbUrlArg
|
||||
}
|
||||
|
||||
@ -30,30 +23,24 @@ export class Db {
|
||||
/**
|
||||
* connects to the database that was specified during instance creation
|
||||
*/
|
||||
connect(): plugins.q.Promise<any> {
|
||||
let done = plugins.q.defer()
|
||||
if (this.dbType === 'mongodb') {
|
||||
plugins.mongodb.MongoClient.connect(this.dbUrl, (err, db) => {
|
||||
if (err) { console.log(err) }
|
||||
plugins.assert.equal(null, err)
|
||||
this.db = db
|
||||
plugins.beautylog.success(`connected to database at ${this.dbUrl}`)
|
||||
done.resolve(this.db)
|
||||
})
|
||||
} else if (this.dbType === 'nedb') {
|
||||
this.db = null
|
||||
}
|
||||
connect (): Promise<any> {
|
||||
let done = plugins.smartq.defer()
|
||||
plugins.mongodb.MongoClient.connect(this.dbUrl, (err, db) => {
|
||||
if (err) { console.log(err) }
|
||||
plugins.assert.equal(null, err)
|
||||
this.db = db
|
||||
plugins.beautylog.success(`connected to database at ${this.dbUrl}`)
|
||||
done.resolve(this.db)
|
||||
})
|
||||
return done.promise
|
||||
}
|
||||
|
||||
/**
|
||||
* closes the connection to the databse
|
||||
*/
|
||||
close(): plugins.q.Promise<any> {
|
||||
let done = plugins.q.defer()
|
||||
if (this.dbType === 'mongodb') {
|
||||
this.db.close()
|
||||
}
|
||||
close (): Promise<any> {
|
||||
let done = plugins.smartq.defer()
|
||||
this.db.close()
|
||||
plugins.beautylog.ok(`disconnected to database at ${this.dbUrl}`)
|
||||
done.resolve()
|
||||
return done.promise
|
||||
@ -64,8 +51,8 @@ export class Db {
|
||||
/**
|
||||
* gets a collection by name: string
|
||||
*/
|
||||
getCollectionByName<T>(nameArg: string): plugins.q.Promise<DbCollection<T>> {
|
||||
let done = plugins.q.defer<DbCollection<any>>()
|
||||
getCollectionByName<T>(nameArg: string): Promise<DbCollection<T>> {
|
||||
let done = plugins.smartq.defer<DbCollection<any>>()
|
||||
let resultCollection = this.collections.find((dbCollectionArg) => {
|
||||
return dbCollectionArg.name === nameArg
|
||||
})
|
||||
@ -73,9 +60,9 @@ export class Db {
|
||||
done.resolve(resultCollection)
|
||||
}
|
||||
return done.promise
|
||||
};
|
||||
}
|
||||
|
||||
addCollection(dbCollectionArg: DbCollection<any>) {
|
||||
addCollection (dbCollectionArg: DbCollection<any>) {
|
||||
this.collections.add(dbCollectionArg)
|
||||
}
|
||||
|
||||
|
@ -1,150 +1,117 @@
|
||||
import * as plugins from './smartdata.plugins'
|
||||
import { Db } from './smartdata.classes.db'
|
||||
import { DbDoc } from './smartdata.classes.dbDoc'
|
||||
|
||||
export interface IFindOptions {
|
||||
limit?: number
|
||||
limit?: number
|
||||
}
|
||||
|
||||
export interface IDocValidation<T> {
|
||||
(doc: T): boolean
|
||||
(doc: T): boolean
|
||||
}
|
||||
|
||||
export function Collection(db: Db) {
|
||||
return function (constructor) {
|
||||
constructor['dbCollection'] = new DbCollection(constructor.name, db)
|
||||
}
|
||||
export function Collection (db: Db) {
|
||||
return function (constructor) {
|
||||
constructor[ 'dbCollection' ] = new DbCollection(constructor.name, db)
|
||||
}
|
||||
}
|
||||
|
||||
export class DbCollection<T> {
|
||||
/**
|
||||
* the collection that is used, defaults to mongodb collection,
|
||||
* can be nedb datastore (sub api of mongodb)
|
||||
*/
|
||||
collection: plugins.mongodb.Collection
|
||||
name: string
|
||||
db: Db
|
||||
objectValidation: IDocValidation<T> = null
|
||||
/**
|
||||
* the collection that is used, defaults to mongodb collection,
|
||||
* can be nedb datastore (sub api of mongodb)
|
||||
*/
|
||||
collection: plugins.mongodb.Collection
|
||||
collectedClass: T & DbDoc<T>
|
||||
objectValidation: IDocValidation<T> = null
|
||||
name: string
|
||||
db: Db
|
||||
|
||||
constructor (collectedClassArg: T & DbDoc<T>, dbArg: Db) {
|
||||
// tell the collection where it belongs
|
||||
this.collectedClass = collectedClassArg
|
||||
this.name = collectedClassArg.name
|
||||
this.db = dbArg
|
||||
|
||||
constructor(nameArg: string, dbArg: Db) {
|
||||
// tell the collection where it belongs
|
||||
this.name = nameArg
|
||||
this.db = dbArg
|
||||
// make sure it actually exists
|
||||
this.collection = dbArg.db.collection(this.name)
|
||||
|
||||
// make sure it actually exists
|
||||
if (this.db.dbType === 'mongodb') {
|
||||
this.collection = dbArg.db.collection(nameArg)
|
||||
} else {
|
||||
this.collection = new plugins.nedb()
|
||||
}
|
||||
// tell the db class about it (important since Db uses different systems under the hood)
|
||||
this.db.addCollection(this)
|
||||
}
|
||||
|
||||
// tell the db class about it (important since Db uses different systems under the hood)
|
||||
this.db.addCollection(this)
|
||||
/**
|
||||
* adds a validation function that all newly inserted and updated objects have to pass
|
||||
*/
|
||||
addDocValidation (funcArg: IDocValidation<T>) {
|
||||
this.objectValidation = funcArg
|
||||
}
|
||||
|
||||
/**
|
||||
* finds an object in the DbCollection
|
||||
*/
|
||||
find (docMatchArg: T | any, optionsArg?: IFindOptions): Promise<T[]> {
|
||||
let done = plugins.smartq.defer<T[]>()
|
||||
let findCursor = this.collection.find(docMatchArg)
|
||||
if (optionsArg) {
|
||||
if (optionsArg.limit) { findCursor = findCursor.limit(1) }
|
||||
}
|
||||
findCursor.toArray((err, docs) => {
|
||||
if (err) {
|
||||
done.reject(err)
|
||||
throw err
|
||||
}
|
||||
done.resolve(docs)
|
||||
})
|
||||
return done.promise
|
||||
}
|
||||
|
||||
/**
|
||||
* adds a validation function that all newly inserted and updated objects have to pass
|
||||
*/
|
||||
addDocValidation(funcArg: IDocValidation<T>) {
|
||||
this.objectValidation = funcArg
|
||||
}
|
||||
/**
|
||||
* inserts object into the DbCollection
|
||||
*/
|
||||
insertOne (docArg: T): Promise<void> {
|
||||
let done = plugins.smartq.defer<void>()
|
||||
this.checkDoc(docArg).then(
|
||||
() => {
|
||||
this.collection.insertOne(docArg)
|
||||
.then(() => { done.resolve() })
|
||||
},
|
||||
() => {
|
||||
done.reject(new Error('one the docs did not pass validation'))
|
||||
})
|
||||
return done.promise
|
||||
}
|
||||
|
||||
/**
|
||||
* finds an object in the DbCollection
|
||||
*/
|
||||
find(docMatchArg: T | any, optionsArg?: IFindOptions): plugins.q.Promise<T[]> {
|
||||
let done = plugins.q.defer<T[]>()
|
||||
if (this.db.dbType === 'mongodb') {
|
||||
let findCursor = this.collection.find(docMatchArg)
|
||||
if (optionsArg) {
|
||||
if (optionsArg.limit) { findCursor = findCursor.limit(1) }
|
||||
}
|
||||
findCursor.toArray((err, docs) => {
|
||||
if (err) {
|
||||
done.reject(err)
|
||||
throw err
|
||||
}
|
||||
done.resolve(docs)
|
||||
})
|
||||
} else if (this.db.dbType === 'nedb') {
|
||||
this.collection.find(docMatchArg, (err, docs) => {
|
||||
if (err) {
|
||||
done.reject(err)
|
||||
throw err
|
||||
}
|
||||
done.resolve(docs)
|
||||
})
|
||||
}
|
||||
return done.promise
|
||||
/**
|
||||
* inserts many objects at once into the DbCollection
|
||||
*/
|
||||
insertMany (docArrayArg: T[]): Promise<void> {
|
||||
let done = plugins.smartq.defer<void>()
|
||||
let checkDocPromiseArray: Promise<void>[] = []
|
||||
for (let docArg of docArrayArg) {
|
||||
checkDocPromiseArray.push(this.checkDoc(docArg))
|
||||
}
|
||||
Promise.all(checkDocPromiseArray).then(() => {
|
||||
this.collection.insertMany(docArrayArg)
|
||||
.then(() => { done.resolve() })
|
||||
})
|
||||
return done.promise
|
||||
}
|
||||
|
||||
/**
|
||||
* inserts object into the DbCollection
|
||||
*/
|
||||
insertOne(docArg: T): plugins.q.Promise<void> {
|
||||
let done = plugins.q.defer<void>()
|
||||
this.checkDoc(docArg).then(
|
||||
() => {
|
||||
if (this.db.dbType === 'mongodb') {
|
||||
this.collection.insertOne(docArg)
|
||||
.then(() => { done.resolve() })
|
||||
} else if (this.db.dbType === 'nedb') {
|
||||
this.collection.insert(docArg, (err, newDoc) => {
|
||||
if (err) {
|
||||
done.reject(err)
|
||||
throw err
|
||||
}
|
||||
done.resolve()
|
||||
})
|
||||
}
|
||||
},
|
||||
() => {
|
||||
done.reject(new Error('one the docs did not pass validation'))
|
||||
})
|
||||
return done.promise
|
||||
/**
|
||||
* checks a Doc for constraints
|
||||
*/
|
||||
private checkDoc (docArg: T): Promise<void> {
|
||||
let done = plugins.smartq.defer<void>()
|
||||
let validationResult = true
|
||||
if (this.objectValidation) {
|
||||
validationResult = this.objectValidation(docArg)
|
||||
}
|
||||
|
||||
/**
|
||||
* inserts many objects at once into the DbCollection
|
||||
*/
|
||||
insertMany(docArrayArg: T[]): plugins.q.Promise<void> {
|
||||
let done = plugins.q.defer<void>()
|
||||
let checkDocPromiseArray: plugins.q.Promise<void>[] = []
|
||||
for (let docArg of docArrayArg) {
|
||||
checkDocPromiseArray.push(this.checkDoc(docArg))
|
||||
}
|
||||
plugins.q.all(checkDocPromiseArray).then(() => {
|
||||
if (this.db.dbType === 'mongodb') {
|
||||
this.collection.insertMany(docArrayArg)
|
||||
.then(() => { done.resolve() })
|
||||
} else if (this.db.dbType === 'nedb') {
|
||||
let paramArray = plugins.lodash.concat<any>(docArrayArg, (err, newDoc) => {
|
||||
if (err) {
|
||||
done.reject(err)
|
||||
throw err
|
||||
}
|
||||
done.resolve()
|
||||
})
|
||||
this.collection.insert.apply(null, paramArray)
|
||||
}
|
||||
})
|
||||
return done.promise
|
||||
}
|
||||
|
||||
/**
|
||||
* checks a Doc for constraints
|
||||
*/
|
||||
private checkDoc(docArg: T): plugins.q.Promise<void> {
|
||||
let done = plugins.q.defer<void>()
|
||||
let validationResult = true
|
||||
if (this.objectValidation) {
|
||||
validationResult = this.objectValidation(docArg)
|
||||
}
|
||||
if (validationResult) {
|
||||
done.resolve()
|
||||
} else {
|
||||
done.reject('validation of object did not pass')
|
||||
}
|
||||
return done.promise
|
||||
if (validationResult) {
|
||||
done.resolve()
|
||||
} else {
|
||||
done.reject('validation of object did not pass')
|
||||
}
|
||||
return done.promise
|
||||
}
|
||||
}
|
||||
|
@ -35,11 +35,17 @@ export class DbDoc<T> {
|
||||
*/
|
||||
saveableProperties: string[]
|
||||
|
||||
/**
|
||||
* name
|
||||
*/
|
||||
name: string
|
||||
|
||||
/**
|
||||
* class constructor
|
||||
*/
|
||||
constructor() {
|
||||
constructor(nameArg: string) {
|
||||
this.collection = this.constructor[ 'dbCollection' ]
|
||||
this.name = nameArg
|
||||
}
|
||||
|
||||
/**
|
||||
@ -47,7 +53,7 @@ export class DbDoc<T> {
|
||||
* may lead to data inconsistencies, but is faster
|
||||
*/
|
||||
save() {
|
||||
let saveableObject: any = {} // isn not exposed to outside, so any is ok here
|
||||
let saveableObject: any = {} // is not exposed to outside, so any is ok here
|
||||
for (let propertyNameString of this.saveableProperties) {
|
||||
saveableObject[ propertyNameString ] = this[ propertyNameString ]
|
||||
}
|
||||
|
@ -3,14 +3,12 @@ import * as assert from 'assert'
|
||||
import * as beautylog from 'beautylog'
|
||||
import * as lodash from 'lodash'
|
||||
import * as mongodb from 'mongodb'
|
||||
import * as q from 'q'
|
||||
let nedb = require('nedb')
|
||||
import * as smartq from 'smartq'
|
||||
|
||||
export {
|
||||
assert,
|
||||
beautylog,
|
||||
lodash,
|
||||
mongodb,
|
||||
q,
|
||||
nedb
|
||||
smartq
|
||||
}
|
||||
|
Reference in New Issue
Block a user