UNPKG

jsharmony-db-sqlite

Version:
224 lines (197 loc) 8.09 kB
/* Copyright 2017 apHarmony This file is part of jsHarmony. jsHarmony is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. jsHarmony is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this package. If not, see <http://www.gnu.org/licenses/>. */ var DB = require('jsharmony-db'); var dbtypes = DB.types; var _ = require('lodash'); var async = require('async'); function DBmeta(db){ this.db = db; } DBmeta.prototype.getTables = function(table, options, callback){ var _this = this; options = _.extend({ ignore_jsharmony_schema: true }, options); var tables = []; var messages = []; var sql_param_types = []; var sql_params = {}; var sql = "select '' schema_name, name table_name, name description, (case when type='table' then 'table' else 'view' end) table_type \ from sqlite_master \ WHERE (type='table' or type='view') \ "; if(table){ sql += "and name=@table_name"; sql_param_types = [dbtypes.VarChar(dbtypes.MAX)]; sql_params = {'table_name':(table.schema?(table.schema+'_'):'')+table.name}; } sql += ' order by name;'; this.db.Recordset('',sql,sql_param_types,sql_params,function(err,rslt){ if(err){ return callback(err); } for(var i=0;i<rslt.length;i++){ var dbtable = rslt[i]; if(!table){ if(options.ignore_jsharmony_schema && (dbtable.table_name.substr(0,10)=='jsharmony_')) continue; if(dbtable.table_name=='sqlite_sequence') continue; } var table_selector = dbtable.table_name; if(dbtable.schema_name && (dbtable.schema_name != _this.db.getDefaultSchema())) table_selector = dbtable.schema_name + '.' + dbtable.table_name; tables.push({ schema:dbtable.schema_name, name:dbtable.table_name, description:dbtable.description, table_type:dbtable.table_type, model_name:((dbtable.schema_name||'')==(_this.db.getDefaultSchema()||'')?dbtable.table_name:dbtable.schema_name+'_'+dbtable.table_name), table_selector: table_selector, }); } return callback(null, messages, tables); }); }; DBmeta.prototype.getAllTableFields = function(callback){ var _this = this; var rsltfields = []; var rsltmessages = []; _this.getTables(undefined, { ignore_jsharmony_schema: false }, function(err, messages, tables){ if(err) return callback(err); async.eachSeries(tables, function(table, table_cb){ _this.getTableFields({ name: table.name }, function(err, messages, fields){ if(err) return table_cb(err); if(fields) for(let i=0;i<fields.length;i++) rsltfields.push(fields[i]); if(messages) for(let i=0;i<messages.length;i++) rsltmessages.push(messages[i]); return table_cb(); }); },function(err){ if(err) return callback(err); return callback(null, rsltmessages, rsltfields); }); }); }; DBmeta.prototype.getTableFields = function(tabledef, callback){ var _this = this; if(!tabledef) return _this.getAllTableFields(callback); var fields = []; var messages = []; var table_name = (tabledef.schema?(tabledef.schema+'_'):'')+tabledef.name; var dbdriver = _this.db.dbconfig._driver; var autoincrement = 0; async.waterfall([ function(table_cb){ _this.db.Recordset('',"select count(*) cnt from sqlite_sequence where name='" + dbdriver.escape(table_name) + "';",[],{},function(err,rslt){ if(err){ //Do not show an error if the sqlite_sequence table is missing return table_cb(); } autoincrement = rslt[0].cnt; return table_cb(); }); }, function(table_cb){ _this.db.Recordset('',"PRAGMA table_info('" + dbdriver.escape(table_name) + "');",[],{},function(err,rslt){ if(err){ return table_cb(err); } var pragmacols = rslt; //Convert to jsHarmony Data Types / Fields for(var i=0;i<pragmacols.length;i++){ var pragmacol = pragmacols[i]; var col = { schema_name: '', table_name: table_name, column_name: pragmacol.name, type_name: (pragmacol.type||'text').toString().toLowerCase(), //integer, real, text, blob max_length: -1, precision: -1, scale: -1, required: (!pragmacol.dflt_value && pragmacol.notnull), readonly: pragmacol.pk && autoincrement, description: pragmacol.name, primary_key: pragmacol.pk }; var field = { name: col.column_name }; if(col.type_name=="text"){ field.type = "varchar"; } else if(col.type_name=="integer"){ field.type = "int"; } else if(col.type_name=="real"){ field.type = "real"; if(field.precision && (field.precision.toString() != '24')) field.precision = 53; } else if(col.type_name=="blob"){ field.type = "blob"; field.length = col.max_length; } else if(col.type_name=="number"){ field.type = "real"; } else{ messages.push('WARNING - Skipping Column: '+(tabledef.schema?tabledef.schema+'.':'')+tabledef.name+'.'+col.column_name+': Data type '+col.type_name + ' not supported.'); continue; } field.coldef = col; fields.push(field); } return table_cb(); }); }, ], function(err){ if(err){ return callback(err); } return callback(null, messages, fields); }); }; DBmeta.prototype.getAllForeignKeys = function(callback){ var _this = this; var rsltfields = []; var rsltmessages = []; _this.getTables(undefined, { ignore_jsharmony_schema: false }, function(err, messages, tables){ if(err) return callback(err); async.eachSeries(tables, function(table, table_cb){ _this.getForeignKeys({ name: table.name }, function(err, messages, fields){ if(err) return table_cb(err); if(fields) for(let i=0;i<fields.length;i++) rsltfields.push(fields[i]); if(messages) for(let i=0;i<messages.length;i++) rsltmessages.push(messages[i]); return table_cb(); }); },function(err){ if(err) return callback(err); return callback(null, rsltmessages, rsltfields); }); }); }; DBmeta.prototype.getForeignKeys = function(tabledef, callback){ var _this = this; if(!tabledef) return _this.getAllForeignKeys(callback); var fields = []; var messages = []; var table_schema = tabledef.schema || _this.db.getDefaultSchema(); var table_name = (table_schema?(table_schema+'_'):'')+tabledef.name; var dbdriver = _this.db.dbconfig._driver; _this.db.MultiRecordset('',"PRAGMA foreign_key_list('" + dbdriver.escape(table_name) + "');", [], {}, function(err,rslt){ if(err){ return callback(err); } if(!rslt || !rslt.length) return callback(null, messages, fields); var pragmacols = rslt[0]; //Convert to jsHarmony Data Types / Fields for(var i=0;i<pragmacols.length;i++){ var pragmacol = pragmacols[i]; var field = { id: pragmacol.id, from: { schema_name: '', table_name: table_name, column_name: pragmacol.from }, to: { schema_name: '', table_name: pragmacol.table, column_name: pragmacol.to } }; fields.push(field); } return callback(null, messages, fields); }); }; exports = module.exports = DBmeta;