Skip to content

Commit

Permalink
working with binary save and load
Browse files Browse the repository at this point in the history
  • Loading branch information
mikesmullin committed Dec 30, 2012
1 parent dff88cd commit 7251e0b
Show file tree
Hide file tree
Showing 23 changed files with 27,771 additions and 84 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules/
20 changes: 0 additions & 20 deletions Makefile

This file was deleted.

61 changes: 0 additions & 61 deletions README.markdown

This file was deleted.

43 changes: 43 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Node.js SQLite 100% JavaScript implementation

sql.js is a port of SQLite to JavaScript, by compiling the SQLite C code with Emscripten.
no C bindings or node-gyp compilation here.

SQLite is public domain, sql.js is MIT licensed.

## Usage

```coffeescript
Sql = require 'node-sql'
Sql.open db_file, {}, (err, db) ->
throw err if err
db.exec '''
/* Demo DB */
CREATE TABLE employees( id integer, name text,
designation text, manager integer,
hired_on date, salary integer,
commission float, dept integer);
INSERT INTO employees VALUES (1,'JOHNSON','ADMIN',6,'12-17-1990',18000,NULL,4);
INSERT INTO employees VALUES (2,'HARDING','MANAGER',9,'02-02-1998',52000,300,3);
INSERT INTO employees VALUES (3,'TAFT','SALES I',2,'01-02-1996',25000,500,3);
INSERT INTO employees VALUES (4,'HOOVER','SALES I',2,'04-02-1990',27000,NULL,3);
INSERT INTO employees VALUES (5,'LINCOLN','TECH',6,'06-23-1994',22500,1400,4);
INSERT INTO employees VALUES (6,'GARFIELD','MANAGER',9,'05-01-1993',54000,NULL,4);
INSERT INTO employees VALUES (7,'POLK','TECH',6,'09-22-1997',25000,NULL,4);
INSERT INTO employees VALUES (8,'GRANT','ENGINEER',10,'03-30-1997',32000,NULL,2);
INSERT INTO employees VALUES (9,'JACKSON','CEO',NULL,'01-01-1990',75000,NULL,4);
INSERT INTO employees VALUES (10,'FILLMORE','MANAGER',9,'08-09-1994',56000,NULL,2);
INSERT INTO employees VALUES (11,'ADAMS','ENGINEER',10,'03-15-1996',34000,NULL,2);
INSERT INTO employees VALUES (12,'WASHINGTON','ADMIN',6,'04-16-1998',18000,NULL,4);
INSERT INTO employees VALUES (13,'MONROE','ENGINEER',10,'12-03-2000',30000,NULL,2);
INSERT INTO employees VALUES (14,'ROOSEVELT','CPA',9,'10-12-1995',35000,NULL,1);
'''

db.exec "SELECT * FROM employees WHERE designation = 'CEO';", (err, results) ->
assert.deepEqual [{"id":"9","name":"JACKSON","designation":"CEO","manager":"(null)","hired_on":"01-01-1990","salary":"75000","commission":"(null)","dept":"4"}], results
```

## Related

* [In-Browser/Client-Side Demo](http://syntensity.com/static/sql.html)
19 changes: 19 additions & 0 deletions c/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Edit for your paths
EMSCRIPTEN=~/Dev/emscripten
EMCC=$(EMSCRIPTEN)/emcc -O2
# -s INLINING_LIMIT=0
CFLAGS=-DSQLITE_DISABLE_LFS -DLONGDOUBLE_TYPE=double -DSQLITE_INT64_TYPE="long long int" -DSQLITE_THREADSAFE=0

all: ../js/sql.js ../test/benchmark.html ../test/benchmark.js

sql.js: sqlite3.c
$(EMCC) $(CFLAGS) sqlite3.c main.c --pre-js ../js/pre.js --post-js ../js/post.js -o ../js/sql.js -s EXPORTED_FUNCTIONS="['_sqlite3_open', '_sqlite3_close', '_sqlite3_exec']"

benchmark.html: sqlite3.c benchmark.c
$(EMCC) $(CFLAGS) sqlite3.c benchmark.c -o ../test/benchmark.html

benchmark: benchmark.c
gcc $(CFLAGS) -pthread -O2 sqlite3.c benchmark.c -o ../test/benchmark

clean:
rm ../js/sql.js ../test/benchmark.html ../test/benchmark.js
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
107 changes: 107 additions & 0 deletions coffee/node-sqlite-purejs.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
vm = require 'vm'
fs = require 'fs'
code = ''

module.exports = class Sql
# create new instance
# optionally read database from disk
@open: (file, options, cb) ->
s = new Sql()
s.file = file
s.options = options or {}
js_file = __dirname+'/sql.js'
data = `undefined`
serial = []
serial[0] = ->
next = serial[1]
return next() if code
fs.readFile js_file, 'utf8', (err, _code) ->
return cb err if err
code = _code
return next()
return
serial[1] = ->
next = serial[2]
sandbox = vm.createContext
ArrayBuffer: ArrayBuffer
Float32Array: Float32Array
Float64Array: Float64Array
Int16Array: Int16Array
Int32Array: Int32Array
Int8Array: Int8Array
Uint16Array: Uint16Array
Uint32Array: Uint32Array
Uint8Array: Uint8Array
process: process
require: require
console: log: console.log
vm.runInContext code, sandbox, js_file
s.instance = sandbox.SQL
return next() if s.options.manual_load is true
fs.exists s.file, (exists) ->
return next() if not exists
s.load (err, _data) ->
return cb err if err
data = _data
next()
serial[2] = ->
s.db = s.instance.open data
cb null, s
return
serial[0]()
return

# query the in-memory database
exec: (sql, cb) ->
try
# split multiple queries
sql = sql.split ';'
for k of sql when sql[k]
last_result = @db.exec sql[k]+';'

serial = []
serial[0] = =>
next = serial[1]
# optionally save current database state to disk
return next() if @options.manual_save is true
@save (err) ->
return cb err if err
return next()
serial[1] = ->
# convert result to object
recordset = []
for i, row of last_result
record = {}
for ii, col of row
record[col.column] = col.value
recordset.push record

# return result
cb and cb null, recordset
serial[0]()

catch err # err occurred
cb and cb err # return err

return

# read database from disk
load: (cb) ->
fs.readFile @file, (err, buffer) ->
return cb err if err
return cb null, new Uint8Array buffer
return

# write database to disk
save: (cb) ->
view = @db.exportData()
buffer = new Buffer view.byteLength
i = 0
while i < buffer.length
buffer[i] = view[i++]
fs.writeFile @file, buffer, (err) ->
setTimeout (-> cb err), 0
return # important that this returns immediately
return


Loading

0 comments on commit 7251e0b

Please sign in to comment.