forked from Galactic/galactic-bot
192 lines
6.7 KiB
JavaScript
192 lines
6.7 KiB
JavaScript
const { ObjectId } = require('mongodb');
|
|
|
|
class MongodbTable {
|
|
|
|
constructor(client, provider, opts = {}) {
|
|
|
|
this.client = client;
|
|
this.provider = provider;
|
|
|
|
this.name = opts.name;
|
|
|
|
}
|
|
|
|
//Data Search
|
|
|
|
find(query, opts = {}) { //opts: { projection: ... }
|
|
query = this._handleData(query);
|
|
return new Promise((resolve, reject) => {
|
|
if(!this.provider._initialized) return reject(new Error('MongoDB is not connected.'));
|
|
this.collection.find(query, opts, async (error, cursor) => {
|
|
if(error) return reject(error);
|
|
return resolve(await cursor.toArray());
|
|
});
|
|
});
|
|
}
|
|
|
|
findOne(query, opts = {}) { //opts: { projection: ..., sort: ... }
|
|
query = this._handleData(query);
|
|
return new Promise((resolve, reject) => {
|
|
if(!this.provider._initialized) return reject(new Error('MongoDB is not connected.'));
|
|
this.collection.findOne(query, opts, async (error, item) => {
|
|
if(error) return reject(error);
|
|
return resolve(item);
|
|
});
|
|
});
|
|
}
|
|
|
|
aggregate(query) {
|
|
query = this._handleData(query);
|
|
return new Promise((resolve, reject) => {
|
|
if(!this.provider._initialized) return reject(new Error('MongoDB is not connected.'));
|
|
this.collection.aggregate(query, (error, item) => {
|
|
if(error) return reject(error);
|
|
return resolve(item.toArray());
|
|
});
|
|
});
|
|
}
|
|
|
|
random(query, amount = 1) {
|
|
query = this._handleData(query);
|
|
if(amount > 100) amount = 100;
|
|
return new Promise((resolve, reject) => {
|
|
if(!this.provider._initialized) return reject(new Error('MongoDB is not connected.'));
|
|
this.collection.aggregate([{ $match: query }, { $sample: { size: amount } }], (error, item) => {
|
|
if(error) return reject(error);
|
|
return resolve(item);
|
|
});
|
|
});
|
|
}
|
|
|
|
//Data Manipulation
|
|
|
|
insertOne(data) {
|
|
data = this._handleData(data);
|
|
return new Promise((resolve, reject) => {
|
|
if(!this.provider._initialized) return reject(new Error('MongoDB is not connected.'));
|
|
this.collection.insertOne(data, (error, result) => {
|
|
if(error) return reject(error);
|
|
return resolve(result);
|
|
});
|
|
});
|
|
}
|
|
|
|
//NOTE: insertMany?
|
|
|
|
deleteOne(query) {
|
|
query = this._handleData(query);
|
|
return new Promise((resolve, reject) => {
|
|
if(!this.provider._initialized) return reject(new Error('MongoDB is not connected.'));
|
|
this.collection.deleteOne(query, (error, result) => {
|
|
if(error) return reject(error);
|
|
return resolve(result);
|
|
});
|
|
});
|
|
}
|
|
|
|
deleteMany(query) {
|
|
query = this._handleData(query);
|
|
return new Promise((resolve, reject) => {
|
|
if(!this.provider._initialized) return reject(new Error('MongoDB is not connected.'));
|
|
this.collection.deleteMany(query, (error, result) => {
|
|
if(error) return reject(error);
|
|
return resolve(result);
|
|
});
|
|
});
|
|
}
|
|
|
|
updateOne(query, data, upsert = true) {
|
|
query = this._handleData(query);
|
|
return new Promise((resolve, reject) => {
|
|
if(!this.provider._initialized) return reject(new Error('MongoDB is not connected.'));
|
|
this.collection.updateOne(query, { $set: data }, { upsert }, async(error, result) => {
|
|
if(error) return reject(error);
|
|
|
|
const { matchedCount, upsertedCount, modifiedCount } = result;
|
|
return resolve({ matched: matchedCount, upserted: upsertedCount, modified: modifiedCount });
|
|
});
|
|
});
|
|
}
|
|
|
|
removeProperty(query, data) {
|
|
query = this._handleData(query);
|
|
return new Promise((resolve, reject) => {
|
|
if(!this.provider._initialized) return reject(new Error('MongoDB is not connected.'));
|
|
|
|
const unset = {};
|
|
for(const field of data) unset[field] = '';
|
|
this.collection.updateOne(query, { $unset: unset }, async (error, result) => {
|
|
if(error) return reject(error);
|
|
const { matchedCount, modifiedCount } = result;
|
|
return resolve({ matched: matchedCount, modified: modifiedCount });
|
|
});
|
|
|
|
});
|
|
}
|
|
|
|
push(query, data, upsert = true) {
|
|
query = this._handleData(query);
|
|
return new Promise((resolve, reject) => {
|
|
if(!this.provider._initialized) return reject(new Error('MongoDB is not connected.'));
|
|
this.collection.updateOne(query, { $push: data }, { upsert }, async(error, result) => {
|
|
if(error) return reject(error);
|
|
return resolve(result);
|
|
});
|
|
});
|
|
}
|
|
|
|
//Statistics
|
|
stats(options = {}) {
|
|
return new Promise((resolve, reject) => {
|
|
if(!this.provider._initialized) return reject(new Error('MongoDB is not connected.'));
|
|
this.collection.stats(options, (error, statistics) => {
|
|
if(error) return reject(error);
|
|
const { ns, size, count, avgObjSize, freeStorageSize, capped } = statistics;
|
|
return resolve({
|
|
index: ns,
|
|
averageSize: avgObjSize,
|
|
currentSize: size,
|
|
remainingSize: freeStorageSize,
|
|
maximumSize: size+freeStorageSize,
|
|
count,
|
|
capped
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
count(query, options = {}) {
|
|
return new Promise((resolve, reject) => {
|
|
if(!this.provider._initialized) return reject(new Error('MongoDB is not connected.'));
|
|
this.collection.countDocuments(query, options, (error, result) => {
|
|
if(error) return reject(error);
|
|
return resolve(result);
|
|
});
|
|
});
|
|
}
|
|
|
|
//Lazy Function
|
|
_handleData(data) { //Convert data._id to Mongo ObjectIds (gets converted to plaintext through shard communication)
|
|
if(data._id) {
|
|
console.log(data._id, typeof data._id);
|
|
if(typeof data._id === 'string') data._id = ObjectId(data._id);
|
|
else if(typeof data._id === 'object') data._id = {
|
|
$in: Object.values(data._id)[0].map((id) => {
|
|
return ObjectId(id);
|
|
})
|
|
};
|
|
}
|
|
return data;
|
|
}
|
|
|
|
|
|
//Getters
|
|
|
|
get collection() {
|
|
return this.provider.db.collection(this.name);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
module.exports = MongodbTable; |