Giter VIP home page Giter VIP logo

dblite's Introduction

dblite

Build Status

Deprecated

This module served me well to date but it's overly complicated for very little real-world gain or reasons to be so.

Please consider sqlite-tag-spawned as modern, safe, as fast as this module is, alternative, as I am not planning to improve much in here from now on, thank you!


a zero hassle wrapper for sqlite

var dblite = require('dblite'),
    db = dblite('file.name');

// Asynchronous, fast, and ...
db.query('SELECT * FROM table', function(err, rows) {
  // ... that easy!
});

More in the related blogpost and here too :-)

Updates

Version 0.7.5 forces -noheader flag if there is no explicit -header flag so that no matter what, headers will not be used.

This will eventually overwrite the .sqliterc but will make the library behavior more consistent across platforms.

Please check issue 35 to know more.


Previously, in sqlite3 version 3.8.6 you need a "new line agnostic" version of dblite, used in dblite version 0.6.0.

This breaks compatibility with older version of the database cli but this problem should have been fixed in 0.7.0.

// old version
var dblite = require('dblite');

// 3.8.6 version
var dblite = require('dblite').withSQLite('3.8.6+');

// new version, same as old one
var dblite = require('dblite');

It seems that sqlite3 version 3.8.8+ introduced a new line \n on Windows machines too so the whole initialization is now performed asynchronously and through features detection.

This should fix the annoying EOL problem "forevar"

The What And The Why

I've created dblite module because there's still not a simple and straight forward or standard way to have sqlite in node.js without requiring to re-compile, re-build, download sources a part or install dependencies instead of simply apt-get install sqlite3 or pacman -S sqlite3 in your *nix system.

dblite has been created with portability, simplicity, and reasonable performance for embedded Hardware such ARM boards, Raspberry Pi, Arduino Yun, Atmel MIPS CPUs or Linino boards in mind.

Generally speaking all linux based distributions like Arch Linux, where is not always that easy to node-gyp a module and add dependencies that work, can now use this battle tested wrap and perform basic to advanced sqlite operations.

Bootstrap

To install dblite simply npm install dblite then in node:

var dblite = require('dblite'),
    db = dblite('/folder/to/file.sqlite');

// ready to go, i.e.
db.query('.databases');
db.query(
  'SELECT * FROM users WHERE pass = ?',
  [pass],
  function (err, rows) {
    var user = rows.length && rows[0];
  }
);

By default the dblite function uses sqlite3 as executable. If you need to change the path simply update dblite.bin = "/usr/local/bin/sqlite3"; before invoking the function.

API

Right now a created EventEmitter db instance has 3 extra methods: .query(), .lastRowID(), and .close().

The .lastRowID(table, callback(rowid)) helper simplifies a common operation with SQL tables after inserts, handful as shortcut for the following query: SELECT ROWID FROM ``table`` ORDER BY ROWID DESC LIMIT 1.

The method .close() does exactly what it suggests: it closes the database connection. Please note that it is not possible to perform other operations once it has been closed.

Being an EventEmitter instance, the database variable will be notified with the close listener, if any.

Understanding The .query() Method

The main role in this module is played by the db.query() method, a method rich in overloads all with perfect and natural meaning.

The amount of parameters goes from one to four, left to right, where left is the input going through the right which is the eventual output.

All parameters are optionals except the SQL one.

db.query() Possible Combinations

db.query(SQL)
db.query(SQL, callback:Function)
db.query(SQL, params:Array|Object)
db.query(SQL, fields:Array|Object)
db.query(SQL, params:Array|Object, callback:Function)
db.query(SQL, fields:Array|Object, callback:Function)
db.query(SQL, params:Array|Object, fields:Array|Object)
db.query(SQL, params:Array|Object, fields:Array|Object, callback:Function)

All above combinations are tested properly in this file together with many other tests able to make dblite robust enough and ready to be used.

Please note how params is always before fields and/or callback if fields is missing, just as reminder that order is left to right accordingly with what we are trying to do.

Following detailed explanation per each parameter.

The SQL:string

This string accepts any query understood by SQLite plus it accepts all commands that regular SQLite shell would accept such .databases, .tables, .show and all others passing through the specified info listener, if any, using just the console as fallback otherwise.

var dblite = require('dblite'),
    db = dblite('./db.sqlite');

// will call the implicit `info` console.log
db.query('.show');
/* will console.log something like:

     echo: off
  explain: off
  headers: off
     mode: csv
nullvalue: ""
   output: stdout
separator: ","
    stats: off
    width:
*/

// normal query
db.query('CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY, value TEXT)');
db.query('INSERT INTO test VALUES(null, ?)', ['some text']);
db.query('SELECT * FROM test');
// will implicitly log the following
// [ [ '1', 'some text' ] ]
Warning!

This library heavily relies on strings and it normalizes them through special escaping which aim is to make passed data safe and secure which should be goal #1 of each db oriented API.

Please do not pass datamanually like INSERT INTO table VALUES (null, '[email protected]') and always use, specially for any field that contains strings, the provided API: INSERT INTO table VALUES (null, '@email') and {emaiL: '[email protected]'}. These kind of operations are described in the following paragraphs.

The params:Array|Object

If the SQL string contains special chars such ?, :key, $key, or @key properties, these will be replaced accordingly with the params Array or Object that, in this case, MUST be present.

// params as Array
db.query('SELECT * FROM test WHERE id = ?', [1]);

// params as Object
db.query('SELECT * FROM test WHERE id = :id', {id:1});
// same as
db.query('SELECT * FROM test WHERE id = $id', {id:1});
// same as
db.query('SELECT * FROM test WHERE id = @id', {id:1});

The fields:Array|Object

By default, results are returned as an Array where all rows are the outer Array and each single row is another Array.

db.query('SELECT * FROM test');
// will log something like:
[
  [ '1', 'some text' ],     // row1
  [ '2', 'something else' ] // rowN
]

If we specify a fields parameter we can have each row represented by an object, instead of an array.

// same query using fields as Array
db.query('SELECT * FROM test', ['key', 'value']);
// will log something like:
[
  {key: '1', value: 'some text'},     // row1
  {key: '2', value: 'something else'} // rowN
]

Parsing Through The fields:Object

SQLite Datatypes are different from JavaScript plus SQLite works via affinity. This module also parses sqlite3 output which is always a string and as string every result will always be returned unless we specify fields parameter as object, suggesting validation per each field.

// same query using fields as Object
db.query('SELECT * FROM test', {
  key: Number,
  value: String
});
// note the key as integer!
[
  {key: 1, value: 'some text'},     // row1
  {key: 2, value: 'something else'} // rowN
]

More complex validators/transformers can be passed without problems:

// same query using fields as Object
db.query('SELECT * FROM `table.users`', {
  id: Number,
  name: String,
  adult: Boolean,
  skills: JSON.parse,
  birthday: Date,
  cube: function (fieldValue) {
    return fieldValue * 3;
  }
});

The params:Array|Object AND The fields:Array|Object

Not a surprise we can combine both params, using the left to right order input to output so params first!

// same query using params AND fields
db.query('SELECT * FROM test WHERE id = :id', {
  id: 1
},{
  key: Number,
  value: String
});

// same as...
db.query('SELECT * FROM test WHERE id = ?', [1], ['key', 'value']);
// same as...
db.query('SELECT * FROM test WHERE id = ?', [1], {
  key: Number,
  value: String
});
// same as...
db.query('SELECT * FROM test WHERE id = :id', {
  id: 1
}, [
  'key', 'value'
]);

The callback:Function

When a SELECT or a PRAGMA SQL is executed the module puts itself in a waiting for results state.

Update - Starting from 0.4.0 the callback will be invoked with err and data if the callback length is greater than one. function(err, data){} VS function(data){}. However, latter mode will keep working in order to not break backward compatibility. Update - Starting from 0.3.3 every other SQL statement will invoke the callback after the operation has been completed.

As soon as results are fully pushed to the output the module parses this result, if any, and send it to the specified callback.

The callback is always the last specified parameter, if any, or the implicit equivalent of console.log.bind(console). Latter case is simply helpful to operate directly via node console and see results without bothering writing a callback each .query() call.

Extra Bonus: JSON Serialization With fields:Array|Object

If one field value is not scalar (boolean, number, string, null) JSON.stringify is performed in order to save data. This helps lazy developers that don't want to pre parse every field and let dblite do the magic.

// test has two fields, id and value
db.query('INSERT INTO test VALUES(?, ?)', [
  123,
  {name: 'dblite', rate: 'awesome'} // value serialized
]);

// use the fields to parse back the object
db.query('SELECT * FROM test WHERE id = ?', [123], {
  id: Number,
  value: JSON.parse // value unserialized
}, function (err, rows) {
  var record = rows[0];
  console.log(record.id); // 123
  console.log(record.value.name); // "dblite"
  console.log(record.value.rate); // "awesome""
});

Automatic Fields Through Headers

Since version 0.3.0 it is possible to enable automatic fields parsing either through initialization (suggested) or at runtime.

var dblite = require('dblite'),
    // passing extra argument at creation
    db = dblite('file.name', '-header');

db.query('SELECT * FROM table', function(err, rows) {
  rows[0]; // {header0: value0, headerN: valueN}
});

// at runtime
db
  .query('.headers ON')
  .query('SELECT * FROM table', function(err, rows) {
    rows[0]; // {header0: value0, headerN: valueN}
  })
  .query('.headers OFF')
;

In version 0.3.2 a smarter approach for combined headers/fields is used where the right key order is granted by headers but it's possible to validate known fields too.

var db = require('dblite')('file.name', '-header');

db.query('SELECT 1 as one, 2 as two', {two:Number}, function(err, rows) {
  rows[0]; // {one: "1", two: 2} // note "1" as String
});

In this way these two options can be supplementary when and if necessary.

Handling Infos And Errors - Listeners

The EventEmitter will notify any listener attached to info, error, or close accordingly with the current status.

db.on('info', function (data) {
  // show data returned by special syntax
  // such: .databases .tables .show and others
  console.log(data);
  // by default, it does the same
});

db.on('error', function (err) {
  // same as `info` but for errors
  console.error(err.toString());
  // by default, it does the same
});

db.on('close', function (code) {
  // by default, it logs "bye bye"
  // invoked once the database has been closed
  // and every statement in the queue executed
  // the code is the exit code returned via SQLite3
  // usually 0 if everything was OK
  console.log('safe to get out of here ^_^_');
});

Please note that error is invoked only if the callback is not handling it already via double argument.

The close event ensures that all operations have been successfully performed and your app is ready to exit or move next.

Please note that after invoking db.close() any other query will be ignored and the instance will be put in a waiting to complete state which will invoke the close listener once operations have been completed.

Raspberry Pi Performance

This is the output generated after a make test call in this repo folder within Arch Linux for RPi.

npm test

> [email protected] test /home/dblite
> node test/.test.js

/home/dblite/dblite.test.sqlite
------------------------------
main
passes: 1, fails: 0, errors: 0
------------------------------
create table if not exists
passes: 1, fails: 0, errors: 0
------------------------------
100 sequential inserts
100 records in 3.067 seconds
passes: 1, fails: 0, errors: 0
------------------------------
1 transaction with 100 inserts
200 records in 0.178 seconds
passes: 1, fails: 0, errors: 0
------------------------------
auto escape
passes: 1, fails: 0, errors: 0
------------------------------
auto field
fetched 201 rows as objects in 0.029 seconds
passes: 1, fails: 0, errors: 0
------------------------------
auto parsing field
fetched 201 rows as normalized objects in 0.038 seconds
passes: 1, fails: 0, errors: 0
------------------------------
many selects at once
different selects in 0.608 seconds
passes: 1, fails: 0, errors: 0
------------------------------
db.query() arguments
[ [ '1' ] ]
[ [ '2' ] ]
[ { id: 1 } ]
[ { id: 2 } ]
passes: 5, fails: 0, errors: 0
------------------------------
utf-8
¥ · £ · € · $ · ¢ · ₡ · ₢ · ₣ · ₤ · ₥ · ₦ · ₧ · ₨ · ₩ · ₪ · ₫ · ₭ · ₮ · ₯ · ₹
passes: 1, fails: 0, errors: 0
------------------------------
erease file
passes: 1, fails: 0, errors: 0

------------------------------
          15 Passes
------------------------------

If an SD card can do this good, I guess any other environment should not have problems here ;-)

F.A.Q.

Here a list of probably common Q&A about this module. Please do not hesitate to ask me more, if necessary, thanks.

  • How Does It Work? dblite uses a spawned version of the sqlite3 executable. It could theoretically work with any other SQL like database but it's tested with sqlite3-shell only

  • Does It Spawn Per Each Query? this is a quick one: NO! dblite spawns once per each database file where usually there is only one database file opened per time.

  • How About Memory And Performance? Accordingly with node manual:

    These child Nodes are still whole new instances of V8. Assume at least 30ms startup and 10mb memory for each new Node. That is, you cannot create many thousands of them.

    Since dblite spawns only once, there is a little overhead during the database initialization but that's pretty much it, the amount of RAM increases with the amount of data we save or retrieve from the database. The above Raspberry Pi Benchmark should ensure that with most common operation, and using transactions where possible, latency and RAM aren't a real issue.

  • Why Not The Native One? I had some difficulty installing this node-sqlite3 module due node-gyp incompatibilities with some ARM based device in both Debian and ArchLinux. Since I really needed an sqlite manager for the next version of polpetta which aim is to have a complete, lightweight, and super fast web server in many embedded hardware such RPi, Cubieboard, and others, and since I needed something able to work with multiple core too, I've decided to try this road wrapping the native, easy to install and update, sqlite3 shell client and do everything I need. So far, so good I would say ;-)

  • Isn't params and fields an ambiguous choice? At the very beginning I wasn't sure myself if that would have worked as API choice but later on I've changed my mind. First of all, it's very easy to spot special chars in the SQL statement. If present, params is mandatory and used, as easy as that. Secondly, if an object has functions as value, it's obviously a fields object, 'cause params cannot contains functions since these are not compatible with JSON serialization, neither meaningful for the database. The only case where fields might be confused with params is when no params has been specified, and fields is an Array. In this case I believe you are the same one that wrote the SQL too and know upfront if there are fields to retrieve from params or not so this is actually a non real-world problem and as soon as you try this API you'll realize it feels intuitive and right.

  • Are Transactions Supported? ... YES, transactions are supported simply performing multiple queries as you would do in sqlite3 shell:

  db.query('BEGIN TRANSACTION');
  for(var i = 0; i < 100; i++) {
    db.query('INSERT INTO table VALUES(?, ?)', [null, Math.random()]);
  }
  db.query('COMMIT');

The test file has a transaction with 100 records in it, have a look.

  • Can I Connect To A :memory: Database? well, you can do anything you would do with sqlite3 shell so YES
var db = dblite(':memory:'); // that's it!

License

The usual Mit Style, thinking about the WTFPL though ... stay tuned for updates.

Copyright (C) 2013 by WebReflection

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 THE
AUTHORS OR COPYRIGHT HOLDERS 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.

dblite's People

Contributors

greysdawn avatar webreflection avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dblite's Issues

Database is locked

Sorry, here again.
I am testing the system done with dblite and after a two days of testing I got this error:

``Error: Error: near line 44372: database is locked`

It caused the next query to fail.
Is there any workaround? Or maybe I'm handling the errors in the wrong way?

Uncaught invalid executable error with nwjs 0.23.0

OSX El Capitan 10.11.6

Getting error from /Users/blatman/Desktop/invalidexec/node_modules/dblite/build/dblite.node.js:879
Uncaught invalid executable: /Users/blatman/Desktop/invalidexec/node_modules/sqlite3/sqlite3

dblite.node.js
876 value = path.resolve(value);
877 // verify it exists
878 if (!require(IS_NODE_06 ? 'path' : 'fs').existsSync(value)) {
879 throw 'invalid executable: ' + value;
880 }

sqlite3 is latest 3.1.8 npm install
Both versions of nwjs 0.23.0 get this error and don't work.

However if I replace the sqlite3 module with an earlier install which was still 3.1.8 I get the scenario where the nwjs using node 7 and earlier will work fine and give no errors.
The nwjs version using node 8 will crash.

Initially thought node v8 was a suspect but then not sure why dblite is not liking sqlite3 all of a sudden.
Has node 8 done something with fs.existsSync maybe?

nwjs 0.23.0 - node v 7.10.0
http://dl.nwjs.io/live-build/05-26-2017/nw23-b56aac2-03b9af7-4a0cadc-f041292/v0.23.0/nwjs-sdk-v0.23.0-osx-x64.zip

nwjs 0.23.0 - node v 8.0.0pre
http://dl.nwjs.io/live-build/05-31-2017/nw23-b56aac2-9b4425c-10a09e1-c429d34/v0.23.0/nwjs-sdk-v0.23.0-osx-x64.zip

Extra Bonus (ERROR): JSON Serialization With fields:Array|Object

This is not working for me (v0.8.22). I tried using this functionality and it failed with an error. So I decided to just take the example code listed here and run it, the same error occurred. This is the code I ran:

var dblite = require('dblite'),
db = dblite(':memory:');

db.query('CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY, value TEXT)');
db.query('INSERT INTO test VALUES(null, ?)', ['some text']);
db.query('SELECT * FROM test');

db.query('INSERT INTO test VALUES(?, ?)', [
123,
{name: 'dblite', rate: 'awesome'} // value serialized
]);

// use the fields to parse back the object
db.query('SELECT * FROM test WHERE id = ?', [123], {
id: Number,
value: JSON.parse // value unserialized
}, function (rows) {
var record = rows[0];
console.log(record.id); // 123
console.log(record.value.name); // "dblite"
console.log(record.value.rate); // "awesome""
});

Produced this error:

/home/node/webs/node_modules/dblite/build/dblite.node.js:692
"'" + what.replace(SINGLE_QUOTES, SINGLE_QUOTES_DOUBLED) + "'"
^
TypeError: Object # has no method 'replace'
at escape (/home/node/webs/node_modules/dblite/build/dblite.node.js:692:20)
at replaceQuestions (/home/node/webs/node_modules/dblite/build/dblite.node.js:644:10)
at String.replace (native)
at replaceString (/home/node/webs/node_modules/dblite/build/dblite.node.js:626:21)
at EventEmitter.self.query (/home/node/webs/node_modules/dblite/build/dblite.node.js:481:17)
at next (/home/node/webs/node_modules/dblite/build/dblite.node.js:208:18)
at Socket. (/home/node/webs/node_modules/dblite/build/dblite.node.js:291:9)
at Socket.EventEmitter.emit (events.js:96:17)
at Pipe.onread (net.js:397:14)

How to run queries synchronously?

Hey there;

I'd like to be able to run some queries synchronously. Is there a way to do so?

In it's simplest form, I'd like to call db.query and get an array of records back in a blocking manner.

e.g

// the following is not how db.query works. It's how I'd *like* it to work sometimes
var rows = db.query('SELECT * FROM test');
console.log(rows)
// this would print an array of records to the console.

Is this possible? I'd like to do it for inserts, and deletes as well. Thanks!

sqlite json functions don't work

from command line this works:

sqlite> select * from json_each(json_array(20170318,20170319,20170329));
0|20170318|integer|20170318|1||$[0]|$
1|20170319|integer|20170319|2||$[1]|$
2|20170329|integer|20170329|3||$[2]|$

from dblite it results:

[ {}, {}, {} ]

error caused by ABORT renders db unresponsive forever

Encountered with node.js v0.10.25:

If a column has an UNIQUE constraint with the ON CONFLICT ABORT rule, an attempt to insert a non-unique value is correctly answered by an error:

"Error: near line 1: column email is not unique"

However, db is fucked up afterwards, and no callbacks will ever be called by db.query again, tearing down all db-dependent querys to node.js. I will investigate this further.

Cannot escape dollar sign $ while insert the database query

Hello I'm trying to use the libs it looks good but it having issue during processing the dollar sign $

bcrypt.hash(password, bcrypt.genSaltSync(saltRounds) , null, function (err, hash) {
            const insertUsers = 'INSERT INTO users (username, password) VALUES ("kerupukceleng", "$2a$10$IWEAROjtixonnkJ6OJ1Y5.mJCeP54HUi6IaEzAJd74HtzmcoC62Mi");';
            console.log(insertUsers);
            db.query(insertUsers);
        });

but giving me error

\node_modules\dblite\build\dblite.node.js:771
  return escape(paramsObject[key]);
                            ^

TypeError: Cannot read properties of undefined (reading '2a$10$IWEAROjtixonnkJ6OJ1Y5')

Thank you

Dblite does not return query a second time in Linux

Hej there,

I've been working a fair amount with this module and I really love it. Thank you for making it!

I have a strange issue though I would like to hear your take on this:

Currently I run a query to check if my database has any entries available. (eg SELECT * FROM table ORDER BY album asc) If this query returns an error or null, I kick off a separate process to fetch items to fill up the database. So far so good.

Once the separate scraping process has completed its task, I rerun the previous query to check if the database is filled with the desired entries. This is where things go wrong in Linux only. Windows works just fine.

In Linux, the function wrapping the query is being called (checked with console logs), but the query itself never returns anything. Not an error, nor any results.

If I stop the node process and restart it again, the initial check is done and of course since the separate scraping process has already filled the database, the query returns the result.

So what is happening here? Why doesn't the query do anything the second time I run it?

To see the code check here: https://github.com/jansmolders86/mediacenterjs/blob/master/apps/music/music-functions.js

My attempts to fix this so far have been:

  • Added timeouts in case it is some sort of async problem
  • Adding "db.close()" on several places but this only results in errors.

I'm kind of at a loss and I really hope you can shed some light on this problem.

I'm using sqlite3 version 3.7.9

Thank you again for your hard work!

Jan

Callback of query() not called on UPDATE/INSERT

$callback only gets filled/called when the query begins with SELECT or PRAGMA. Shouldn't it also get called after a successful INSERT or UPDATE?

I got the desired behaviour by adjusting the SELECT regex to include UPDATE and INSERT as a quick fix, but I haven't investigated possible other (negative) consequences.

Database not properly closed when .close() is called while in "busy" state

Hi @WebReflection,

I think I may have found a little bug in the current version of the library.
This is related to the close() method: if you call this method while the object is marked as busy, then the ".exit" command is queued but never gets run, because the notWorking flag is set immediately, and then when query() is called again by next(), the method exits before actually running the command.

This sequence of events can happen for instance if you run a select query that raises a fatal error (that makes sqlite output to stderr but not to stdout, so the busy flag is not reset), and then try to close the database.

As a (rather ugly) workaround, setting ignoreErrors==true and adding a call to a successful select before closing solves the problem. E.g.:

db.ignoreErrors= true;
db.query("select 1", function(err, data) {
    db.close();
});

(This "resets" the busy state before the call to close(), so that .exit will be properly run regardless of what happened before).

This is quite a minor issue, as the object is unusable anyway after the call to close(), but it can interfere when doing unit tests with lots of sequential database openings and closings, as the db file stays open (thus locked) until the dblite object gets garbage-collected, instead of being explicitly freed when close() is called.

Please let me know if you need more information to reproduce this.
Bye!

Error message could be improved for sqlite3 < 3.7.15

Since Mac OS 10.8 ships with 3.7.12, my first experience with dblite was:

Error: near "-": syntax error

bye bye

after a little digging, I discovered dblite requires .print, which only arrived in 3.7.15 (December 12, 2012).

dblite could detect incompatible versions the from the welcome prompt:

SQLite version 3.7.12 2012-04-03 19:43:07
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite>

send a misspelled query doesn't return error string

Hi

if I send a query like this:

db.query('select jhgfkjhg * from users',function(err,data) {
    console.log(err);
    console.log(data);
});

err is null and data is an array of 0 elements.

even if a set a global listener db.on('error'... the error inside the closure is an array of 0 elements.

if I send a query like this:

db.query('select jhgfkjhg * from users',null,{id:Number},function(err,data) {
    console.log(err);
    console.log(data);
});

returns:

Uncaught node.js Error 
TypeError: Cannot call method 'forEach' of undefined
    at Socket.eval (... \node_modules\dblite\build\dblite.node.js:296:25 ...)

I run all my code under node-webkit

I do something wrong?
Thanks for your code

Some .mode states not working

Seems to be a problem with setting the .mode and getting file output from the db unless I am missing something simple ....

MacOS 10.13.6 High Sierra
Test Versions:
dblite 1.0.1
sqlite 3.19.3 2017-06-27 16:48:08 (system install - usr/bin)
sqlite3-tools-osx 3.27.2 2019-02-25 16:06:06 (app standalone)
nwjs 0.37.1-sdk (node 11.11.0)
nwjs 0.33.4-sdk (node 10.11.0)
nwjs 0.19.6-sdk (node 7.4.0)

The code below is from dbcontrol.js and the dblite.bin is set for default (system install of sqlite).
If I try the .dump and the save to csv via the Terminal using the same system install everything works fine

Test 1: Try to dump db to .sql file
L293 ~ 295 - result is dumpo.sql file is produced but only contains the MagicNumber (eg: ---W8m6W0zRbPJz7VcaHszdnJA/CZsPeOWzaX7xrD87lzoqM7/OT0WuS9+y933s87Il5YlqHJMkI76fxDcHFcCqVg==---)

I tried setting the mode to ascii since the .dump is an ascii dump but no file is produced and the ascii setting doesn't appear to work.
The .sql file is only produced if the .mode is set for column/line/list/tabs (tabs will set list) - all the other mode values (ascii/csv/html/insert/quote/tcl) do not seem to work and the following .show (L289) will not be captured via info filter.

Test 2: Try to save to .csv file
L303 ~ 322 - csv mode setting doesn't appear to work and no file produced. If a workable mode (eg: list) is used then the .csv is produced but only contains the Magic Numbers.

288 db.query('.mode line');
289 db.query('.show');
290
291 // var newDb = 'Hippowaddler.db';
292 //sqlite3 music.db .dump > music.sql
293 var dumpPath = 'dumpo.sql';
294 db.query('.output ' + dumpPath);
295 db.query('.dump');
296
297 //db.query('.binary off');
298
299
300 // *****************************************************************************
301 // Save to csv file test
302
303 var csvPath = process.cwd() + '/hippo.csv';
304 db.query('.headers on');
305
306 //db.query('.mode ascii'); // FAILS
307 //db.query('.mode column'); // OK
308 db.query('.mode csv'); // FAILS
309 //db.query('.mode html'); // FAILS
310 //db.query('.mode insert'); // FAILS
311 //db.query('.mode line'); // OK
312 //db.query('.mode list'); // OK
313 //db.query('.mode quote'); // FAILS
314 //db.query('.mode tabs'); // sets as list
315 //db.query('.mode tcl'); // FAILS
316
317 db.query('.once ' + csvPath);
318
319 //db.query('.output ' + csvPath);
320
321 //db.query('SELECT * FROM playlists', ['playlistid', 'name']);
322 db.query('SELECT * FROM playlists');
323
324 db.query('.show');

Test app if required attached minus nwjs binary

For nwjs just download/unzip and plonk nwjs.app into the test app folder alongside package.json - double-click to run
http://dl.nwjs.io/live-build/nw37/03-20-2019/b2357a9d6/v0.37.1/

nakedDBLite.zip

Cheers

sqlite 3.8.6-1

Hello (:

Since I upgraded to the latest version of sqlite the query function doesn´t call the callback.
I can still insert things to the database with INSERT though. All the SELECT queryes stucks the databse.

Version 3.8.5-1 works fine.

Best regards !

multiple client connections to db

Apologies for submitting this as an issue - I didn't see a means to otherwise ask a general question.

I have been using a sqlite database to collect and sort results, but allowing multiple connections (so that the workload of entering data can be shared between a small group of people - the actual use case is collecting competition results where we need to enter 100s of results quite quickly). I was thinking of re-writing the system we've been using as a node application (long story).

Having used dblite in some other node work that i've done recently, I wondered how how dblite might cope with this case. Specifically, supposing the node application opened a single database connection, but INSERT/UPDATE queries were received from multiple clients, would dblite queue the relevant queries or would I likely run into blocking issues at the sqlite end of things?

I'm not talking about a large number of clients, usually less than half a dozen perhaps, and whilst there might be other database solutions that could be used sqlite has worked well enough in the past that I don't particularly feel the need to change.

Thanks for any advice and apologies again if I've missed a more appropriate means of enquiry...

Doesn't work on latest node

This worked fine but know it doesn't work on node v0.10.36

No errors, no nothing from the tests ... doesn't look like it's spawning sqlite3.exe

Windows

dblite installation broken (npm)

This is the folder structure I get after issuing the command:

npm install dblite

...

node_modules/
dblite/
benchmark/
dblite.js
sqlite3.js
LICENSE.txt
package.json
README.md

missing subfolder: build

this however, works as expected:
npm install git://github.com/WebReflection/dblite.git

I tried several times in different folders.

on close events don't work as expected.

Hi,

I am happy to use this great package, however I would like to make a process which create db, import data inside and then send data to a remote host.
My issue is when I call close methods with query, I never recevied on close events as describe on specification

db.on('close', function (code) {
  // by default, it logs "bye bye"
  // invoked once the database has been closed
  // and every statement in the queue executed
  // the code is the exit code returned via SQLite3
  // usually 0 if everything was OK
  console.log('safe to get out of here ^_^_');
});

and so I never can launch my third step of my process.

plese see eveidence bellow

var dblite = require('dblite'),
db = dblite('./db.sqlite');
db.on('close', function (code) {
  // by default, it logs "bye bye"
  // invoked once the database has been closed
  // and every statement in the queue executed
  // the code is the exit code returned via SQLite3
  // usually 0 if everything was OK
  console.log('safe to get out of here ^_^_', code);
});
db.close();

outpus is : safe to get out of here ^^ 0

This is OK.

however

var dblite = require('dblite'),
db = dblite('./db.sqlite');
db.on('close', function (code) {
  // by default, it logs "bye bye"
  // invoked once the database has been closed
  // and every statement in the queue executed
  // the code is the exit code returned via SQLite3
  // usually 0 if everything was OK
  console.log('safe to get out of here ^_^_', code);
});
db.query('CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY, value TEXT)');
db.close();

output is empty, event is never emit, this is not OK.

Can you please tell me if I am doing something wrong?

error detection

hi,

what is wrong on this? (apologies for my english...)

win server 2012

PS C:\consip> node -v
v0.12.1

PS C:\consip> npm list dblite
C:\consip
└── [email protected]

PS C:\consip> sqlite3
SQLite version 3.8.8.3 2015-02-25 13:29:11
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> .ex

PS C:\consip> type .\testErr.js
var dblite = require('dblite'),
consipDB = dblite('consip.db');
consipDB.query(
"select * ffrom utenti where nome=?",["pp"],
function(err1, rows) {
console.log(err1,rows)
}
);

PS C:\consip> node .\testErr.js
null []

How to use special characters on the SQL

Hi!
I'd like to use special character inside the sql. As special character I refer to https://github.com/WebReflection/dblite#the-paramsarrayobject

I'd like to execute this query:

INSERT OR REPLACE INTO User (user_id, username, group_id, status, credits, active) 
VALUES ( 58,"[email protected]",(SELECT group_id FROM Groups WHERE groupname="subscriber"),1,0,1);

But I got:

.../node_modules/dblite/build/dblite.node.js:672
.../node_modules/dblite/build/dblite.node.js:672
  return escape(paramsObject[key]);
  return escape(paramsObject[key]);
                                  ^
                      ^
TypeError: Cannot read property 'gmail' of null

And I didn't find anything in a quick documentation look.

dblite.bin isn't respected

Since Mac OS 10.8 ships with a version of sqlite3 without print, I installed a new version with brew install dblite and set dblite.bin = '/usr/local/opt/sqlite/bin/sqlite3'.

But dblite was still using the old binary.

This line is invoking sqlite3 with the proper cwd, but just as in a terminal, that doesn't work. If it were invoking ./sqlite3 or the full path there, it would.

Can't open database

Says
Error: near "/": syntax error

Even if i put a relative or fix path, program is the one below

var dblite = require('dblite');

var db = dblite( '/home/jj/var/ProjetStyle/node/test.sqlite3' , function ( err , result ) {

if ( err )
    console.log(err) ;
else
    console.log(result) ;

} ) ;

System Linux 3.2.0-56-generic 32Bit
cwd /home/jj/var/ProjetStyle/node
node -v v0.10.22
npm -v 1.3.14

older sqlite3 versions support (no -csv switch)

I have an older sqlite3 (3.3.6) version installed on a machine. This version does not support the -csv switch, therefore the spawn fails.

All other switches are supported, i.e.

-column
-html
-line
-list
-separator

The same can be achieved with list + separator ... I think -csv is only a shortcut for that...

-list -separator ','

ist the same as

-csv

I checked!

What do you think?

node-sqlite3

From reading your readme I see that you had trouble installing node-sqlite3. I wanted to let you know that we now have a system in place to provide binaries and so installing no longer requires node-gyp, python, or a compiler. See https://github.com/developmentseed/node-sqlite3/wiki/Binaries for details.

We don't have binaries yet for platforms other than mac, windows, and linux, but there is no reason why we can't eventually provide them for arm/rasp. I can understand if you feel good momentum with the dblite approach and don't want to contribute to node-sqlite3, but wanted to let you know either way.

Error: spawn sqlite3 ENOENT when creating db

Hi,
I've installed dblite on my raspberry pi and when I'm trying to instantiate a db

var dblite = require('dblite');
var db_path = __dirname+'/db/db.sqlite';
db = dblite(db_path, '-header');

and run node app.js, I'm having this error

Error: spawn sqlite3 ENOENT

The db exists and is readable and the path is correct.

On OSX the error doesn't appear.

Thanks!
\m

Undefined parameter in SQL string hangs dblite instance

Everything is in the title.

I had to edit escape(what) function to manage undefined what.

case 'undefined':
    return 'null';

Without this patch, a missing parameter hangs the query queue because of

  throw new Error('unsupported data');

dblite small example does not terminate

I'm using node v0.11.21
SQLite version 3.7.9
node --harmony dblite.js

Linux 3.2.0-24-virtual #37-Ubuntu SMP Wed Apr 25 12:51:49 UTC 2012 i686 i686 i386 GNU/Linux

var dblite = require('dblite'),
db = dblite('./tags.db');

db.on('error', function(err) {
console.log('something terrible happened, rebooting', err);
process.exit();
})
// ready to go, i.e.
db.query('.databases');

prints out the correct information, but hangs rather than completing.

shouldn't integer types be returned as integers (and not strings?)

im doing this:

var dblite = require('dblite'),
            db = dblite(':memory:');
        db.query('CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY, textValue TEXT, intValue INTEGER)');
        db.query('INSERT INTO test VALUES(null, ?, ?)', ['some text', 123]);
        db.query('SELECT * FROM test');

and expect to have the intValue returned as an Integer and NOT a String.

i know i can do this:

     db.query('SELECT * FROM test', {
            id: Number,
            textValue: String,
            intValue: Number
        });

but maybe i don't want object notation, also its more to write..

but i do like object notation, and when you enable the -header option you get the rows automatically as objects with names of the columns, just like in sqlite3-node, but the Integeres are strings, if you dont set this explicitly..

this is the output i get in both cases:

[ [ '1', 'some text', '123' ] ]
[ { id: 1, textValue: 'some text', intValue: 123 } ]

query with fields object|array fails on empty table

If you query an empty table with a fields object or array, you get the following error:

/Users/jcole/src/harvester/node_modules/dblite/build/dblite.node.js:296
              result[0].forEach(enrichFields, fields);

This happens if the table is empty or the query returns no rows due to the where clause.

Errors on callbacks

Is there a reason errors are not returned on callbacks, like normally in node.js libs? I think it is more difficult to do tests and return error messages when you have to set an event handler on the db object.

Ubuntu gives me a EACCES error

Hi there,

I've been using DBlite with great success and I'm very grateful!
I have a question about running DBlite in Linux.

I've been developing in Windows without issues and I am now testing on Linux.
I have the following code:

 // Init Database
 dblite.bin = "./lib/database/sqlite3";
 var db = dblite('./lib/database/mcjs.sqlite');

In the database folder I have the binaries for both Linux and Windows.
I've tried without having the mcjs.sqlite present and with the file already in place.

But I keep getting the following error:

Events.js:72
throw er; // unhandled 'error' event

Error: spawn EACCES

When I remove the DBlite code the error disappears.
I also tried installing sqlite3 with apt-get and settings read and write permissions on the folder.

Do you know what I'm doing wrong by any change?

Thanks again,
Jan

I dont know -> child_process.js:1230 throw errnoException(err, 'kill');

This is my errorcode
child_process.js:1230
throw errnoException(err, 'kill');
^
Error: kill EINVAL
at exports._errnoException (util.js:746:11)
at ChildProcess.kill (child_process.js:1230:13)
at setUpAndGo (C:\Users\Theenoro\desk\Project Mio\app\node_modules\dblite\bu
ild\dblite.node.js:161:19)
at Socket.onerror (C:\Users\Theenoro\desk\Project Mio\app\node_modules\dblit
e\build\dblite.node.js:135:11)
at Socket.emit (events.js:107:17)
at onwriteError (_stream_writable.js:317:10)
at onwrite (_stream_writable.js:335:5)
at WritableState.onwrite (_stream_writable.js:105:5)
at fireErrorCallbacks (net.js:448:13)
at Socket._destroy (net.js:486:3)

and this is the only thing I have written.
var dblite = require('dblite'),
db = dblite('./db.sqlite');

Select queries do not return log

Hi there,

I'm very excited to use this module as I was looking for a SQLite implementation that wasn't constricted by node-gyp.

I'm been doing some tests and creating a database and writing to that database works great!

But I'm having trouble retrieving data from that database.

My code:

    console.log('do i have access to db?', db.query);
    db.query(
        'SELECT * FROM test',
        function(rows) {
            console.log('test',rows);
        }
    );

My connection code:

    dblite.bin = "./lib/database/sqlite3";
    db = dblite('./lib/database/test.sqlite');

What am I doing wrong? The console.log shows the 'db.query' is accessible but I do not see the test log.

What am I doing wrong?

Thanks for your time and efforts!

Jan

how make it run on Windows

I work on windows 7, and install the sqlite3 in the folder C:\albert\sqlite, both sqlite3.dll and sqlite3.exe exist in this folder. and I installed dblite ( npm install dblite ) in my Visual Studio Code.
and create a database file named 'abc.db' and a source code file app.js, it contains the following source codes.
var dblite = require('dblite');
db = dblite('./abc.db');

however it throw the following error:
Exception has occurred: Error
Error: kill EINVAL
at exports._errnoException (util.js:1018:11)
at ChildProcess.kill (internal/child_process.js:397:13)
at setUpAndGo (c:\albert\NetCode\NodejsWorkspace\dblitetest\node_modules\dblite\build\dblite.node.js:162:19)
at Socket.onerror (c:\albert\NetCode\NodejsWorkspace\dblitetest\node_modules\dblite\build\dblite.node.js:135:11)
at emitOne (events.js:96:13)
at Socket.emit (events.js:188:7)
at onwriteError (_stream_writable.js:343:10)
at onwrite (_stream_writable.js:361:5)
at __dirname.WritableState.stream.onwrite (_stream_writable.js:90:5)
at fireErrorCallbacks (net.js:467:13)

would you please take a look at this issue or give me some ideas to make it run on Windows

Encryption support

Hello guys,

Is any kind of encryption supported?

If not, do you have plans for it?

Regards

Problem with JSON.stringify on binary BLOB fields

When dblite uses JSON.stringify on binary BLOB fields, there is a problem when i want to use sqlite3 dbs created by others with binary data (not stringified). I now need to have two different ways of parsing them. I wish BLOB fields where not stringified, or one could make it optional.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.