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 <[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;
|
||||
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue