evils.db
Version:
  
130 lines (105 loc) • 3.71 kB
text/typescript
import { get, set, unset } from "lodash";
import { Database } from "./Database";
import { DatabaseError } from "./Error";
import type { MongoDatabaseOptions } from "./Interface";
export class MongoDatabase extends Database {
private options: MongoDatabaseOptions;
private collection: any;
private connection: any;
private collectionName: string;
public constructor(options: MongoDatabaseOptions) {
super();
let mongoClient: any = undefined;
try {
mongoClient = require("mongoose");
} catch {
throw new DatabaseError('The "mongoose" module is not installed. Please install it with "npm install mongoose"');
}
let schema = new mongoClient.Schema({
key: {
type: mongoClient.Schema.Types.String,
unique: true,
required: true
},
value: {
type: mongoClient.Schema.Types.Mixed,
unique: true,
required: true
}
});
this.options = options;
this.collectionName = options.collectionName;
this.connection = mongoClient.createConnection(this.options.url, this.options.clientOptions)
this.collection = this.connection.model(this.options.collectionName, schema);
async() => {
await this.setAll();
}
}
public async set(key: string, value: any) {
let dotKey = key.split('.')[0];
let data = get(this.cache, dotKey);
set(this.cache, key, value);
if(data) {
if(key.includes('.')) {
set(this.cache, dotKey, data)
set(this.cache, key, value)
await this.collection.updateOne(
{ key: dotKey },
{ value: get(this.cache, dotKey) }
)
} else {
await this.collection.updateOne({ key }, { value })
}
} else {
if(key.includes('.')) {
await this.collection.create({ key: dotKey, value: get(this.cache, dotKey) })
} else {
await this.collection.create({ key, value })
}
}
return value;
}
public get(key: string) {
return get(this.cache, key);
}
public async remove(key: string) {
unset(this.cache, key);
if(key.includes('.')) {
let dotKey = key.split('.')[0];
await this.set(dotKey, get(this.cache, dotKey))
} else {
await this.collection.deleteOne({ key })
}
}
public async getAll() {
return this.cache;
}
public async setAll() {
let data = await this.collection.find();
for (const item of data) {
set(this.cache, item.key, item.value)
}
return this.cache;
}
public async push(key: string, value: any) {
let data = get(this.cache, key);
if(!data) data = [];
data.push(value);
await this.set(key, data);
return data;
}
public async pull(key: string, value: any) {
let data = get(this.cache, key);
if(!data) data = [];
data = data.filter((x: any) => x !== value);
await this.set(key, data);
return data;
}
public async add(key: string, value: any) {
let data = get(this.cache, key);
if(!data) data = 0;
data += value;
await this.set(key, data);
return data;
}
}