UNPKG

spincycle

Version:

A reactive message router and object manager that lets clients subscribe to object property changes on the server

514 lines (473 loc) 15.2 kB
// Generated by CoffeeScript 1.12.6 (function() { var Couch, DB, LRU, OStore, ResolveModule, Rethink, all, debug, defer, resolver, uuid, indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; defer = require('node-promise').defer; all = require('node-promise').all; uuid = require('node-uuid'); LRU = require('lru-cache'); OStore = require('./OStore'); Couch = require('./CouchPersistence'); Rethink = require('./RethinkPersistence'); ResolveModule = require('./ResolveModule'); resolver = new ResolveModule(); debug = process.env["DEBUG"]; DB = (function() { function DB() {} DB.dburl = 'localhost'; DB.lru = LRU(); DB.lrudiff = LRU(); DB.dbname = ''; DB.onUpdated = function(record) { if (record && record.type && record.id) { return resolver.createObjectFrom(record).then(function(ooo) { return OStore.updateObj(ooo); }); } }; DB.getDataStore = function(_name) { var name, q; name = _name || DB.dbname; DB.dbname = name; q = defer(); if (!DB.DataStore) { if (!name) { DB.DataStore = new Rethink(DB.dburl, DB); } else if (name === 'couchdb') { DB.DataStore = new Couch(DB.dburl); } else if (name === 'rethinkdb') { DB.DataStore = new Rethink(DB.dburl, DB); } DB.DataStore.connect().then(function(ds) { return DB.getOrCreateObjectByRecord({ id: 11122333444, type: 'SpinMeta' }).then(function(meta) { DB.meta = meta; meta.serialize(); DB.DataStore = ds; return q.resolve(ds); }); }); } else { q.resolve(DB.DataStore); } return q; }; DB.createDatabases = function(dblist) { var q; q = defer(); console.log('*** createDatabases called for list of dbs...'); console.dir(dblist); DB.getDataStore().then(function(store) { var promises; console.log('DB.createDatabases got back store'); promises = []; dblist.forEach(function(dbname) { var db; console.log('attempting to get table for ' + dbname); if (!(indexOf.call(DB.meta.knownModels, dbname) >= 0)) { DB.meta.knownModels.push(dbname); DB.meta.serialize(); } db = store.getDbFor(dbname); return promises.push(db); }); return all(promises).then(function(results) { console.log('*DB.createDatabases all good'); dblist.forEach(function(dbname2) { return DB.extendSchemaIfNeeded(DB.DataStore, dbname2); }); return q.resolve(results); }); }); return q; }; DB.extendSchemaIfNeeded = function(db, _dbname) { var dbname, proto, q; dbname = _dbname; q = defer(); proto = ResolveModule.modulecache[dbname]; if (!(proto && proto.model)) { console.log('found undefined prototype for ' + dbname); q.resolve(); } else { db.all(dbname, { skip: 0, limit: 10 }, function(res) { var k, lookup, missing, o, v; if (res.length > 0) { o = res[res.length - 1]; missing = []; lookup = { createdAt: true, modifiedAt: true, createdBy: true }; for (k in o) { v = o[k]; lookup[k] = k; } proto.model.forEach(function(property) { if (!lookup[property.name]) { return missing.push(property); } }); if (missing.length > 0) { return DB.count(dbname).then(function(modelcount) { var count, cursor, getThese, loopThrough; count = modelcount; cursor = 0; console.log('adding ' + missing.length + ' missing properties to ' + modelcount + ' existing objects'); getThese = function(where) { var r, start; console.log('getThese called with skip ' + where); r = defer(); start = Date.now(); db.all(dbname, { skip: where, limit: 1000 }, function(objs) { var cnt; console.log('getThese got ' + objs.length + ' objs'); cnt = objs.length * missing.length; return objs.forEach(function(ro) { return missing.forEach(function(mprop) { if (!mprop["default"]) { if (mprop.array) { mprop["default"] = []; } else if (mprop.hashtable) { mprop["default"] = {}; } else if (mprop.type) { mprop["default"] = ''; } } if (ro) { return DB.extend(ro.type, ro.id, mprop.name, mprop["default"]).then(function(o) { var diff, end; DB.lru.set(ro.id, ro); if (--cnt === 0) { end = Date.now(); diff = parseInt((end - start) / 1000); console.log('extendSchemaIfNeeded done for ' + res.length + ' objects. runtime = ' + diff + ' seconds'); return r.resolve(); } }); } }); }); }); return r; }; loopThrough = function() { return getThese(cursor).then(function() { return setTimeout(function() { if (cursor < count) { cursor += 1000; return loopThrough(); } }, 100); }); }; return loopThrough(); }); } else { return q.resolve(); } } }); } return q; }; DB.extend = function(type, id, field, def) { return DB.getDataStore().then(function(store) { return store.extend(type, id, field, def); }); }; DB.getFromStoreOrDB = function(type, id) { var q; q = defer(); OStore.getObject(id, type).then(function(oo) { if (oo) { return q.resolve(oo); } else { return DB.get(type, [id]).then(function(records) { var record; if (records && records[0]) { record = records[0]; return resolver.createObjectFrom(record).then(function(ooo) { return q.resolve(ooo); }); } else { return q.resolve(void 0); } }); } }); return q; }; DB.getOrCreateObjectByRecord = function(record) { var q; q = defer(); if (debug) { console.log('getOrCreateObjectByRecord called for type ' + record.type + ' and id ' + record.id); } OStore.getObject(record.id, record.type).then(function(oo) { if (debug) { console.log('DB.getOrCreateObjectByRecord OStore returns ' + oo); } if (oo) { return q.resolve(oo); } else { return DB.get(record.type, [record.id]).then(function(res) { if (debug) { console.log('DB.getOrCreateObjectByRecord DB load returns ' + res); } if (res && res[0]) { if (debug) { console.log('DB.getOrCreateObjectByRecord found existing record in DB *'); } record = res[0]; } return resolver.createObjectFrom(record).then(function(ooo) { if (debug) { console.log('DB.getOrCreateObjectByRecord createFromRecord returns ' + ooo); } return q.resolve(ooo); }); }); } }); return q; }; DB.byProviderId = function(type, pid) { var q; q = defer(); if (pid) { DB.getDataStore().then(function(store) { return store.byProviderId(type, pid).then(function(res) { return q.resolve(res); }); }); } else { q.resolve(void 0); } return q; }; DB.all = function(type, query, cb) { return DB.getDataStore().then(function(store) { if (store.all) { return store.all(type, query, cb); } else { console.log('DB.all: All not implemented in underlying persistence logic'); return cb([]); } }); }; DB.count = function(type) { var q; q = defer(); DB.getDataStore().then(function(store) { return store.count(type).then(function(value) { return q.resolve(value); }); }); return q; }; DB.find = function(type, property, value) { var q; q = defer(); DB.getDataStore().then(function(store) { return store.find(type, property, value).then(function(result) { if (!result) { } else { if (!typeof result.id === 'string') { console.log('----------***************** DB.find error: trying to cache found result but id is not a string!!!'); console.dir(result); } else { if (result.length) { result.forEach(function(re) { return DB.lru.set(re.id, re); }); } else { DB.lru.set(result.id, result); } } } return q.resolve(result); }); }); return q; }; DB.findMany = function(type, property, value) { var q; q = defer(); DB.getDataStore().then(function(store) { return store.findMany(type, property, value).then(function(results) { if (debug) { console.log('DB.findMany results are..'); } if (debug) { console.dir(results); } if (!results || !results.length || results.length === 0) { return q.resolve([]); } else { results.forEach(function(result) { return DB.lru.set(result.id, result); }); return q.resolve(results); } }); }); return q; }; DB.findQuery = function(type, query) { var q; q = defer(); DB.getDataStore().then(function(store) { return store.findQuery(type, query).then(function(results) { if (results && results.length && results.length > 0) { if (debug) { console.log(' DB.findQuery got back '); } if (debug) { console.dir(results); } results.forEach(function(result) { if (result) { return DB.lru.set(result.id, result); } }); } return q.resolve(results); }); }); return q; }; DB.filter = function(type, query) { var q; q = defer(); DB.getDataStore().then(function(store) { return store.filter(type, query).then(function(results) { if (results && results.length && results.length > 0) { if (debug) { console.log(' DB.filter got back '); } if (debug) { console.dir(results); } results.forEach(function(result) { if (result) { return DB.lru.set(result.id, result); } }); } return q.resolve(results); }); }); return q; }; DB.search = function(type, property, value) { var q; q = defer(); DB.getDataStore().then(function(store) { return store.search(type, property, value).then(function(results) { if (!results) { if (debug) { console.log('DB.search type ' + type + ', property ' + property + ', value ' + value + ' got back ' + results); } } else { results.forEach(function(result) { return DB.lru.set(result.id, result); }); } return q.resolve(results); }); }); return q; }; DB.get = function(type, ids) { var id, q, rv, toarr; if (!type || !ids) { console.log('********************************* DB.get called with null type or id ***********************'); console.dir(arguments); xyzzy; } toarr = function(x) { if (!Array.isArray(x)) { x = [x]; } return x; }; if (!ids.length) { ids = [ids]; } q = defer(); id = ids[0]; if (!id) { console.log('DB.get for type ' + type + ' was served an empty id!'); q.resolve(); } else if (typeof id === 'object') { console.log('DB.get was served an object instead of an id!!!'); console.dir(id); xyzzy; } else { rv = DB.lru.get(id); if (rv) { if (debug) { console.log('DB found ' + id + ' in lru: ' + rv); } if (debug) { console.dir(rv); } q.resolve(toarr(rv)); } else { DB.getDataStore().then(function(store) { return store.get(type, id, function(result) { if (!result) { } else { result = toarr(result); DB.lru.set(id, result); if (debug) { console.log('DB.get resolving ' + result); } if (debug) { console.dir(result); } } return q.resolve(result); }); }); } } return q; }; DB.set = function(type, obj, cb) { if (obj) { DB.lru.set(obj.id, obj); return DB.getDataStore().then(function(store) { return store.set(type, obj, function(res) { return cb(res); }); }); } else { return cb(); } }; DB.remove = function(obj, cb) { DB.lru.del(obj.id); return DB.getDataStore().then(function(store) { return store.remove(obj.type, obj, function(res) { if (cb) { return cb(res); } }); }); }; return DB; })(); module.exports = DB; }).call(this); //# sourceMappingURL=DB.js.map