pico-engine-core
Advanced tools
Comparing version 0.45.5 to 0.45.6
{ | ||
"name": "pico-engine-core", | ||
"version": "0.45.5", | ||
"version": "0.45.6", | ||
"description": "The core javascript api for the pico-engine. (no http, logging, process management etc...)", | ||
@@ -5,0 +5,0 @@ "main": "src/index.js", |
105
src/DB.js
@@ -42,23 +42,50 @@ var _ = require("lodash"); | ||
var putPVar = function(ldb, key_prefix, query, val, callback){ | ||
var path = ktypes.isNull(query) ? [] : toKeyPath(query); | ||
query = ktypes.isNull(query) ? [] : query; | ||
query = ktypes.isArray(query) ? query : [query]; | ||
// do this before toKeyPath b/c it will convert all parts to stings | ||
var isArrayIndex = _.isInteger(query[0]) && query[0] >= 0; | ||
var path = toKeyPath(query); | ||
if(_.size(path) > 0){ | ||
var subkey_prefix = key_prefix.concat(["value", _.head(path)]); | ||
var sub_path = _.tail(path); | ||
if(_.isEmpty(sub_path)){ | ||
ldb.put(subkey_prefix, val, callback); | ||
return; | ||
} | ||
ldb.get(subkey_prefix, function(err, data){ | ||
if(err && err.notFound){ | ||
data = {}; | ||
}else if(err){ | ||
var subkeyPrefix = key_prefix.concat(["value", path[0]]); | ||
var subPath = _.tail(path); | ||
ldb.get(key_prefix, function(err, oldRoot){ | ||
if(err && ! err.notFound){ | ||
callback(err); | ||
return; | ||
} | ||
data = _.set(data, sub_path, val); | ||
ldb.put(subkey_prefix, data, callback); | ||
var ops = []; | ||
var type = oldRoot && oldRoot.type; | ||
if(type !== "Map" && type !== "Array"){ | ||
type = isArrayIndex ? "Array" : "Map"; | ||
} | ||
if(type === "Array" && !isArrayIndex){ | ||
type = "Map";// convert to map if a non-index key comes in | ||
} | ||
var root = { | ||
type: type, | ||
// this `value` helps _.set in the toObj db dump set the right type | ||
value: type === "Array" ? [] : {} | ||
}; | ||
ops.push({type: "put", key: key_prefix, value: root}); | ||
if(_.isEmpty(subPath)){ | ||
ops.push({type: "put", key: subkeyPrefix, value: val}); | ||
ldb.batch(ops, callback); | ||
return; | ||
} | ||
ldb.get(subkeyPrefix, function(err, data){ | ||
if(err && err.notFound){ | ||
data = {}; | ||
}else if(err){ | ||
callback(err); | ||
return; | ||
} | ||
data = _.set(data, subPath, val); | ||
ops.push({type: "put", key: subkeyPrefix, value: data}); | ||
ldb.batch(ops, callback); | ||
}); | ||
}); | ||
return; | ||
} | ||
ldb.get(key_prefix, function(err, data){ | ||
ldb.get(key_prefix, function(err, oldRoot){ | ||
if(err && ! err.notFound){ | ||
@@ -68,3 +95,3 @@ callback(err); | ||
} | ||
var db_ops = []; | ||
var ops = []; | ||
dbRange(ldb, { | ||
@@ -74,15 +101,16 @@ prefix: key_prefix, | ||
}, function(key){ | ||
db_ops.push({type: "del", key: key}); | ||
ops.push({type: "del", key: key}); | ||
}, function(err){ | ||
if(err) return callback(err); | ||
var index_type = ktypes.typeOf(val); | ||
var root_value = {type: index_type}; | ||
switch(index_type){ | ||
var root = { | ||
type: ktypes.typeOf(val) | ||
}; | ||
switch(root.type){ | ||
case "Null": | ||
root_value.value = null; | ||
root.value = null; | ||
break; | ||
case "Function": | ||
case "Action": | ||
root_value.type = "String"; | ||
root_value.value = ktypes.toString(val); | ||
root.type = "String"; | ||
root.value = ktypes.toString(val); | ||
break; | ||
@@ -92,3 +120,3 @@ case "Map": | ||
_.each(val, function(v, k){ | ||
db_ops.push({ | ||
ops.push({ | ||
type: "put", | ||
@@ -99,12 +127,14 @@ key: key_prefix.concat(["value", k]), | ||
}); | ||
// this `value` helps _.set in the toObj db dump set the right type | ||
root.value = root.type === "Array" ? [] : {}; | ||
break; | ||
default: | ||
root_value.value = val; | ||
root.value = val; | ||
} | ||
db_ops.push({ | ||
ops.push({ | ||
type: "put", | ||
key: key_prefix, | ||
value: root_value, | ||
value: root, | ||
}); | ||
ldb.batch(db_ops, callback); | ||
ldb.batch(ops, callback); | ||
}); | ||
@@ -142,4 +172,3 @@ }); | ||
} | ||
var is_array = data.type === "Array"; | ||
var value = is_array ? [] : {}; | ||
var value = data.type === "Array" ? [] : {}; | ||
dbRange(ldb, { | ||
@@ -149,7 +178,3 @@ prefix: key_prefix, | ||
if(data.key.length === (key_prefix.length + 2)){ | ||
if(is_array){ | ||
value.push(data.value); | ||
}else{ | ||
value[data.key[key_prefix.length + 1]] = data.value; | ||
} | ||
value[data.key[key_prefix.length + 1]] = data.value; | ||
} | ||
@@ -279,3 +304,3 @@ }, function(err){ | ||
toObj: function(callback){ | ||
var db_data = {}; | ||
var dump = {}; | ||
dbRange(ldb, {}, function(data){ | ||
@@ -285,5 +310,5 @@ if(!_.isArray(data.key)){ | ||
} | ||
_.set(db_data, data.key, data.value); | ||
_.set(dump, data.key, data.value); | ||
}, function(err){ | ||
callback(err, db_data); | ||
callback(err, dump); | ||
}); | ||
@@ -532,4 +557,8 @@ }, | ||
ldb.get(["pico", id], function(err, pico){ | ||
if((err && err.notFound) || !pico){ | ||
next(); | ||
return; | ||
} | ||
if(err) return next(err); | ||
if(pico && pico.parent_id){ | ||
if(pico.parent_id){ | ||
keyRange(["pico-children", pico.parent_id, id], function(key){ | ||
@@ -536,0 +565,0 @@ db_ops.push({type: "del", key: key}); |
@@ -946,1 +946,50 @@ var _ = require("lodash"); | ||
}); | ||
test("DB - persistent variables array/map", function(t){ | ||
var db = mkTestDB(); | ||
cocb.run(function*(){ | ||
var put = _.partial(cocb.wrap(db.putEntVar), "p", "r"); | ||
var get = _.partial(cocb.wrap(db.getEntVar), "p", "r"); | ||
var del = _.partial(cocb.wrap(db.delEntVar), "p", "r"); | ||
var toObj = cocb.wrap(db.toObj); | ||
var toJson = JSON.stringify; | ||
var tst = function*(name, type, value, msg){ | ||
var val = toJson(value); | ||
t.equals(toJson((yield toObj()).entvars.p.r[name]), "{\"type\":\""+type+"\",\"value\":"+val+"}", msg); | ||
t.equals(toJson(yield get(name)), val, msg); | ||
}; | ||
yield put("foo", [0], "aaa"); | ||
yield put("foo", [1], "bbb"); | ||
yield tst("foo", "Array", ["aaa", "bbb"], "`foo` is infered to be an array based on the int index"); | ||
// Now should change to a map b/c the key is not an int index | ||
yield put("foo", ["wat"], "da"); | ||
yield tst("foo", "Map", {0: "aaa", 1: "bbb", wat: "da"}, "`foo` is now a map"); | ||
// once a map, always a map | ||
yield del("foo", ["wat"]); | ||
yield tst("foo", "Map", {0: "aaa", 1: "bbb"}, "`foo` is still a map"); | ||
yield put("foo", [2], "ccc"); | ||
yield tst("foo", "Map", {0: "aaa", 1: "bbb", 2: "ccc"}, "`foo` is still a map"); | ||
// infered as map if it's a string | ||
yield put("bar", ["0"], "aaa"); | ||
yield tst("bar", "Map", {0: "aaa"}, "`bar` is a map since the first key was a string"); | ||
// infered as an Array b/c the key is a positive integer | ||
yield put("baz", [2], "ccc"); | ||
yield tst("baz", "Array", [null, null, "ccc"], "`baz` is an Array"); | ||
// now it's a map b/c the key is a string | ||
yield put("baz", ["1"], "bbb"); | ||
yield tst("baz", "Map", {1: "bbb", 2: "ccc"}, "`baz` is now a Map"); | ||
// initialzed as array should db dump as an array | ||
yield put("qux", null, ["aaa"]); | ||
yield tst("qux", "Array", ["aaa"], "`qux` is an Array"); | ||
}, t.end); | ||
}); |
@@ -166,2 +166,5 @@ var _ = require("lodash"); | ||
var fn = krl_stdlib_wrapped[fn_name]; | ||
if(fn===void 0){ | ||
throw new Error("Not an operator: " + fn_name); | ||
} | ||
return fn.apply(void 0, args); | ||
@@ -168,0 +171,0 @@ }; |
@@ -45,3 +45,7 @@ var _ = require("lodash"); | ||
core.db.getPicoIDByECI(args.eci, callback); | ||
core.db.getPicoIDByECI(args.eci, function(err, pico){ | ||
if(err && err.notFound) return callback(); | ||
if(err) return callback(err); | ||
callback(null, pico); | ||
}); | ||
}), | ||
@@ -57,5 +61,10 @@ | ||
core.db.assertPicoID(pico_id, function(err, pico_id){ | ||
if(err && err.notFound) return callback(); | ||
if(err) return callback(err); | ||
core.db.getParent(pico_id, callback); | ||
core.db.getParent(pico_id, function(err, parent_id){ | ||
if(err && err.notFound) return callback(); | ||
if(err) return callback(err); | ||
callback(null, parent_id); | ||
}); | ||
}); | ||
@@ -72,5 +81,10 @@ }), | ||
core.db.assertPicoID(pico_id, function(err, pico_id){ | ||
if(err && err.notFound) return callback(); | ||
if(err) return callback(err); | ||
core.db.getAdminECI(pico_id, callback); | ||
core.db.getAdminECI(pico_id, function(err, eci){ | ||
if(err && err.notFound) return callback(); | ||
if(err) return callback(err); | ||
callback(null, eci); | ||
}); | ||
}); | ||
@@ -87,5 +101,10 @@ }), | ||
core.db.assertPicoID(pico_id, function(err, pico_id){ | ||
if(err && err.notFound) return callback(); | ||
if(err) return callback(err); | ||
core.db.listChildren(pico_id, callback); | ||
core.db.listChildren(pico_id, function(err, children){ | ||
if(err && err.notFound) return callback(); | ||
if(err) return callback(err); | ||
callback(null, children); | ||
}); | ||
}); | ||
@@ -108,2 +127,3 @@ }), | ||
core.db.assertPicoID(pico_id, function(err, pico_id){ | ||
if(err && err.notFound) return callback(); | ||
if(err) return callback(err); | ||
@@ -123,5 +143,7 @@ | ||
core.db.assertPicoID(pico_id, function(err, pico_id){ | ||
if(err && err.notFound) return callback(); | ||
if(err) return callback(err); | ||
core.db.ridsOnPico(pico_id, function(err, rid_set){ | ||
if(err && err.notFound) return callback(); | ||
if(err) return callback(err); | ||
@@ -152,2 +174,3 @@ callback(null, _.keys(rid_set)); | ||
core.db.getEnabledRuleset(args.rid, function(err, data){ | ||
if(err && err.notFound) return callback(); | ||
if(err) return callback(err); | ||
@@ -194,2 +217,3 @@ var rid = data.rid; | ||
core.db.assertPicoID(pico_id, function(err, pico_id){ | ||
if(err && err.notFound) return callback(null, false); | ||
if(err) return callback(err); | ||
@@ -203,3 +227,7 @@ | ||
} | ||
core.db.removePico(pico_id, callback); | ||
core.db.removePico(pico_id, function(){ | ||
if(err && err.notFound) return callback(null, false); | ||
if(err) return callback(err); | ||
callback(null, true); | ||
}); | ||
}); | ||
@@ -224,3 +252,7 @@ }); | ||
} | ||
core.db.removePolicy(id, callback); | ||
core.db.removePolicy(id, function(err){ | ||
if(err && err.notFound) return callback(null, false); | ||
if(err) return callback(err); | ||
callback(null, true); | ||
}); | ||
}), | ||
@@ -281,3 +313,7 @@ | ||
core.db.removeChannel(args.eci, callback); | ||
core.db.removeChannel(args.eci, function(err){ | ||
if(err && err.notFound)return callback(null, false); | ||
if(err)return callback(err); | ||
callback(null, true); | ||
}); | ||
}), | ||
@@ -284,0 +320,0 @@ |
@@ -78,7 +78,3 @@ var _ = require("lodash"); | ||
); | ||
yield tstErr( | ||
get("quux"), | ||
"NotFoundError: ECI not found: quux", | ||
"eci not found" | ||
); | ||
t.equals(yield get("quux"), void 0, "eci not found"); | ||
}); | ||
@@ -316,8 +312,4 @@ | ||
); | ||
try{ | ||
yield descRID(ctx, {rid: "not.found"}); | ||
t.fail("should fail b/c not found"); | ||
}catch(err){ | ||
t.ok(err && err.notFound); | ||
} | ||
t.equals(yield descRID(ctx, {rid: "not.found"}), void 0); | ||
}); | ||
@@ -398,3 +390,4 @@ | ||
t.deepEquals(yield listChildren({pico_id: "id2"}, []), ["id6"]); | ||
t.equals(yield removePico({pico_id: "id6"}, []), void 0); | ||
t.equals(yield removePico({pico_id: "id6"}, []), true); | ||
t.equals(yield removePico({pico_id: "id6"}, []), false); | ||
strictDeepEquals(t, yield listChildren({}, ["id2"]), []); | ||
@@ -413,7 +406,7 @@ | ||
yield assertInvalidPicoID(getAdminECI , "id404", "NotFoundError: Pico not found: id404"); | ||
yield assertInvalidPicoID(getParent , "id404", "NotFoundError: Pico not found: id404"); | ||
yield assertInvalidPicoID(listChildren, "id404", "NotFoundError: Pico not found: id404"); | ||
t.equals(yield getAdminECI({}, ["id404"]), void 0); | ||
t.equals(yield getParent({pico_id: "id404"}, []), void 0); | ||
t.equals(yield listChildren({pico_id: "id404"}, []), void 0); | ||
yield assertInvalidPicoID(newPico , "id404", "NotFoundError: Pico not found: id404"); | ||
yield assertInvalidPicoID(removePico , "id404", "NotFoundError: Pico not found: id404"); | ||
t.equals(yield removePico({}, ["id404"]), false); | ||
@@ -476,5 +469,6 @@ yield tstErr( | ||
yield tstErr(removePolicy(), "TypeError: engine:removePolicy was given null instead of a policy_id string"); | ||
yield tstErr(removePolicy("id404"), "NotFoundError: Policy not found: id404"); | ||
t.equals(yield removePolicy("id404"), false); | ||
yield removePolicy(pFoo.id); | ||
t.equals(yield removePolicy(pFoo.id), true); | ||
t.equals(yield removePolicy(pFoo.id), false); | ||
t.deepEquals(yield listPolicies(), [pAdmin, pBar]); | ||
@@ -484,3 +478,3 @@ | ||
yield removePolicy(pBar.id); | ||
t.equals(yield removePolicy(pBar.id), true); | ||
t.deepEquals(yield listPolicies(), [pAdmin]); | ||
@@ -554,9 +548,6 @@ }); | ||
); | ||
yield tstErr( | ||
removeChannel({}, ["eci404"]), | ||
"NotFoundError: Key not found in database [channel,eci404]", | ||
"eci not found" | ||
); | ||
t.equals(yield removeChannel({}, ["eci404"]), false); | ||
t.equals(yield removeChannel({}, ["id2"]), void 0); | ||
t.equals(yield removeChannel({}, ["id2"]), true); | ||
t.equals(yield removeChannel({}, ["id2"]), false); | ||
t.deepEquals(yield listChannels({}, ["id0"]), [ | ||
@@ -581,3 +572,3 @@ mkChan("id0", "id1", "admin", "secret"), | ||
yield assertInvalidPicoID(newChannel , "id404", "NotFoundError: Pico not found: id404"); | ||
yield assertInvalidPicoID(listChannels, "id404", "NotFoundError: Pico not found: id404"); | ||
t.deepEquals(yield listChannels({}, ["id404"]), void 0); | ||
@@ -669,3 +660,3 @@ | ||
yield assertInvalidPicoID(uninstallRID, "id404", "NotFoundError: Pico not found: id404"); | ||
yield assertInvalidPicoID(listRIDs , "id404", "NotFoundError: Pico not found: id404"); | ||
t.deepEquals(yield listRIDs({pico_id: "id404"}, []), void 0); | ||
@@ -672,0 +663,0 @@ }); |
var _ = require("lodash"); | ||
var cocb = require("co-callback"); | ||
var ktypes = require("krl-stdlib/types"); | ||
var runKRL = require("./runKRL"); | ||
@@ -69,3 +70,19 @@ var runAction = require("./runAction"); | ||
/** | ||
* used by `foreach` in krl | ||
* Array's use index numbers, maps use key strings | ||
*/ | ||
function toPairs(v){ | ||
if(ktypes.isArray(v)){ | ||
var pairs = []; | ||
var i; | ||
for(i = 0; i < v.length; i++){ | ||
pairs.push([i, v[i]]); | ||
} | ||
return pairs; | ||
} | ||
return _.toPairs(v); | ||
} | ||
var runRuleBody = cocb.wrap(function*(core, rule_body_fns, scheduled){ | ||
@@ -93,3 +110,3 @@ | ||
yield runKRL(rule.body, ctx, runAction, _.toPairs); | ||
yield runKRL(rule.body, ctx, runAction, toPairs); | ||
}); | ||
@@ -96,0 +113,0 @@ |
Sorry, the diff of this file is too big to display
366666
9752