var tcrudSetup = require('./../tcrud-setup'); var debug = require('debug')('ff:tcrud:backend:database'); module.exports = { loadModule: function(key,dbModule) { tcrudSetup.pluginLoad(new DatabasePlugin(key,dbModule)); }, loadPostgres: function(key,dbUri,pgDB,pgDBNamed) { tcrudSetup.pluginLoad(new DatabasePlugin(key,new PostgresModule(dbUri,pgDB,pgDBNamed))); }, loadMysql2: function(key,pool) { tcrudSetup.pluginLoad(new DatabasePlugin(key,new Mysql2Module(pool))); }, loadMssql: function(key,driver,conn) { tcrudSetup.pluginLoad(new DatabasePlugin(key,new MssqlModule(driver,conn))); } } //------- PostgresModule Object function PostgresModule(dbUri,pgDB,pgDBNamed) { this.dbUri = dbUri; this.pgDB = pgDB; this.pgDBNamed = pgDBNamed; } PostgresModule.prototype.query = function(sqlQuery,params, cb) { var self = this; self.pgDB.connect(self.dbUri, function(err, client, done) { self.pgDBNamed.patch(client); client.query(sqlQuery, params, function(err, result) { done(); // release client from pool cb(err,result); }); }); } function Mysql2Module(pool) { this.pool = pool; } Mysql2Module.prototype.query = function(sqlQuery,params, cb) { var self = this; self.pool.getConnection(function(err, connection) { connection.config.namedPlaceholders = true; connection.execute(sqlQuery,params, function(err, rows) { connection.release(); cb(err,rows); }); }); } function MssqlModule(driver,conn) { this.driver = driver; this.conn = conn; } MssqlModule.prototype.query = function(sqlQuery,params, cb) { var self = this; var request = new self.driver.Request(self.conn); request.query(sqlQuery,params,function(err, rows) { cb(err,rows); }); } //------- DatabasePlugin Object function DatabasePlugin(key,dbModule) { this.key = key; this.dbModule = dbModule; } DatabasePlugin.prototype.configPlugin = function (ctx) { ctx.key='db#'+this.key; ctx.description='Database api adapter for '+this.key; }; DatabasePlugin.prototype.createBackend = function() { return new DatabaseBackend(this); } DatabasePlugin.prototype.query = function(sqlQuery,params, cb) { this.dbModule.query(sqlQuery,params,cb); } // -------- DatabaseBackend function findKeysView(tview) { return tview.tkeys; } function findKeysModel(tview) { return tview.tmeta.tmodel.tkeys; } function selectField(tview,crudType) { var result = []; tview[crudType].tfields.forEach(function (tfieldKey) { var tfield = tview.tmeta.tfields[tfieldKey]; result.push(tfield.tid); }); var resultSql = ''; for (var i = 0; i < result.length; i++) { var key = result[i]; resultSql += key; if (i < (result.length - 1)) { resultSql += ','; } } return resultSql; } function whereKeys(tview) { var resultSql = ''; for (var i = 0; i < tview.tmeta.tmodel.tkeys.length; i++) { var key = tview.tmeta.tmodel.tkeys[i]; //resultSql += key +' = $'+(i+1); resultSql += key +' = $'+key; if (i < (tview.tmeta.tmodel.tkeys.length - 1)) { resultSlug += ' AND '; } } return resultSql; } function updateValues(tview,data) { var resultSql = 'SET '; var dataKeys = Object.keys(data); for (var i = 0; i < dataKeys.length; i++) { var key = dataKeys[i]; var skip = false; for (var ii = 0; ii < tview.tmeta.tmodel.tkeys.length; ii++) { var keyPK = tview.tmeta.tmodel.tkeys[ii]; if (key === keyPK) { skip = true; break; } } if (skip === true) { continue; } resultSql += key +' = $'+key; if (i < (dataKeys.length - 1)) { resultSql += ','; } } return resultSql; } function DatabaseBackend(plugin) { this.plugin = plugin; } DatabaseBackend.prototype.getKey = function() { return this.plugin.key; } DatabaseBackend.prototype.findAll = function(tview,crudType) { var self = this; return function(data, dataParam, cb) { var querySql = 'SELECT '+selectField(tview,crudType)+' FROM '+tview.tmeta.tmodel.tid+''; debug('findAll %s',querySql); var query = self.plugin.query(querySql,[],function (err, result) { if (err) { debug(err); cb(err); } else { cb(err,result.rows); } }); }; } DatabaseBackend.prototype.createNew = function(tview,crudType) { var self = this; return function(data, dataParam, cb) { }; } DatabaseBackend.prototype.findOne = function(tview,crudType) { var self = this; return function(data, dataParam, cb) { var querySql = 'SELECT '+selectField(tview,crudType)+' FROM '+tview.tmeta.tmodel.tid+' WHERE '+whereKeys(tview)+''; debug('findOne param %s',JSON.stringify(dataParam)); debug('findOne sql %s',querySql); var query = self.plugin.query(querySql, dataParam, function (err, result) { if (err) { debug(err); cb(err); } else { cb(err,result.rows[0]); } }); }; } DatabaseBackend.prototype.updateOne = function(tview,crudType) { var self = this; return function(data, dataParam, cb) { var querySql = 'UPDATE '+tview.tmeta.tmodel.tid+' '+updateValues(tview,data)+' WHERE '+whereKeys(tview); debug('updateOne param %s',JSON.stringify(dataParam)); debug('updateOne data %s',JSON.stringify(data)); debug('updateOne sql %s',querySql); var query = self.plugin.query(querySql, data, function (err, result) { if (err) { debug(err); cb(err); } else { cb(err,result.rows[0]); } }); }; } DatabaseBackend.prototype.deleteOne = function(tview,crudType) { var self = this; return function(data, dataParam, cb) { var querySql = 'DELETE FROM '+tview.tmeta.tmodel.tid+' WHERE '+whereKeys(tview); debug('deleteOne param %s',JSON.stringify(dataParam)); debug('deleteOne sql %s',querySql); var query = self.plugin.query(querySql, dataParam, function (err, result) { if (err) { debug(err); cb(err); } else { cb(err,result.rows[0]); } }); }; } DatabaseBackend.prototype.findAllCount = function(tview,crudType) { var self = this; return function(data, dataParam, cb) { var querySql = 'SELECT count(*) FROM '+tview.tmeta.tmodel.tid; //+' WHERE '+whereKeys(tview); debug('findAllCount param %s',JSON.stringify(dataParam)); debug('findAllCount sql %s',querySql); var query = self.plugin.query(querySql, dataParam, function (err, result) { if (err) { debug(err); cb(err); } else { cb(err,result.rows[0]); } }); }; }