add cache option to Ox.api

This commit is contained in:
rolux 2012-04-03 15:09:39 +02:00
parent 4613c96a01
commit 1278e39759

View file

@ -7,6 +7,7 @@ Ox.api <f> Turns an array into a list API
(items, options) -> <f> List API
items <[o]> An array of objects (key/value stores)
options <o> Options object
cache <b|false> If true, cache results
enums <o> Enumerables, for example <code>{size: ['S', 'M', 'L', 'XL']}</code>
geo <b|false> If true, return combined area with totals
sort <[o]|[s]> Default sort, for example <code> ['+name', '-age']
@ -116,11 +117,107 @@ Ox.api <f> Turns an array into a list API
Ox.api = function(items, options) {
var api = {
cache: options.cache,
enums: options.enums ? parseEnums(options.enums) : {},
geo: options.geo,
sort: options.sort || [],
sums: options.sums || [],
unique: options.unique || 'id'
},
fn = function(options, callback) {
var data,
result = {data: {}, status: {code: 200, text: 'ok'}},
sort = {};
options = options || {};
if (options.query) {
// find
options.query.conditions = parseConditions(options.query.conditions);
result.data.items = items.filter(function(item) {
return testQuery(item, options.query);
});
} else {
result.data.items = Ox.clone(items);
}
if (options.sort && result.data.items.length > 1) {
// sort
options.sort = parseSort(Ox.merge(Ox.clone(options.sort), api.sort));
options.sort.forEach(function(v) {
var key = v.key;
if (api.enums[key]) {
sort[key] = function(value) {
return api.enums[key].indexOf(value.toLowerCase());
};
} /*else if (Ox.isArray(items[0][key])) {
sort[key] = function(value) {
return value.join(', ');
};
}*/
});
result.data.items = Ox.sortBy(result.data.items, options.sort, sort);
}
if (options.positions) {
// return positions
data = {positions: {}};
options.positions.forEach(function(id) {
data.positions[id] = Ox.getIndex(result.data.items, api.unique, id)
});
result.data = data;
} else if (!options.keys) {
// return totals
data = {};
api.sums.forEach(function(key) {
data[key] = Ox.sum(result.data.items.map(function(item) {
return item[key];
}));
})
data.items = result.data.items.length;
if (api.geo) {
/*
data.area = Ox.joinAreas(result.data.items.map(function(item) {
return {
sw: {lat: item.south, lng: item.west},
ne: {lat: item.north, lng: item.east}
};
}));
data.area = {
south: data.area.sw.lat,
west: data.area.sw.lng,
north: data.area.ne.lat,
east: data.area.ne.lng
};
*/
data.area = {
south: Ox.MIN_LATITUDE,
west: -180,
north: Ox.MAX_LATITUDE,
east: 180
}
}
result.data = data;
} else {
// return items
if (!Ox.isEmpty(options.keys)) {
// filter keys
if (options.keys.indexOf(api.unique) == -1) {
options.keys.push(api.unique);
}
result.data.items = result.data.items.map(function(item) {
var ret = {};
options.keys.forEach(function(key) {
ret[key] = item[key];
});
return ret;
});
}
if (options.range) {
// apply range
result.data.items = Ox.sub(
result.data.items, options.range[0], options.range[1]
);
}
}
callback && callback(result);
return result;
};
function parseEnums(enums) {
@ -223,93 +320,7 @@ Ox.api = function(items, options) {
return match;
}
return function(options, callback) {
var data,
result = {data: {}, status: {code: 200, text: 'ok'}},
sort = {};
options = options || {};
if (options.query) {
// find
options.query.conditions = parseConditions(options.query.conditions);
result.data.items = items.filter(function(item) {
return testQuery(item, options.query);
});
} else {
result.data.items = Ox.clone(items);
}
if (options.sort && result.data.items.length > 1) {
// sort
options.sort = parseSort(Ox.merge(options.sort, api.sort));
options.sort.forEach(function(v) {
var key = v.key;
if (api.enums[key]) {
sort[key] = function(value) {
return api.enums[key].indexOf(value.toLowerCase());
};
} /*else if (Ox.isArray(items[0][key])) {
sort[key] = function(value) {
return value.join(', ');
};
}*/
});
result.data.items = Ox.sortBy(result.data.items, options.sort, sort);
}
if (options.positions) {
// return positions
data = {positions: {}};
options.positions.forEach(function(id) {
data.positions[id] = Ox.getIndex(result.data.items, api.unique, id)
});
result.data = data;
} else if (!options.keys) {
// return totals
data = {};
api.sums.forEach(function(key) {
data[key] = Ox.sum(result.data.items.map(function(item) {
return item[key];
}));
})
data.items = result.data.items.length;
if (api.geo) {
data.area = Ox.joinAreas(result.data.items.map(function(item) {
return {
sw: {lat: item.south, lng: item.west},
ne: {lat: item.north, lng: item.east}
};
}));
data.area = {
south: data.area.sw.lat,
west: data.area.sw.lng,
north: data.area.ne.lat,
east: data.area.ne.lng
};
}
result.data = data;
} else {
// return items
if (!Ox.isEmpty(options.keys)) {
// filter keys
if (options.keys.indexOf(api.unique) == -1) {
options.keys.push(api.unique);
}
result.data.items = result.data.items.map(function(item) {
var ret = {};
options.keys.forEach(function(key) {
ret[key] = item[key];
});
return ret;
});
}
if (options.range) {
// apply range
result.data.items = Ox.sub(
result.data.items, options.range[0], options.range[1]
);
}
}
callback && callback(result);
return result;
};
return api.cache ? Ox.cache(fn, {async: true}) : fn;
};