Common Database Interface for Node

Overview

database-js

Build Status npm version Mentioned in Awesome Node.js downloads

Wrapper for multiple databases with a JDBC-like connection

Database-js implements a common, promise-based interface for SQL database access. Inspired by Java, it uses connection strings to identify the database driver. Wrappers around native database drivers provide a unified interface to handle databases. Thus, you don't need to modify your code (except the connection string) to change your database! 😉

Database-js has built-in prepared statements, even if the underlying driver does not support them. It is built on Promises, so it works well with ES7 async code.

Contents

Install

npm install database-js

Drivers

Driver (wrapper) Note Installation
ActiveX Data Objects Windows only npm i database-js-adodb
CSV files npm i database-js-csv
Excel files npm i database-js-xlsx
Firebase npm i database-js-firebase
INI files npm i database-js-ini
JSON files npm i database-js-json
MySQL npm i database-js-mysql
MS SQL Server npm i database-js-mssql
PostgreSQL npm i database-js-postgres
SQLite npm i database-js-sqlite

See here how to add a new driver.

Usage

var Connection = require('database-js').Connection;

// 👉 Change the connection URL according to the database you need to connect
var conn =
	new Connection("sqlite:///path/to/test.sqlite"); // SQLite
	// new Connection("mysql://user:password@localhost/test"); // MySQL
	// new Connection("postgres://user:password@localhost/test"); // PostgreSQL
	// new Connection( < ANOTHER URL HERE > ); // see the drivers

var statement = conn.prepareStatement("SELECT * FROM states WHERE state = ?");
statement.query("South Dakota")
	.then((results) => {
		console.log(results); // Display the results
		conn.close() // Close the database connection
			.then(() => {
				process.exit(0); // Success!
			}).catch((reason) => {
				console.log(reason); // Some problem when closing the connection
				process.exit(1);
			});
	}).catch((reason) => {
		console.log(reason); // Some problem while performing the query
		conn.close() // Close the connection
			.then(() => {
				process.exit(0); // Success!
			}).catch((reason) => {
				console.log(reason); // Some problem when closing the connection
				process.exit(1);
			});
	});

Async / await

Because database-js is built on Promises, it works very well with async/await. Compare the following code to the code from above. They accomplish the same thing.

var Connection = require('database-js').Connection;

(async function() {
    let conn, statement, results;
    try {
        conn = new Connection("sqlite:///path/to/test.sqlite"); // Just change the connection URL for a different database
        statement = conn.prepareStatement("SELECT * FROM states WHERE state = ?");
        results = await statement.query("South Dakota");
        console.log(results);
    } catch (reason) {
        console.log(reason);
    } finally {
        if (conn) {
            await conn.close();
        }
        process.exit(0);
    }
})();

See also

codeceptjs-dbhelper - Allows to use database-js inside CodeceptJS tests (as a helper).

License

MIT

Comments
  • Try to use the name

    Try to use the name "database-js" on NPM

    The original projected named 'database-js' is abandoned. Acessing its project page returns a 404.

    NPM has a policy about disputes that states This process is an excellent way to: - Adopt an "abandoned" package (...), among other things. So, I think this is a good opportunity to get the name database-js.

    opened by thiagodp 12
  • Global connection already exists. Call sql.close() first.

    Global connection already exists. Call sql.close() first.

    I have a test like:

    
    async myFunction() {
    ...
    try {
    		conn = new Connection(connStr); 
    		statement = conn.prepareStatement(orderIdsQuery);
    
    		do {
    			results = await statement.query();
    		}
    		while ([undefined, null].includes(results));
    
    		let randomIndex = getRandomInt(0, results.length - 1);
    		let orderId = results[randomIndex].Id;
    		let multiDrive = results[randomIndex].DriverAmount === 1;
    
    		statement = conn.prepareStatement(orderPeopleQuery);
    
    		do {
    			results = await statement.query(orderId);
    		}
    		while ([undefined, null].includes(results));
    
    		result = {'orderId': orderId, 'multiDrive': multiDrive, 'people': results};
    	}
    	catch (reason) {
    		console.log(reason);
    	}
    	finally {
    		if (conn) {
    			await conn.close();
    		}
    	}
    
    	return result;
    }
    
    Before() {
    ...
    let res = await myFunction();
    ...
    }
    
    Scenario() {
    ...
    }.retry(1)
    

    It is expected that test to work like this: If it fails - it starts again, completes request once more, and then goes to scenario steps, but I got this exception after test restarted:

    Error: Global connection already exists. Call sql.close() first.
        at Object.connect (/Users/orkhan.mamedov/WebstormProjects/SravniClient/node_modules/database-js-mssql/node_modules/mssql/lib/base.js:1639:10)
        at MsSql._pool (/Users/orkhan.mamedov/WebstormProjects/SravniClient/node_modules/database-js-mssql/index.js:61:33)
        at MsSql.query (/Users/orkhan.mamedov/WebstormProjects/SravniClient/node_modules/database-js-mssql/index.js:73:31)
        at /Users/orkhan.mamedov/WebstormProjects/SravniClient/node_modules/database-js/lib/statement.js:69:38
        at new Promise (<anonymous>)
        at PreparedStatement.query (/Users/orkhan.mamedov/WebstormProjects/SravniClient/node_modules/database-js/lib/statement.js:60:16)
    ...
    

    It seems as a bug, can you help me with that?

    opened by orihomie 4
  • Accept connection parameters from a plain object

    Accept connection parameters from a plain object

    Currently, Connection currently receives a connectionString:

    class Connection {
        constructor(connectionString, driver) {
            this.__base = ParseConnection(connectionString, driver);
            . . .
        }
      . . .
    }
    

    Sometimes it is desirable to create a connection passing parameters, such as in ConnectionObject, or maybe using a plain object.

    So, to adjusting Connection's constructor to accept both a string or a ConnectionObject would be:

    class Connection {
        constructor(conn, driver) {
            this.__base = 'string' === typeof conn ? ParseConnection(conn, driver) : conn;
            . . .
       }
       . . .
    }
    

    To receiving a plain object with connection properties, I think it would be better changing ConnectionObject instead of Connection. In this case, ConnectionObject could have a static constructor-like method:

    class ConnectionObject {
       ...
       static fromPlain( obj, driver ) {
          return new ConnectionObject(
            obj[ 'driverName' ], 
            obj[ 'username' ],
            obj[ 'password' ],
            obj[ 'hostname' ],
            obj[ 'port' ],
            obj[ 'database' ],
            obj[ 'parameters' ],
            driver
          );
       }
      . . .
    }
    

    And then we could create a connection from a plain object:

    let p = require( 'mydb.json' ); // a JSON file with database connection properties
    let c = new Connection( ConnectionObject.fromPlain( p, driver ), driver );
    // or just
    let c = new Connection( ConnectionObject.fromPlain( require( 'mydb.json' ), driver ) );
    

    Wouldn't it be nice?

    opened by thiagodp 4
  • Hack for drivers be tested properly

    Hack for drivers be tested properly

    Database-js has drivers as separated projects. It does not need to include them as dev dependencies.

    On the other side, the drivers should include database-js as a dev dependency, for testing purposes (or they have to me maintained inside database-js, but never committed). However, database-js loads the drivers according to the driverName, including (with require) the respective file. Since the driver's index.js is not inside database-js, it is not able to find it and, thus, to load the driver.

    There is a little hack, however, to solve this problem. I have used it in database-js-json, inside its mocha test file:

        var obj = {
            // hack to load the index of the driver as a module of database-js
            driverName: '../../../index', 
            . . .
        };
       var conn = new dbjs.Connection( obj );
       . . .
    

    It would be nice having another solution to the driver loading problem. I the mean time, this hack can be useful to add proper tests in each driver project. @mlaanderson What do you think?

    enhancement question 
    opened by thiagodp 3
  • There is an issue with the string connection

    There is an issue with the string connection

    I think there is an error using a string connection , I had to change my password in order to make it work

    for example my password : gwW^/0/L

    was not working image

    I think it would be cool if you could receive an object so in that way the regex wont fail and it would be easier to pass the parameters

    opened by javierfuentesm 2
  • hang await statement.query always loading

    hang await statement.query always loading

    conn = new Connection("database-js-postgres://postgres:password@ip:5432/db"); try { statement = await conn.prepareStatement("SELECT * FROM connection WHERE name = ?"); rows = await statement.query('datasama'); console.log(rows); } catch (error) { console.log(error); } finally { await connection.close(); }

    opened by tegarkurniawan 2
  • Add Travis build

    Add Travis build

    Activate this project in Travis, in order to let it check the build status. Then we can add an image of the build status to the README.md file.

    @mlaanderson I've already added the file .travis.yml to the project.

    enhancement 
    opened by thiagodp 2
  • Simpler driver names

    Simpler driver names

    Instead of using database-js-driver://, the project could adopt just driver://.

    Examples (JDBC-like):

    • mysql for MySQL databases (currently database-js-mysql)
    • postgresql for PostgreSQL databases (currently database-js-postgres)
    • sqlite for SQLite databases (currently database-js-sqlite)
    • firebase for Firebase databases (currently database-js-firebase)
    • ado for ActiveX Data Objects, like MS Excel tables and MS Access databases (currently database-js-adodb)
    • ini for INI files (currently database-js-ini)

    Other examples (for future use?):

    • json for JSON files
    • xml for XML files
    • odbc for ODBC access to databases
    • oracle for Oracle databases
    • sqlserver for MS SQL Server databases
    • firebirdsql for Firebird databases
    • mariadb for MariaDB (as an alternative driver to MySQL)
    enhancement 
    opened by thiagodp 2
  • Beter examples

    Beter examples

    Please, Can you provide better examples, how to use database-js? Something like this https://www.w3schools.com/nodejs/nodejs_mysql_create_db.asp How to create database, create table, insert into table a single row and insert multiple rows from array, update data, delete data ... database-je nice because support a lot of different drivers.

    Thanks in advance, VladanO

    opened by vladano 1
  • QuoteString() only escapes the first special character of each type in a string

    QuoteString() only escapes the first special character of each type in a string

    QuoteString() uses the string.replace() method to escape special characters, but passes the patterns to it as strings. When the pattern is given as a string, only the first instance of the pattern is replaced.

    The patterns need to be converted to regex patterns/objects in order for every instance to be replaced properly. For example, string = string.replace("'", "''"); becomes string = string.replace(/'/g, "''");.

    I'm preparing a PR and will be submitting it soon if you'd be willing to accept it.

    opened by zachary-D 1
  • Improve subprojects' keywords

    Improve subprojects' keywords

    When trying to search "database-js" in NPM, the subprojects don't appear. Maybe adding the keyword database-js to them would make they do.

    So, in order to improve the discoverability of database-js and subprojects, I suggest that:

    NPM uses the keywords from package.json.

    opened by thiagodp 1
  • Add support to TXT files

    Add support to TXT files

    Proposal

    database-js-txt

    Virtual Columns

    Text files could have these virtual columns:

    1. line (any line of the file)
    2. line_number

    Examples:

    # Line starting with Hello
    SELECT `line_number`, `line` WHERE `line` LIKE "Hello%"
    
    # First line in the file
    SELECT `line` WHERE `line_number` = 1
    
    # Number of lines in the file
    SELECT COUNT( `line` )
    
    # Number of lines in the file, different way
    SELECT MAX( `line_number` )
    
    # Last line in the file
    SELECT `line` WHERE `line_number` = COUNT( `line` )
    
    # Content from some lines
    SELECT `line` WHERE `line_number` BETWEEN 5 AND 10
    
    # Content from some lines, different way (needed?)
    SELECT `line` OFFSET 5 LIMIT 5
    

    Basic Operators

    =, <>, >, >=, <, <=, LIKE, NOT, AND, OR, BETWEEN

    Basic Constructions

    WHERE, ORDER BY

    Basic Functions

    COUNT, MAX

    Expected future enhancements

    • MATCHES operator, for matching a given regular expression. E.g., SELECT * WHERE line MATCHES "^Created at [0-9]{1,2}:[0-9]{1,2}"
    enhancement help wanted 
    opened by thiagodp 0
Releases(v3.0.10)
Owner
null
DolphinDB JavaScript API is a JavaScript library that encapsulates the ability to operate the DolphinDB database, such as: connecting to the database, executing scripts, calling functions, uploading variables, etc.

DolphinDB JavaScript API English | 中文 Overview DolphinDB JavaScript API is a JavaScript library that encapsulates the ability to operate the DolphinDB

DolphinDB 6 Dec 12, 2022
PostgreSQL interface for Node.js

pg-promise PostgreSQL interface for Node.js About Support & Sponsorship Documentation Contributing Usage Methods Query Formatting Index Variables Name

Vitaly Tomilov 3.2k Jan 6, 2023
⚡️ lowdb is a small local JSON database powered by Lodash (supports Node, Electron and the browser)

Lowdb Small JSON database for Node, Electron and the browser. Powered by Lodash. ⚡ db.get('posts') .push({ id: 1, title: 'lowdb is awesome'}) .wri

null 18.9k Dec 30, 2022
Execute one command (or mount one Node.js middleware) and get an instant high-performance GraphQL API for your PostgreSQL database!

PostGraphile Instant lightning-fast GraphQL API backed primarily by your PostgreSQL database. Highly customisable and extensible thanks to incredibly

Graphile 11.7k Jan 4, 2023
AlaSQL.js - JavaScript SQL database for browser and Node.js. Handles both traditional relational tables and nested JSON data (NoSQL). Export, store, and import data from localStorage, IndexedDB, or Excel.

Please use version 1.x as prior versions has a security flaw if you use user generated data to concat your SQL strings instead of providing them as a

Andrey Gershun 6.1k Jan 9, 2023
The JavaScript Database, for Node.js, nw.js, electron and the browser

The JavaScript Database Embedded persistent or in memory database for Node.js, nw.js, Electron and browsers, 100% JavaScript, no binary dependency. AP

Louis Chatriot 13.2k Jan 2, 2023
Node.js client for the Aerospike database

Aerospike Node.js Client An Aerospike add-on module for Node.js. The client is compatible with Node.js v8.x, v10.x (LTS), v12.x (LTS), and v14.x (LTS)

Aerospike 198 Dec 30, 2022
jSQL is a locally instantiated database for Node.js

jSQL is a locally instantiated database for Node.js. It provides the functionalities of a database, unique to a single project, meaning that no configuration from one project will affect another one.

Denes Garda 3 Mar 7, 2022
A database library stores JSON file for Node.js.

concisedb English | 简体中文 A database library stores JSON file for Node.js. Here is what updated every version if you want to know. API Document Usage B

LKZ烂裤子 3 Sep 4, 2022
The Blog system developed by nest.js based on node.js and the database orm used typeorm, the development language used TypeScript

考拉的 Nest 实战学习系列 readme 中有很多要说的,今天刚开源还没来及更新,晚些慢慢写,其实本人最近半年多没怎么写后端代码,主要在做低代码和中台么内容,操作的也不是原生数据库而是元数据Meta,文中的原生数据库操作也当作复习下,数据库的操作为了同时适合前端和Node开发小伙伴,所以并不是很

程序员成长指北 148 Dec 22, 2022
A Node.js library for retrieving data from a PostgreSQL database with an interesting query language included.

RefQL A Node.js library for retrieving data from a PostgreSQL database with an interesting query language included. Introduction RefQL is about retrie

Rafael Tureluren 7 Nov 2, 2022
A web client port-scanner written in GO, that supports the WASM/WASI interface for Browser WebAssembly runtime execution.

WebAssembly Port Scanner Written in Go with target WASM/WASI. The WASM main function scans all the open ports in the specified range (see main.go), vi

Avi Lumelsky 74 Dec 27, 2022
A web SQL interface to your Stripe account using Datasette.

Datasette, Stripe and tdog Or: Stripe Sigma Alternative Datasette is a web GUI for exploring SQLite datasets. Stripe handles online payments. Sigma is

Table Dog 20 Nov 27, 2022
🔄 A realtime Database for JavaScript Applications

RxDB A realtime Database for JavaScript Applications RxDB (short for Reactive Database) is a NoSQL-database for JavaScript Applications like Websites,

Daniel Meyer 18.6k Dec 31, 2022
:koala: - PouchDB is a pocket-sized database.

PouchDB – The Database that Syncs! PouchDB is an open-source JavaScript database inspired by Apache CouchDB that is designed to run well within the br

PouchDB 15.4k Dec 30, 2022
🍉 Reactive & asynchronous database for powerful React and React Native apps ⚡️

A reactive database framework Build powerful React and React Native apps that scale from hundreds to tens of thousands of records and remain fast ⚡️ W

Nozbe 8.8k Jan 5, 2023
Lovefield is a relational database for web apps. Written in JavaScript, works cross-browser. Provides SQL-like APIs that are fast, safe, and easy to use.

Lovefield Lovefield is a relational database written in pure JavaScript. It provides SQL-like syntax and works cross-browser (currently supporting Chr

Google 6.8k Jan 3, 2023
Realm is a mobile database: an alternative to SQLite & key-value stores

Realm is a mobile database that runs directly inside phones, tablets or wearables. This project hosts the JavaScript versions of Realm. Currently we s

Realm 5.1k Jan 3, 2023
:rocket: One command to generate REST APIs for any MySql Database.

Xmysql : One command to generate REST APIs for any MySql database Why this ? Generating REST APIs for a MySql database which does not follow conventio

null 129 Dec 30, 2022