import * as plugins from "./smartdata.plugins"; import { Db } from "./smartdata.classes.db"; import { DbDoc } from "./smartdata.classes.dbdoc"; // RethinkDb Interfaces import { WriteResult, Cursor } from "rethinkdb"; export interface IFindOptions { limit?: number; } /** * */ export interface IDocValidationFunc { (doc: T): boolean; } /** * This is a decorator that will tell the decorated class what dbTable to use * @param db */ export function Table(db: Db) { return function(constructor) { constructor["dbTable"] = new DbTable(constructor, db); }; } export class DbTable { /** * the collection that is used */ table: plugins.rethinkDb.Table; objectValidation: IDocValidationFunc = null; tableName: string; db: Db; constructor(collectedClassArg: T & DbDoc, dbArg: Db) { // tell the collection where it belongs this.tableName = collectedClassArg.name; this.db = dbArg; // tell the db class about it (important since Db uses different systems under the hood) this.db.addTable(this); } async init() { if (!this.table) { // connect this instance to a RethinkDB table const availableTables = await plugins.rethinkDb .db(this.db.dbName) .tableList() .run(this.db.dbConnection); if (availableTables.indexOf(this.tableName)) { await plugins.rethinkDb .db(this.db.dbName) .tableCreate(this.tableName) .run(this.db.dbConnection); } } this.table = plugins.rethinkDb.table(this.tableName); } /** * adds a validation function that all newly inserted and updated objects have to pass */ addDocValidation(funcArg: IDocValidationFunc) { this.objectValidation = funcArg; } /** * finds an object in the DbCollection */ async find(filterObject: any): Promise { await this.init(); let cursor = await plugins.rethinkDb .table(this.tableName) .filter(filterObject) .run(this.db.dbConnection); return await cursor.toArray(); } /** * create an object in the database */ async insert(dbDocArg: T & DbDoc): Promise { await this.init(); await this.checkDoc(dbDocArg); return await plugins.rethinkDb .table(this.tableName) .insert(dbDocArg.createSavableObject()) .run(this.db.dbConnection); } /** * inserts object into the DbCollection */ async update(dbDocArg: T & DbDoc): Promise { await this.init(); await this.checkDoc(dbDocArg); console.log(this.tableName, dbDocArg.createSavableObject()); return await plugins.rethinkDb .table(this.tableName) .update(dbDocArg.createSavableObject()) .run(this.db.dbConnection); } /** * checks a Doc for constraints * if this.objectValidation is not set it passes. */ private checkDoc(docArg: T): Promise { let done = plugins.smartq.defer(); 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; } extractKey(writeResult: WriteResult) {} }