forked from Galactic/galactic-bot
194 lines
5.7 KiB
JavaScript
194 lines
5.7 KiB
JavaScript
const Provider = require('../Provider.js');
|
|
const { MongoClient } = require('mongodb');
|
|
|
|
class MongoDBProvider extends Provider {
|
|
|
|
constructor(manager, config) {
|
|
|
|
super(manager, config, 'mongodb');
|
|
|
|
this.client;
|
|
|
|
}
|
|
|
|
async init() {
|
|
|
|
//this.manager.logger.log('Initializing mongodb.');
|
|
|
|
try {
|
|
|
|
this.client = await MongoClient.connect(this.config.url+this.config.database, { useUnifiedTopology: true });
|
|
this.manager.db = await this.client.db(this.config.database);
|
|
this.db = this.manager.db;
|
|
this.loaded = true;
|
|
// this.manager.write('info', `Provider ${this.name} connected.`);
|
|
|
|
} catch(err) {
|
|
|
|
// this.manager.write('error', `Provider ${this.name} failed to connect.` + err);
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
_query(query) {
|
|
/*
|
|
{
|
|
type: '',
|
|
collection: '',
|
|
query: '',
|
|
data: {
|
|
|
|
}
|
|
}
|
|
*/
|
|
|
|
if(!this[query.type]) return { error: true, message: `Invalid query type, got '${query.type}'` };
|
|
return this[query.type](query);
|
|
|
|
|
|
}
|
|
|
|
/**
|
|
* Find and return the first match
|
|
* @memberof Database
|
|
*/
|
|
|
|
find({ collection, query }) {
|
|
|
|
//if(this.manager.debug) this.manager.logger.debug(`Incoming find query for ${db} with parameters ${JSON.stringify(query)}`);
|
|
return new Promise((resolve, reject) => {
|
|
|
|
if(!this.loaded) reject(new Error('MongoDB not connected'));
|
|
|
|
this.db.collection(collection).find(query, async (error, cursor) => {
|
|
|
|
if(error) return reject(error);
|
|
return resolve(await cursor.toArray());
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
/**
|
|
* Find and return the first match
|
|
*
|
|
* @param {String} db The collection in which the data is to be updated
|
|
* @param {Object} query The filter that is used to find the data
|
|
* @returns {Object} An object containing the queried data
|
|
* @memberof Database
|
|
*/
|
|
|
|
findOne({ collection, query }) {
|
|
|
|
//if(this.manager.debug) this.manager.logger.debug(`Incoming findOne query for ${db} with parameters ${JSON.stringify(query)}`);
|
|
return new Promise((resolve, reject) => {
|
|
|
|
if(!this.loaded) reject(new Error('MongoDB not connected'));
|
|
|
|
this.db.collection(collection).findOne(query, async (error, item) => {
|
|
|
|
if(error) return reject(error);
|
|
return resolve(item);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
/**
|
|
* Update the first filter match.
|
|
*
|
|
* @param {String} db The collection in which the data is to be updated
|
|
* @param {Object} filter The filter that is used to find the data
|
|
* @param {Object} data The updated data
|
|
* @param {Boolean} [upsert=false] Create a new entry if no match is found
|
|
* @returns {WriteResult} Object containing the followint counts: Matched, Upserted, Modified
|
|
* @memberof Database
|
|
*/
|
|
updateOne({ collection, query, data, upsert = false }) {
|
|
|
|
//if(this.manager.debug) this.manager.logger.debug(`Incoming updateOne query for ${db} with parameters ${JSON.stringify(filter)}`);
|
|
return new Promise((resolve, reject) => {
|
|
|
|
if(!this.loaded) reject(new Error('MongoDB not connected'));
|
|
|
|
this.db.collection(collection).updateOne(query, { $set: data }, { upsert: upsert }, async (error, result) => {
|
|
|
|
if(error) return reject(error);
|
|
else {
|
|
//return resolve(result)
|
|
let { matchedCount, upsertedCount, modifiedCount } = result;
|
|
return resolve({ matched: matchedCount, upserted: upsertedCount, modified: modifiedCount });
|
|
}
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
/**
|
|
* Push data to an array
|
|
*
|
|
* @param {string} db The collection to query
|
|
* @param {object} filter The filter to find the document to update
|
|
* @param {object} data The data to be pushed
|
|
* @param {boolean} [upsert=false] Create a new entry if no match is found
|
|
* @returns
|
|
* @memberof Database
|
|
*/
|
|
push({ collection, query, data, upsert = false }) {
|
|
|
|
//if(this.manager.debug) this.manager.logger.debug(`Incoming push query for ${db}, with upsert ${upsert} and with parameters ${JSON.stringify(filter)} and data ${JSON.stringify(data)}`);
|
|
return new Promise((resolve, reject) => {
|
|
|
|
if(!this.loaded) reject(new Error('MongoDB not connected'));
|
|
|
|
this.db.collection(collection).updateOne(query, { $push: data }, { upsert: upsert }, async (error, result) => {
|
|
|
|
if(error) return reject(error);
|
|
else return resolve(result);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
/**
|
|
* Find a random element from a database
|
|
*
|
|
* @param {string} db The collection to query
|
|
* @param {object} [filter={}] The filtering object to narrow down the sample pool
|
|
* @param {number} [amount=1] Amount of items to return
|
|
* @returns {object}
|
|
* @memberof Database
|
|
*/
|
|
random({ collection, query = {}, amount = 1 }) {
|
|
|
|
//if(this.manager.debug) this.manager.logger.debug(`Incoming random query for ${db} with parameters ${JSON.stringify(filter)} and amount ${amount}`);
|
|
if(amount > 100) amount = 100;
|
|
|
|
return new Promise((resolve, reject)=>{
|
|
|
|
if(!this.loaded) reject(new Error('MongoDB not connected'));
|
|
|
|
this.db.collection(collection).aggregate([{ $match: query }, { $sample: {size: amount}}], function(err, item) {
|
|
|
|
if(err) return reject(err);
|
|
resolve(item);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
module.exports = MongoDBProvider; |