Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

keydb

Package Overview
Dependencies
Maintainers
1
Versions
19
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

keydb - npm Package Compare versions

Comparing version 0.0.2 to 0.0.4

lib/drivers/kv-mysql.js

4

index-server.js

@@ -10,3 +10,7 @@ var keydb = require('./lib/keydb');

keydb.driver('version', require('./lib/drivers/version'));
keydb.driver('table', require('./lib/drivers/table'));
keydb.driver('kv-mysql', require('./lib/drivers/kv-mysql'));
keydb.sugar('kv-mysql', require('./lib/sugar/kv-mysql'));
module.exports = keydb;

261

lib/drivers/mysql.js

@@ -6,2 +6,12 @@ var q = require('q');

var dbTypes = {
string: function (prop) {
if (prop.maxLength && prop.maxLength < 10000) {
return 'varchar(' + prop.maxLength + ') collate latin1_bin';
} else {
return 'longblob';
}
}
};
var Db = function (options) {

@@ -38,8 +48,3 @@ this.database = options.database || options.id || 'keydb';

var sql = 'create table if not exists ' + self.database + '.' + name + ' (';
columns.forEach(function (column, i) {
if (i > 0) {
sql += ', ';
}
sql += ' ' + column;
});
sql += columns.join(', ');
sql += ')';

@@ -67,59 +72,2 @@ return q.when(self.query(sql));

var valueToRow = function (command) {
var row = {
media_value: null,
media_type: null
};
if (command.isBinary) {
row.value_type = 'bin';
row.media_type = command.mediaType;
// TODO: need to parse base64, blah, blah
} else if (command.mediaType) {
row.value_type = 'txt';
row.media_type = command.mediaType;
row.media_value = command.value;
} else if (typeof command.value === 'string') {
row.value_type = 'str';
row.media_value = command.value;
} else if (typeof command.value === 'number') {
row.value_type = 'num';
row.media_value = JSON.stringify(command.value);
} else if (typeof command.value === 'boolean') {
row.value_type = 'bool';
row.media_value = JSON.stringify(command.value);
} else if (typeof command.value === 'undefined' || command.value === 'null') {
row.value_type = 'null';
} else {
row.value_type = 'json';
row.media_value = JSON.stringify(command.value);
}
return row;
};
var rowToObject = function (row) {
var obj = {value: null};
if (row.value_type === 'bin') {
obj.isBinary = true;
obj.mediaType = row.media_type;
// TODO: convert to base64, blah, blah
} else if (row.value_type === 'txt') {
obj.mediaType = row.media_type;
obj.value = row.media_value.toString();
} else if (row.value_type === 'str') {
obj.value = row.media_value.toString();
} else if (row.value_type === 'num') {
obj.value = JSON.parse(row.media_value.toString());
} else if (row.value_type === 'bool') {
obj.value = JSON.parse(row.media_value.toString());
} else if (row.value_type === 'null') {
obj.value = null;
} else if (row.value_type === 'json') {
// cross fingers
obj.value = JSON.parse(row.media_value.toString());
} else {
obj.value = null;
}
return obj;
};
var createMySqlSource = function (next, options) {

@@ -130,69 +78,112 @@ options = options || {};

var init = function () {
var modifiedTimeColumn = 'modified_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP';
return db.createDatabase()
var initDatabase = function () {
return db.createDatabase();
};
var readyDatabase = utils.createReady(initDatabase);
var makeInitTableFn = function (tableName) {
return function () {
var defs = [];
var table = options.tables[tableName];
if (!table) {
throw new error.TableSchemaNotFound({table: tableName});
}
var props = table.properties;
Object.keys(props).forEach(function (key) {
var prop = props[key];
var def = key + ' ' + dbTypes[prop.type](prop);
if (table.required && Array.isArray(table.required) && table.required.indexOf(key) >= 0) {
def += ' not null';
}
defs.push(def);
});
if (!table.primaryKey) {
throw new error.PrimaryKeyRequired({table: tableName});
}
defs.push('primary key (' + table.primaryKey + ')');
return db.createTable(tableName, defs);
};
};
var readyTable = {};
var ready = function (msg) {
return readyDatabase()
.then(function () {
return db.createTable('item', [
'item_key varchar(500) collate latin1_bin',
'tag_key varchar(500) collate latin1_bin',
'value_type varchar(8)',
'media_value longblob',
'media_type varchar(250)',
'version varchar(50) not null',
'source_key varchar(500) collate latin1_bin',
'primary key (item_key)',
'modified_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP',
'index(source_key)'
]);
})
.then(function (result) {
if (result.warningCount === 1) {
// table was already created
return db.ensureColumn('item', modifiedTimeColumn);
if (!msg.table) {
return;
}
if (!readyTable[msg.table]) {
readyTable[msg.table] = utils.createReady(makeInitTableFn(msg.table));
}
return readyTable[msg.table]();
});
};
// make a function that will return a promise that resolves when initialized
var ready = utils.createReady(init);
var reset = function () {
readyDatabase = utils.createReady(initDatabase);
readyTable = {};
};
var msgKeys = function (msg, attrs) {
try {
var primaryKeys = options.tables[msg.table].primaryKey;
if (typeof primaryKeys === 'string') {
primaryKeys = [primaryKeys];
}
primaryKeys.forEach(function (key) {
if (!attrs[key]) {
throw new error.PrimaryKeyRequiredForOp({op: msg.op});
}
});
return primaryKeys;
} catch (e) {
throw new error.PrimaryKeyRequiredForOp({op: msg.op});
}
};
var ops = {
get: function (msg) {
// if (msg.keys) {
// return ops.getKeys(msg);
// }
query: function (msg) {
var sql = [
'select * from ' + db.tableId('item'),
'select',
msg.attributes ? msg.attributes.join(',') : '*',
'from ' + db.tableId(msg.table),
'where',
'item_key = ' + mysql.escape(msg.key)
Object.keys(msg.filters).map(function (key) {
return key + ' = ' + mysql.escape(msg.filters[key]);
})
].join('\n');
return db.query(sql)
.then(function (result) {
if (result.length < 1) {
throw new error.NotFound({key: msg.key});
}
var reply = rowToObject(result[0]);
reply.key = msg.key;
return reply;
.then(function (results) {
// Need to remove non-column properties.
var items = [];
return {
items: results.map(function (result) {
var obj = {};
Object.keys(result).forEach(function (key) {
obj[key] = result[key];
});
return obj;
})
};
});
},
// getKeys: function (msg) {
// var prefix = msg.key || '';
// var keys = msg.keys.map(function (key) {
// return prefix + key;
// });
// },
create: function (msg) {
var valueFields = valueToRow(msg);
var sql = 'insert into ' + db.tableId('item');
sql += ' (item_key, tag_key, value_type, media_value, media_type, version) select ';
sql += ' ' + mysql.escape(msg.key);
sql += ', ' + mysql.escape(msg.tag || null);
sql += ', ' + mysql.escape(valueFields.value_type);
sql += ', ' + mysql.escape(valueFields.media_value);
sql += ', ' + mysql.escape(valueFields.media_type);
sql += ', ' + mysql.escape(msg.version);
sql += ' from dual where not exists ( select * from ' + db.tableId('item');
sql += ' where item_key = ' + mysql.escape(msg.key);
sql += ')';
var sql = [
'insert into ' + db.tableId(msg.table),
'(' + Object.keys(msg.attributes).join(',') + ')',
'select',
Object.keys(msg.attributes).map(function (key) {
return mysql.escape(msg.attributes[key]);
}).join(','),
'from dual where not exists',
'(',
'select * from ' + db.tableId(msg.table),
'where ',
msgKeys(msg, msg.attributes).map(function (key) {
return key + ' = ' + mysql.escape(msg.attributes[key]);
}).join(','),
')'
].join('\n');
return db.query(sql)

@@ -208,14 +199,13 @@ .then(function (result) {

update: function (msg) {
var valueFields = valueToRow(msg);
var sql = 'update ' + db.tableId('item') + ' ';
sql += 'set item_key = ' + mysql.escape(msg.key) + ' ';
sql += ', tag_key = ' + mysql.escape(msg.tag || null) + ' ';
sql += ', value_type = ' + mysql.escape(valueFields.value_type) + ' ';
sql += ', media_value = ' + mysql.escape(valueFields.media_value) + ' ';
sql += ', media_type = ' + mysql.escape(msg.mediaType) + ' ';
sql += ', version = ' + mysql.escape(msg.version) + ' ';
sql += 'where item_key = ' + mysql.escape(msg.key) + ' ';
if (msg.ifVersion) {
sql += 'and version = ' + mysql.escape(msg.ifVersion) + ' ';
}
var sql = [
'update ' + db.tableId(msg.table),
'set ',
Object.keys(msg.attributes).map(function (key) {
return key + ' = ' + mysql.escape(msg.attributes[key]);
}).join(','),
'where',
msgKeys(msg, msg.filters).map(function (key) {
return key + ' = ' + mysql.escape(msg.filters[key]);
}).join(',')
].join('\n');
return db.query(sql)

@@ -232,5 +222,7 @@ .then(function (result) {

var sql = [
'delete from ' + db.tableId('item'),
'delete from ' + db.tableId(msg.table),
'where',
'item_key = ' + mysql.escape(msg.key)
msgKeys(msg, msg.filters).map(function (key) {
return key + ' = ' + mysql.escape(msg.filters[key]);
}).join(',')
].join('\n');

@@ -245,2 +237,9 @@ return db.query(sql)

});
},
'delete-database': function (msg) {
return db.query('drop database ' + mysql.escapeId(options.database))
.then(function () {
console.log("DELETED ALL DATA FOREVER FROM: " + options.database);
reset();
});
}

@@ -250,3 +249,3 @@ };

var source = function (msg) {
return ready()
return ready(msg)
.then(function () {

@@ -253,0 +252,0 @@ return ops[msg.op](msg);

var utils = require('../utils');
var error = require('../error');

@@ -24,2 +25,5 @@ var createStack = function (next) {

stack.driver = function (driver) {
if (typeof driver !== 'function') {
throw new error.InvalidDriver({});
}
var args = utils.slice(arguments, 1);

@@ -26,0 +30,0 @@ drivers.push(function (next) {

@@ -7,3 +7,3 @@ var _ = require('underscore');

var source = function (msg) {
if (msg.op === 'set') {
if (msg.op === 'set' || msg.op === 'upsert') {
var createMsg = _.extend({}, msg);

@@ -10,0 +10,0 @@ var updateMsg = _.extend({}, msg);

var errman = require('errman')();
errman.registerType('InvalidDriver', {
status: 500,
code: 'invalid_driver',
message: 'An invalid driver was added to a stack.'
});
errman.registerType('TableSchemaNotFound', {
status: 500,
code: 'table_schema_not_found',
message: 'No table schema defined for table: {{table}}'
});
errman.registerType('PrimaryKeyRequired', {
status: 500,
code: 'primary_key_required',
message: 'No primary key defined for table: {{table}}'
});
errman.registerType('PrimaryKeyRequiredForOp', {
status: 500,
code: 'primary_key_required_for_op',
message: 'No primary key defined for operation: {{op}}'
});
errman.registerType('InvalidKey', {

@@ -4,0 +28,0 @@ status: 400,

@@ -6,5 +6,31 @@ var q = require('q');

var keydb = function (source) {
return createStackSource(source);
if (typeof source === 'string') {
var stack = createStackSource();
var args = Array.prototype.slice.call(arguments, 1);
stack.driver.apply(stack, [keydb.drivers[source]].concat(args));
if (keydb.sugars[source]) {
stack = keydb.sugars[source](stack);
}
return stack;
} else {
return createStackSource(source);
}
};
var camelize = function (id) {
if (id.indexOf('-') >= 0) {
var parts = id.split('-');
if (parts.length > 1) {
return parts[0] + parts.slice(1).map(function (part) {
if (part.length > 0) {
return part[0].toUpperCase() + part.slice(1);
} else {
return part;
}
}).join('');
}
}
return id;
};
keydb.drivers = {};

@@ -14,4 +40,12 @@

keydb.drivers[id] = driver;
keydb.drivers[camelize(id)] = driver;
};
keydb.sugars = {};
keydb.sugar = function (id, wrap) {
keydb.sugars[id] = wrap;
keydb.sugars[camelize(id)] = wrap;
};
keydb.error = require('./error');

@@ -18,0 +52,0 @@

{
"name": "keydb",
"version": "0.0.2",
"version": "0.0.4",
"description": "Key/value data/query API to use on the server and in the browser.",

@@ -5,0 +5,0 @@ "main": "index-server.js",

@@ -6,3 +6,3 @@ keydb

Key/value data/query API to use on the server or in the browser.
Build data APIs using the middleware concept.

@@ -42,12 +42,69 @@ ## Installation

db.driver(keydb.drivers.upsert);
db.driver(keydb.drivers.version);
db.driver(keydb.drivers.mysql);
db.driver(keydb.drivers.mysql, {
database: 'test',
tables: {
user: {
properties: {
user_id: {
type: 'string',
maxLength: 100
},
first_name: {
type: 'string',
maxLength: 100
},
last_name: {
type: 'string',
maxLength: 100
}
},
primaryKey: 'user_id'
}
}
});
db({op: 'set', key: 'users/joe', value: {fn: 'Joe'}})
db({
op: 'upsert',
attributes: {
user_id: 'joe', first_name: 'Joe', last_name: 'Foo'
},
filters: {user_id: 'joe'}
})
.then(function () {
return db({op: 'get', key: 'users/joe'});
return db({op: 'query', filters: {user_id: 'joe'}});
})
.then(function (msg) {
console.log(msg);
console.log(msg.items);
})
```
In the above example, an upsert driver is stacked on top of a mysql driver so
that upsert semantics can be added to mysql without the underlying driver
actually supporting upsert.
Some drivers are preconfigured stacks, and these can be easily created by their
IDs. They may also add sugar methods.
```js
var keydb = require('keydb');
var db = keydb('kv-mysql');
db.set('users/joe', {firstName: 'Joe'})
.then(function () {
return db.get('users/joe');
})
```
The above is the same as:
```js
var keydb = require('keydb');
var db = keydb('kv-mysql');
db({op: 'set', key: 'users/joe', value: {firstName: 'Joe'}})
.then(function () {
return db({op: 'get', key: 'users/joe'});
})
```

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc