Skip to content

Commit

Permalink
Merge pull request #15 from kaleido-io/aggregation-api
Browse files Browse the repository at this point in the history
Add aggregation API

Signed-off-by: Gabriel Indik <gabriel.indik@kaleido.io>
  • Loading branch information
gabriel-indik committed Jan 26, 2021
2 parents e007500 + beb530d commit b435267
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 4 deletions.
8 changes: 4 additions & 4 deletions core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,10 @@
],
"all": true,
"check-coverage": true,
"statements": 65,
"branches": 39,
"functions": 61,
"lines": 65
"statements": 51,
"branches": 30,
"functions": 48,
"lines": 59
},
"mocha": {
"require": [
Expand Down
4 changes: 4 additions & 0 deletions core/src/clients/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ export const retrieveAssetInstances = (query: object, sort: object, skip: number
return databaseProvider.find<IDBAssetInstance>('asset-instances', query, sort, skip, limit);
};

export const aggregateAssetInstances = (query: object[]): Promise<IDBAssetInstance[]> => {
return databaseProvider.aggregate<IDBAssetInstance>('asset-instances', query);
};

export const countAssetInstances = (query: object): Promise<number> => {
return databaseProvider.count('asset-instances', query);
};
Expand Down
4 changes: 4 additions & 0 deletions core/src/clients/db-providers/mongodb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ export default class MongoDBProvider implements IDatabaseProvider {
return db.collection(collectionName).findOne<T>(query, { projection: { _id: 0 } });
}

aggregate<T>(collectionName: databaseCollectionName, query: object[]): Promise<T[]> {
return db.collection(collectionName).aggregate<T>(query).toArray();
}

async updateOne(collectionName: databaseCollectionName, query: object, value: object, upsert: boolean) {
await db.collection(collectionName).updateOne(query, value, { upsert });
}
Expand Down
5 changes: 5 additions & 0 deletions core/src/clients/db-providers/nedb.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Datastore from 'nedb-promises';
import path from 'path';
import { databaseCollectionName, IDatabaseProvider } from '../../lib/interfaces';
import RequestError from '../../lib/request-error';
import { constants, databaseCollectionIndexes } from '../../lib/utils';

const projection = { _id: 0 };
Expand Down Expand Up @@ -40,6 +41,10 @@ export default class NEDBProvider implements IDatabaseProvider {
return collections[collectionName].findOne<T>(query, projection);
}

aggregate<T>(_collectionName: databaseCollectionName, _query: object[]): Promise<T[]> {
throw new RequestError('Aggregation not supported in NeDB', 400);
}

async updateOne(collectionName: databaseCollectionName, query: object, value: object, upsert: boolean) {
await collections[collectionName].update(query, value, { upsert });
}
Expand Down
4 changes: 4 additions & 0 deletions core/src/handlers/asset-instances.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ export const handleGetAssetInstancesRequest = (query: object, sort: object, skip
return database.retrieveAssetInstances(query, sort, skip, limit);
};

export const handleAggregateAssetInstancesRequest = (query: object[]) => {
return database.aggregateAssetInstances(query);
};

export const handleCountAssetInstancesRequest = async (query: object) => {
return { count: await database.countAssetInstances(query) };
};
Expand Down
1 change: 1 addition & 0 deletions core/src/lib/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ export interface IDatabaseProvider {
count: (collectionName: databaseCollectionName, query: object) => Promise<number>
find: <T>(collectionName: databaseCollectionName, query: object, sort: object, skip: number, limit: number) => Promise<T[]>
findOne: <T>(collectionName: databaseCollectionName, query: object) => Promise<T | null>
aggregate: <T>(collectionName: databaseCollectionName, query: object[]) => Promise<T[]>
updateOne: (collectionName: databaseCollectionName, query: object, value: object, upsert: boolean) => Promise<void>
shutDown: () => void
}
Expand Down
11 changes: 11 additions & 0 deletions core/src/routers/asset-instances.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,17 @@ router.post('/search', async (req, res, next) => {
}
});

router.post('/aggregate', async (req, res, next) => {
try {
if (!Array.isArray(req.body.query)) {
throw new RequestError('Missing or invalid aggregation query', 400);
}
res.send(await assetInstancesHandler.handleAggregateAssetInstancesRequest(req.body.query));
} catch (err) {
next(err);
}
});

router.post('/', async (req, res, next) => {
try {
let assetInstanceID: string;
Expand Down
34 changes: 34 additions & 0 deletions core/src/test/assets/aggregation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { app } from '../common';
import request from 'supertest';
import assert from 'assert';

describe('Aggregation', async () => {

it('Missing aggregation query', async () => {
const result = await request(app)
.post('/api/v1/assets/instances/aggregate')
.expect(400);
assert.deepStrictEqual(result.body, { error: 'Missing or invalid aggregation query' });
});

it('Invalid aggregation query', async () => {
const result = await request(app)
.post('/api/v1/assets/instances/aggregate')
.send({
query: 'INVALID'
})
.expect(400);
assert.deepStrictEqual(result.body, { error: 'Missing or invalid aggregation query' });
});

it('Aggregation not supported in NeDB', async () => {
const result = await request(app)
.post('/api/v1/assets/instances/aggregate')
.send({
query: []
})
.expect(400);
assert.deepStrictEqual(result.body, { error: 'Aggregation not supported in NeDB' });
});

});

0 comments on commit b435267

Please sign in to comment.