Writing reusable code has always been a programming hobbyist’s hobby, especially when you need to connect to a database every time you run mongodb, which can be cumbersome and make your code look bloated

First, I’ll create a new file called curd, which encapsulates a class, and I’ll instantiate all curd operations through the class, such as db. find. I’ll also need some auxiliary methods or properties, such as _ope,this.tips

class DB{

constructor(){

this.tips = “”

this.query = []

this.charts = []

this.methods = []

}

static hasInstance(){}

_canNext(){}

_ope(){}

_connect(){}

_find(){}

_update(){}

_delete(){}

_add(){}

trigger(){}

}

If you had read my other article, you would have done the same

Add a method trigger to the DB class. This method is used as the only interface exposed by the DB class to switch calls to the internal CURD, so I will prefix each CURD method with “_” to indicate that it is a private method

I want when the user calls the trigger method, I can switch the internal _CURD directive based on the CURD specified by the user. I also need the user to at least tell me the database address I want to link to and the name of the table I want to operate on, so I consider implementing trigger this way

trigger(operate,params){

this.query = params.jsons? params.jsons:[]

let str = ”

switch(operate){

case ‘find’:

STR = ‘query’ break

case ‘update’:

STR = ‘update’ break

case ‘add’:

STR = ‘add’ break

case ‘delete’:

STR = ‘delete’ break

}

this.tips = str

if(operate==’find’){

this._find(params)

}else{

this._ope(params)

}

}

Among them:

1. The this._find() method is singled out because of its unique way of retrieving the results of operations and its “inflexiability”.

2. The switch method dynamically modifies the value of this.tips based on the passed operation name, which is returned as MSG of the result of the operation

3. This. query The parameter passed by the user. Some operations may have more than one parameter, so it is saved as an array

4 to operate is the user to perform an operation, params carry is the user query methods, including at least the following {collection: String, jsons: Array}

Implement the _ope method

_ope(operate,params){

return new Promise((resolve,reject)=>{

this._connect().then(db=>{

db.collection(params.collection)[operate](… this.query,(err,data)=>{

if(err){

reject({

status:0,

MSG: ${this. Tips} failure ~

})

}

resolve({

status:1,

MSG: ${this. Tips} ~ success

})

})

})

})

}

Among them:

1. The this._connect method is used to connect to the database. After the connection is successful, the db object is returned

Db.collection (params.collection)[operate] is used to join the table, equivalent to db.chartname.operate (see 🙂

3… This.query expands the parameter object, which is useful when performing such updates

Implement _find

_find(params){

this._connect().then(db=>{

db.collection(params.collection)operate.toArray((err,data)=>{

if(err){

reject({

status:0,

MSG: ${this. Tips} failure ~

})

}

resolve({

status:1,

MSG: ${this. Tips} ~ success

})

})

})

}

Among them:

1.. ToArray is one of the reasons why find was singled out for analysis in the first place

Implement _connect

_connect(params){

return new Promise((resolve) => {

params.MongodbClient.connect(params.dbUri, {

useUnifiedTopology: true

}, (err, client) => {

if (err) {

throw new Error(err)

}

let db = client.db(params.dbName)

resolve(db)

})

})

}

Among them:

MongodbClient is the client property of the introduced database module

2. DbUri is the address of the connected database

3. DbName is the database to be connected

At this point, the theory looks like it’s done, but in fact, it’s not

Almost what?

1. If there are multiple instances, there will be multiple connections, and each connection is time-consuming

2. If the user provides a method that the DB class does not support or the connected database or table does not exist, the user should be prompted

Therefore,

Define this.charts to hold operable tables; Define this.methods to hold executable methods; Define _canNext and call it inside trigger to solve problem 2

_canNext(params,operate){

if (! this.charts.includes(params.collection)) {

Throw new Error(” database “+ params.dbname + ‘not found’ + params.collection + ‘table ‘)

}

if (! this.methods.includes(operate)) {

Throw new Error(“DB class does not exist method “+ method)

}

}

Define hasInstance as a singleton to solve problem 1 and call it in this._connect, exporting the method instead of class DB when exported

static hasInstance(){

if (! Db.instance) {

Db.instance = new Db()

}

return Db.instance

}

So far, done!!