You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

122 lines
4.2 KiB

import { DbQueryWrapper, QueryExecutionError } from './basedb';
import { Collection, FilterQuery, ObjectID } from 'mongodb';
import { wrapIdToMongoDbQuery, wrapIdsToMongoDbQuery, isEmptyArray } from './utils';
import * as _ from 'lodash';
export class MongoDbQueryWrapper implements DbQueryWrapper {
async dbInsertOne(collection: Collection, doc: any): Promise<string> {
// http://mongodb.github.io/node-mongodb-native/3.1/api/Collection.html#insertOne
// TODO: move to utils
if(doc._id !== undefined) {
doc._id = new ObjectID(doc._id);
}
const newDoc = await collection.insertOne(doc);
return newDoc.insertedId.toString();
}
async dbInsertMany(collection: Collection, docs: any[]): Promise<string[]> {
// http://mongodb.github.io/node-mongodb-native/3.1/api/Collection.html#insertMany
if(docs.length === 0) {
return [];
}
// TODO: move to utils
docs.forEach(doc => {
if(doc._id !== undefined) {
doc._id = new ObjectID(doc._id);
}
});
const newDocs = await collection.insertMany(docs);
return _.map(newDocs.insertedIds, (id: ObjectID) => id.toString());
}
async dbUpdateOne(collection: Collection, query: FilterQuery<string | object>, updateQuery: any): Promise<void> {
// http://mongodb.github.io/node-mongodb-native/3.1/api/Collection.html#updateOne
// "_id" is immutable. Mongo throws an exception if updateQuery contains "_id" field.
if(updateQuery._id !== undefined) {
delete updateQuery._id;
}
let mongodbUpdateQuery = { $set: updateQuery }
query = wrapIdToMongoDbQuery(query);
await collection.updateOne(
query,
mongodbUpdateQuery
);
}
async dbUpdateMany(collection: Collection, query: string[] | object, updateQuery: any): Promise<void> {
// http://mongodb.github.io/node-mongodb-native/3.1/api/Collection.html#updateMany
if(isEmptyArray(query)) {
return;
}
// "_id" is immutable. Mongo throws an exception if updateQuery contains "_id" field.
if(updateQuery._id !== undefined) {
delete updateQuery._id;
}
let mongodbUpdateQuery = { $set: updateQuery };
query = wrapIdsToMongoDbQuery(query);
await collection.updateMany(
query,
mongodbUpdateQuery
);
}
async dbFindOne(collection: Collection, query: FilterQuery<string | object>): Promise<any> {
// http://mongodb.github.io/node-mongodb-native/3.1/api/Collection.html#findOne
query = wrapIdToMongoDbQuery(query);
let doc = await collection.findOne(query);
// TODO: move to utils
if(doc !== null) {
doc._id = doc._id.toString();
}
return doc;
}
async dbFindMany(collection: Collection, query: string[] | object, sortQuery: object = {}): Promise<any[]> {
// http://mongodb.github.io/node-mongodb-native/3.1/api/Collection.html#find
if(isEmptyArray(query)) {
return [];
}
query = wrapIdsToMongoDbQuery(query);
try {
const docs = await collection.find(query).sort(sortQuery).toArray();
docs.forEach(doc => {
if (doc !== null) {
doc._id = doc._id.toString();
}
});
return docs;
} catch(error) {
console.error(`Can't get query result for query ${JSON.stringify(query)} in collection: ${collection.namespace}`);
throw new QueryExecutionError(`MongoDB query error: ${error.message}`);
}
}
async dbRemoveOne(collection: Collection, query: FilterQuery<string | object>): Promise<boolean> {
// http://mongodb.github.io/node-mongodb-native/3.1/api/Collection.html#deleteOne
query = wrapIdToMongoDbQuery(query);
const deleted = await collection.deleteOne(query);
if(deleted.deletedCount > 1) {
throw new Error(`Removed ${deleted.deletedCount} elements with query: ${JSON.stringify(query)}. Only one is Ok.`);
}
return deleted.deletedCount === 1;
}
async dbRemoveMany(collection: Collection, query: string[] | object): Promise<number> {
// http://mongodb.github.io/node-mongodb-native/3.1/api/Collection.html#deleteMany
if(isEmptyArray(query)) {
return 0;
}
query = wrapIdsToMongoDbQuery(query);
const deleted = await collection.deleteMany(query);
return deleted.deletedCount;
}
}