UNPKG

node-querybuilder

Version:

Modeled after Codeigniter's QueryBuilder. Build and execute queries in a safe and database-agnostic way.

146 lines (133 loc) 6.38 kB
/** * QueryBuilder for Node.js * (C) Kyle Farris 2014-2018 * kyle@chomponllc.com * * A generic Query Builder for any SQL or NOSQL database adapter. * * Current adapters: * - MySQL * * Requested Adapters: * - MSSQL * - postgres * - sqlite * - sqlite3 * - oracle * - mongo * * Dual licensed under the MIT and GPL licenses. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL KEVIN VAN ZONNEVELD BE LIABLE FOR ANY CLAIM, DAMAGES * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * **/ class QueryBuilder { constructor(settings, driver, type) { this.settings = (settings ? Object.assign({}, settings) : {}); this.driver = driver || 'mysql'; this.connection_type = type || 'single'; this.drivers = require('./drivers/drivers.json'); this.driver_version = 'default'; this.driver_info = null; this.pool = []; this.get_driver_info(); this.get_connection_type(); return this.get_adapter(); } // **************************************************************************** // Get information about the driver the user wants to use and modify QB object // ----- // @return Object Modified QueryBuilder object // **************************************************************************** get_driver_info() { // A driver must be specified if (typeof this.driver !== 'string') { throw new Error("No database driver specified!"); } this.driver = this.driver.toLowerCase(); // Verify that the driver is one we fundamentally support if (Object.keys(this.drivers).indexOf(this.driver) === -1) { throw new Error("Invalid driver specified!"); } // Determine version of driver to use if (this.settings.hasOwnProperty('version') && /^(string|number)$/i.test(typeof this.settings.version)) { this.driver_version = this.settings.version; delete this.settings.version; } // Retrieve info about driver if available, error if not if (this.drivers[this.driver].versions.hasOwnProperty(this.driver_version)) { if (this.drivers[this.driver].versions[this.driver_version].hasOwnProperty('version')) { this.driver_info = this.drivers[this.driver].versions[this.drivers[this.driver].versions[this.driver_version].version]; } else { this.driver_info = this.drivers[this.driver].versions[this.driver_version]; } } else { throw new Error(`${this.driver_version} is not a version of the ${this.driver} driver that this library specifically supports. Try being more generic.`); } // Fail if specified driver is inactive if (this.driver_info.active === false) { const err = (this.driver_version == 'default' ? 'The default version' : "Version " + this.driver_version) + ` of the ${this.driver} driver you are attempting to load is not currently available!`; throw new Error(err); } } // **************************************************************************** // Determine the type of connection (single, pool, cluster, etc...) // ----- // @return Object Modified QueryBuilder object // **************************************************************************** get_connection_type() { if (!Object.keys(this.drivers[this.driver].connection_types).includes(this.connection_type)) { throw new Error(`You have specified a invalid database connection method: ${this.connection_type}`); } if (this.drivers[this.driver].connection_types[this.connection_type] !== true) { throw new Error(`You cannot connect to a ${this.driver} database using the ${this.connection_type} connection type using this library.`); } return this; } // **************************************************************************** // Returns the single, pool, or cluster adapter // ----- // @return VOID This method responds asychronously via a callback // **************************************************************************** get_adapter() { const settings = Object.assign({}, this.settings); let Single; try { switch (this.connection_type) { case 'cluster': const Cluster = require(`${this.driver_info.path}/adapters/cluster.js`); return new Cluster(settings); case 'pool': const Pool = require(`${this.driver_info.path}/adapters/pool.js`) return new Pool(settings); case 'single': Single = require(`${this.driver_info.path}/adapters/single.js`) return new Single(settings, {}); default: Single = require(`${this.driver_info.path}/adapters/single.js`) return new Single(settings, {}); } } catch(e) { throw new Error(`Couldn't load the "${this.connection_type}" Adapter library for ${this.driver} (${JSON.stringify(this.settings)}): ${e}`); } } } module.exports = QueryBuilder;