json-storage.js/json-tables/lib/index.js

177 lines
4.0 KiB
JavaScript
Raw Normal View History

2011-09-07 03:50:29 +00:00
(function () {
"use strict";
var Future = require('future')
, __id_ = 'id'
, nameToString = function () {
return this.name;
};
function RowType(table) {
var name = table.name,
columns = table.columns,
klass;
klass = function (id, arr) {
/*
// Extending Array doesn't work very well
var self = this;
arr.forEach(function (item, i) {
self[i] = item;
});
*/
if (!(__id_ in this)) {
this[__id_] = id;
}
this.arr = arr;
};
// TODO make more directive-like
// TODO create a delegates_to directive
klass.prototype.toString = table.toString || nameToString;
columns.forEach(function (column, i) {
klass.prototype.__defineGetter__(column, function () {
return this.arr[i];
//return this[i];
});
});
return klass;
}
function createIndexes(tables) {
Object.keys(tables).forEach(function (name) {
var table = tables[name],
index,
krow;
if (!table.columns) {
console.log("missing columns");
console.log(table);
}
table.klass = RowType(table);
index = table.indexed = {};
table.rows.forEach(function (row, z) {
// TODO no need to index
var krow = new table.klass(z, row);
//krow.id = z;
index[krow[__id_]] = krow;
table.rows[z] = krow;
});
});
}
function createRelationships(tables) {
Object.keys(tables).forEach(function (name) {
var table = tables[name],
relationships,
relHandlers = {};
// TODO create a delegates_to directive
relHandlers.belongs_to = function (relname) {
// TODO abstract name mutation
var relation = tables[relname + 's'],
relname_s = relname + '_id';
table.klass.prototype.__defineGetter__(relname, function () {
var fid = this[relname_s];
return relation.indexed[fid];
});
}
//relationships = table.relationships && table.relationships.belongs_to;
//relationships = relationships || [];
relationships = table.relationships || {};
Object.keys(relationships).forEach(function (relType) {
if (!relHandlers[relType]) {
console.log('relationship type "' + relType + '" is not supported');
return;
}
relationships[relType].forEach(relHandlers[relType]);
});
});
}
function createRelate(tables) {
var future = Future()
;
createIndexes(tables);
createRelationships(tables);
//testRelationships(tables);
//console.log(Object.keys(data));
future.fulfill(null, tables);
return future.passable();
}
2011-09-07 07:26:12 +00:00
var Future = require('future')
2011-09-07 03:50:29 +00:00
, Join = require('Join')
;
function createGet(pathname, tables) {
var future = Future()
, join = Join()
, request = require('ahr2')
, db = {}
, errs = []
;
tables.forEach(function (tablename) {
var resource = pathname + '/' + tablename + ".json"
, req = request.get(resource)
;
req.when(function (err, xhr, data) {
if (err) {
console.log('error tables-get');
console.log(err);
console.log(err.message);
return;
}
if (global.Buffer && data instanceof global.Buffer) {
data = data.toString();
}
// TODO need to refactor AHR and fix JSON / text handling
try {
data = JSON.parse(data.toString());
} catch (e) {
// ignore, it was probably already parsed
}
// follow convention
tablename = tablename.replace('-','_');
db[tablename] = data;
});
join.add(req);
});
join.when(function () {
// TODO add timeout as error
if (0 == errs.length) {
errs = null;
}
future.fulfill(errs, db);
});
return future.passable();
}
module.exports = {
get: createGet
, relate: createRelate
};
}());