partial work

This commit is contained in:
AJ ONeal 2015-07-21 18:58:34 -06:00
commit ab33eee579
7 changed files with 192 additions and 0 deletions

35
README.md Normal file
View File

@ -0,0 +1,35 @@
DRAFT
=====
This is just hypothetical while I build out the API
SQLite3 Server
=============
Node.js runs on a single core, which isn't very effective.
You can run multiple Node.js instances to take advantage of multiple cores,
but if you do that, you can't use SQLite in each process.
This module will either run client-server style in environments that benefit from it
(such as the Raspberry Pi 2 with 4 cores), or in-process for environments that don't
(such as the Raspberry Pi B and B+).
Usage
=====
```js
var sqlite = require('sqlite3-server');
var opts = {
key: '1892d335081d8d346e556c9c3c8ff2c3'
, bits: 128
, storage: path.join('/tmp/authn.sqlcipher')
, verbose: false
, port: 3232 // default random
, forceServer: true // default false
};
sqlite.create(opts).then(function (db) {
// EXACT same api as db
});
```

3
client.js Normal file
View File

@ -0,0 +1,3 @@
'use strict';

12
index.js Normal file
View File

@ -0,0 +1,12 @@
'use strict';
var path = require('path');
var numcpus = require('os').cpus().length;
if (numcpus >= 2) {
sqlite3 = require('./sqlite-client');
} else {
sqlite3 = require('./sqlite3-wrapper');
}
module.exports = sqlite3;

11
install-sqlcipher.bash Normal file
View File

@ -0,0 +1,11 @@
#brew options sqlcipher
#brew install sqlcipher --with-fts
echo STOP
echo You must manually install sqlcipher
exit 1
export LDFLAGS="-L`brew --prefix`/opt/sqlcipher/lib"
export CPPFLAGS="-I`brew --prefix`/opt/sqlcipher/include"
npm install sqlite3 --build-from-source --sqlite_libname=sqlcipher --sqlite=`brew --prefix`
node -e 'require("sqlite3")'

15
serve.js Normal file
View File

@ -0,0 +1,15 @@
'use strict';
var server = require('http').createServer();
var WebSocketServer = require('ws').Server;
var wss = new WebSocketServer({ server: server });
var port = process.env.PORT || process.argv[0] || 4080;
var app = require('./sqlite-server');
server.listen(port, function () {
});
app.create({ server: server, wss: wss }).then(function (app) {
server.on('request', app);
});

55
server.js Normal file
View File

@ -0,0 +1,55 @@
'use strict';
function create(options) {
var url = require('url');
var express = require('express');
var app = express();
var wss = options.wss;
wss.on('connection', function (ws) {
var location = url.parse(ws.upgradeReq.url, true);
// you might use location.query.access_token to authenticate or share sessions
// or ws.upgradeReq.headers.cookie (see http://stackoverflow.com/a/16395220/151312
ws.__session_id = location.query.session_id || Math.random();
ws.on('message', function (buffer) {
var cmd;
try {
cmd = JSON.parse(buffer.toString('utf8'));
} catch(e) {
ws.send(JSON.stringify({ type: 'error', value: { message: e.message, code: "E_PARSE_JSON" } }));
}
switch(cmd.type) {
case 'init':
break;
case 'rpc':
break;
default:
break;
}
});
ws.send(JSON.stringify({ type: 'session', value: ws.__session_id }));
});
/*
var tablename = 'authn';
if (tablename) {
setup.push(db.runAsync("CREATE TABLE IF NOT EXISTS '" + sanitize(tablename)
+ "' (id TEXT, secret TEXT, json TEXT, PRIMARY KEY(id))"));
}
*/
/*global Promise*/
return new Promise(function (resolve) {
resolve(app);
});
}
module.exports.create = create;

61
sqlite-wrapper.js Normal file
View File

@ -0,0 +1,61 @@
'use strict';
/*global Promise*/
var sqlite3 = require('sqlite3');
var dbs = {};
function sanitize(str) {
return String(str).replace("'", "''");
}
function create(opts) {
var db;
if (!opts) {
opts = {};
}
if (opts.verbose) {
sqlite3.verbose();
}
if (!dbs[opts.storage] || dbs[opts.storage].__key !== opts.key) {
dbs[opts.storage] = new sqlite3.Database(opts.storage);
}
db = dbs[opts.storage];
db.__key = opts.key;
return new Promise(function (resolve, reject) {
db.serialize(function() {
var setup = [];
if (opts.key) {
// TODO test key length
if (!opts.bits) {
opts.bits = 128;
}
// TODO db.run(sql, function () { resolve() });
setup.push(new Promise(function (resolve, reject) {
db.run("PRAGMA KEY = \"x'" + sanitize(opts.key) + "'\"", [], function (err) {
if (err) { reject(err); return; }
resolve(this);
});
}));
setup.push(new Promise(function (resolve, reject) {
db.run("PRAGMA CIPHER = 'aes-" + sanitize(opts.bits) + "-cbc'", [], function (err) {
if (err) { reject(err); return; }
resolve(this);
});
}));
}
Promise.all(setup).then(function () { resolve(db); }, reject);
});
});
}
module.exports.sanitize = sanitize;
module.exports.Database = sqlite3.Database;
module.exports.create = create;