add cache option to Ox.api
This commit is contained in:
parent
4613c96a01
commit
1278e39759
1 changed files with 104 additions and 93 deletions
|
@ -7,6 +7,7 @@ Ox.api <f> Turns an array into a list API
|
||||||
(items, options) -> <f> List API
|
(items, options) -> <f> List API
|
||||||
items <[o]> An array of objects (key/value stores)
|
items <[o]> An array of objects (key/value stores)
|
||||||
options <o> Options object
|
options <o> Options object
|
||||||
|
cache <b|false> If true, cache results
|
||||||
enums <o> Enumerables, for example <code>{size: ['S', 'M', 'L', 'XL']}</code>
|
enums <o> Enumerables, for example <code>{size: ['S', 'M', 'L', 'XL']}</code>
|
||||||
geo <b|false> If true, return combined area with totals
|
geo <b|false> If true, return combined area with totals
|
||||||
sort <[o]|[s]> Default sort, for example <code> ['+name', '-age']
|
sort <[o]|[s]> Default sort, for example <code> ['+name', '-age']
|
||||||
|
@ -116,12 +117,108 @@ Ox.api <f> Turns an array into a list API
|
||||||
Ox.api = function(items, options) {
|
Ox.api = function(items, options) {
|
||||||
|
|
||||||
var api = {
|
var api = {
|
||||||
enums: options.enums ? parseEnums(options.enums) : {},
|
cache: options.cache,
|
||||||
geo: options.geo,
|
enums: options.enums ? parseEnums(options.enums) : {},
|
||||||
sort: options.sort || [],
|
geo: options.geo,
|
||||||
sums: options.sums || [],
|
sort: options.sort || [],
|
||||||
unique: options.unique || 'id'
|
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) {
|
function parseEnums(enums) {
|
||||||
// make enumerable strings lowercase
|
// make enumerable strings lowercase
|
||||||
|
@ -223,93 +320,7 @@ Ox.api = function(items, options) {
|
||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
|
|
||||||
return function(options, callback) {
|
return api.cache ? Ox.cache(fn, {async: true}) : fn;
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue