Add functions for DB access

This commit is contained in:
Zaid Abdulla committed 2018-12-26 00:22:07 -08:00
1 parent 327cb78f1a
commit 12cdc8a6f1
6 files changed
+114 -26

No files matched your search

+5
View File
@@ -266,6 +266,11 @@ table.table {
& td {
margin: 0;
padding: 0.2em 0.5em;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 400px;
}
& tfoot td > a {
+1
View File
@@ -1,6 +1,7 @@
{
"server.port": 3000,
"server.nbi": "http://127.0.0.1:7557/",
"server.mongodbConnectionUrl": "mongodb://127.0.0.1:27017",
"server.jwtSecret": "jwtSecret",
"auth.simple.users.admin.password": "admin",
"auth.simple.users.admin.roles": "admin",
+1
View File
@@ -19,6 +19,7 @@
"koa-router": "^7.4.0",
"koa-static": "^4.0.2",
"mithril": "^1.1.6",
"mongodb": "^3.0.10",
"parsimmon": "^1.7.2"
},
"devDependencies": {
+7 -6
View File
@@ -24,20 +24,20 @@ function unpackTimestamps(filter) {
});
}
function filterToQuery(filter, negate = false, res = {}) {
function filterToMongoQuery(filter, negate = false, res = {}) {
const op = filter[0];
if ((!negate && op === "AND") || (negate && op === "OR")) {
res["$and"] = res["$and"] || [];
for (let i = 1; i < filter.length; ++i)
res["$and"].push(filterToQuery(filter[i], negate));
res["$and"].push(filterToMongoQuery(filter[i], negate));
} else if ((!negate && op === "OR") || (negate && op === "AND")) {
res["$or"] = res["$or"] || [];
for (let i = 1; i < filter.length; ++i)
res["$or"].push(filterToQuery(filter[i], negate));
res["$or"].push(filterToMongoQuery(filter[i], negate));
} else if (op === "NOT") {
filterToQuery(filter[1], !negate, res);
filterToMongoQuery(filter[1], !negate, res);
} else if (op === "=") {
let p = (res[filter[1]] = res[filter[1]] || {});
if (negate) p["$ne"] = filter[2];
@@ -84,7 +84,7 @@ function count(resource, filter, limit) {
filter = filter.evaluateExpressions();
let ast = unpackTimestamps(filter.ast);
let q = filterToQuery(ast);
let q = filterToMongoQuery(ast);
if (resource === "devices") q = device.transposeQuery(q);
qs.query = JSON.stringify(q);
}
@@ -121,7 +121,7 @@ function query(resource, filter, limit, skip, projection, callback) {
filter = filter.evaluateExpressions();
let ast = unpackTimestamps(filter.ast);
let q = filterToQuery(ast);
let q = filterToMongoQuery(ast);
if (resource === "devices") q = device.transposeQuery(q);
qs.query = JSON.stringify(q);
@@ -372,3 +372,4 @@ exports.count = count;
exports.postTasks = postTasks;
exports.deleteResource = deleteResource;
exports.updateTags = updateTags;
exports.filterToMongoQuery = filterToMongoQuery;
+33 -20
View File
@@ -2,22 +2,26 @@
const Router = require("koa-router");
const db = require("./db");
const apiFunctions = require("./api-functions");
const Filter = require("../common/filter");
const router = new Router();
const RESOURCE_DELETE = 1 << 0;
const RESOURCE_DB = 1 << 1;
const resources = {
devices: true,
presets: true,
provisions: true,
files: true,
virtual_parameters: true,
faults: true,
tasks: false
devices: 0 | RESOURCE_DELETE,
presets: 0 | RESOURCE_DELETE,
provisions: 0 | RESOURCE_DELETE,
files: 0 | RESOURCE_DELETE,
virtual_parameters: 0 | RESOURCE_DELETE,
faults: 0 | RESOURCE_DELETE,
tasks: 0
};
for (let [resource, update] of Object.entries(resources)) {
for (let [resource, flags] of Object.entries(resources)) {
router.head(`/${resource}`, async (ctx, next) => {
let filter, limit;
if (ctx.request.query.filter) filter = new Filter(ctx.request.query.filter);
@@ -31,16 +35,20 @@ for (let [resource, update] of Object.entries(resources)) {
filter = f.and(filter);
}
let count = await apiFunctions.count(resource, filter, limit);
let count;
if (flags & RESOURCE_DB) count = await db.count(resource, filter, limit);
else count = await apiFunctions.count(resource, filter, limit);
ctx.set("X-Total-Count", count);
ctx.body = "";
});
router.get(`/${resource}`, async (ctx, next) => {
let filter, limit, skip;
let filter, limit, skip, projection;
if (ctx.request.query.filter) filter = new Filter(ctx.request.query.filter);
if (ctx.request.query.limit) limit = +ctx.request.query.limit;
if (ctx.request.query.skip) skip = +ctx.request.query.skip;
if (ctx.request.query.projection) projection = ctx.request.query.projection;
if (!ctx.state.authorizer.hasAccess(resource, 2)) return next();
@@ -50,20 +58,23 @@ for (let [resource, update] of Object.entries(resources)) {
filter = f.and(filter);
}
ctx.body = await apiFunctions.query(
resource,
filter,
limit,
skip,
ctx.request.query.projection
);
let res;
if (flags & RESOURCE_DB)
res = await db.query(resource, filter, limit, skip);
else
res = await apiFunctions.query(resource, filter, limit, skip, projection);
ctx.body = res;
});
router.head(`/${resource}/:id`, async (ctx, next) => {
let filter = new Filter(`DeviceID.ID = "${ctx.params.id}"`);
if (!ctx.state.authorizer.hasAccess(resource, 2)) return next();
let res = await apiFunctions.query(resource, filter);
let res;
if (flags & RESOURCE_DB) res = await db.query(resource, filter);
else res = await apiFunctions.query(resource, filter);
if (!res.length) return next();
ctx.body = "";
});
@@ -72,13 +83,15 @@ for (let [resource, update] of Object.entries(resources)) {
let filter = new Filter(`DeviceID.ID = "${ctx.params.id}"`);
if (!ctx.state.authorizer.hasAccess(resource, 2)) return next();
let res = await apiFunctions.query(resource, filter);
let res;
if (flags & RESOURCE_DB) res = await db.query(resource, filter);
else res = await apiFunctions.query(resource, filter);
if (!res.length) return next();
ctx.body = res[0];
});
// TODO add PUT, PATCH routes
if (update)
if (flags & RESOURCE_DELETE && !(flags & RESOURCE_DB))
router.delete(`/${resource}/:id`, async (ctx, next) => {
const authorizer = ctx.state.authorizer;
let filter = new Filter(`DeviceID.ID = "${ctx.params.id}"`);
+67
View File
@@ -0,0 +1,67 @@
"use strict";
const MongoClient = require("mongodb").MongoClient;
const config = require("./config");
const apiFunctions = require("./api-functions");
let _client = null;
function getClient() {
if (_client) return Promise.resolve(_client);
return new Promise((resolve, reject) => {
const CONNECTION_URL = config.get("server.mongodbConnectionUrl");
MongoClient.connect(CONNECTION_URL, (err, client) => {
if (err) return reject(err);
resolve((_client = client.db("genieacs-ui")));
});
});
}
function query(resource, filter, limit, skip, callback) {
let q;
if (filter && filter.ast) q = apiFunctions.filterToMongoQuery(filter.ast);
return new Promise((resolve, reject) => {
getClient().then(client => {
const collection = client.collection(resource);
if (!callback)
collection
.find(q)
.skip(skip || 0)
.limit(limit || 0)
.toArray((err, docs) => {
if (err) return reject(err);
return resolve(docs);
});
else
collection.find(q).forEach(
doc => {
callback(doc);
},
err => {
if (err) reject(err);
else resolve();
}
);
});
});
}
function count(resource, filter) {
let q;
if (filter && filter.ast) q = apiFunctions.filterToMongoQuery(filter.ast);
return new Promise((resolve, reject) => {
getClient().then(client => {
const collection = client.collection(resource);
collection.find(q).count((err, c) => {
if (err) reject(err);
else resolve(c);
});
});
});
}
exports.query = query;
exports.count = count;