如何处理未知变量或如何处理多个数据库

2024-04-23

我正在开发一个带有多个数据库的 Go RESTful API 应用程序。启动服务器时,用户提供他们想要使用的数据库。

在应用程序中,我有三大功能其中一个处理连接:selectedDb.Get(), selectedDb.Add(), selectedDb.Connect().

如果有人选择 Mysql,它会处理 Mysql 的事务,如果有人选择 MongoDB,它会处理 Mongo 的事务,依此类推。

我就是这样try为了实现这一点:

数据库接口.go

package dbinit

type Object struct {
    Uuid         string
    Object       string
    Deleted      bool
}

// The interface that all connectors should have
type Intfc interface {
    Connect() HERE_LIES_MY_PROBLEM
    Add(string, string, string) string
    Get(string) (Object, bool)
}

MySQL.go

package mysqlConnector

import (
    ...
)

type Mysql struct{}

// Connect to mysql
func (f Mysql) Connect() HERE_LIES_MY_PROBLEM {

    client, err = sql.Open("mysql", "yourusername:yourpassword@/yourdatabase")
    if err != nil {
        panic(err.Error())    
    }

    return client
}

// Add item to DB
func (f Mysql) Add(owner string, refType string, object string) string {
    // do stuff related to this DB

    return // a string
}

func (f Mysql) Get(Uuid string) (dbinit.Object, bool) {
    // do stuff related to this DB

    return // an object and a bool
}

Mongo.go

package mongoConnector

import (
    ...
)

type Mongo struct{}

// Connect to mongo
func (f Mongo) Connect() HERE_LIES_MY_PROBLEM {

    info := &mgo.DialInfo{
        Addrs:    []string{hosts},
        Timeout:  60 * time.Second,
        Database: database,
        Username: username,
        Password: password,
    }

    client, err := mgo.DialWithInfo(info)
    if err != nil {
        panic(err)
    }

    return client
}

// Add item to DB
func (f Mongo) Add(owner string, refType string, object string) string {
    // do stuff related to this DB

    return // a string
}

func (f Mongo) Get(Uuid string) (dbinit.Object, bool) {
    // do stuff related to this DB

    return // an object and a bool
}

main.go

...

var selectedDb dbinit.Intfc

commandLineInput := "mysql" // just for the example

if commandLineInput == "mysql" {
    selectedDb = mysqlConnector.Mysql{}
} else if commandLineInput == "mongo" {
    selectedDb = mongoConnector.Mongo{}
}

client := selectedDb.Connect()

// this runs everytime the API is called
api.HandlerFoobar = foobar.handlerFunction(func(params foobar.Params) middleware.Responder {

    // Here I want to add something to the selected dbinit
    selectedDb.Get(client, addStringA, addStringB, addStringC)

    return // the API response

})

...

问题陈述

当我返回 Mysql 客户端时,它不适用于 Mongo,反之亦然。

我只想在启动服务器时连接到数据库并存储client在客户端变量内。然而,问题是 Mongo 返回的客户端比 Mysql 返回的客户端要多,等等。

  1. 我有的地方应该有什么HERE_LIES_MY_PROBLEM在代码中?
  2. 或者我处理这些事情的 Go 范式是错误的吗?

如果您想保留这些方法的接口,您应该对接口进行一些更改,如下所示:

界面:

// The interface that all connectors should have
type Intfc interface {
    // Connect to the database, if an error occur at the moment
    // of connection, return the error
    Connect() error
    // Add returns a string, it returns an error if something occurs
    Add(string, string, string) (string, error)
    Get(string) (Object, bool)
}

MySQL:

type Mysql struct{
    conn *sql.DB // contains the connection to the DB
}

// Connect to mysql
func (f *Mysql) Connect() error {
    conn, err := sql.Open("mysql", "yourusername:yourpassword@/yourdatabase")
    if err != nil {
        return error
    }
    f.conn = conn
    return nil
}

// Add item to DB
func (f *Mysql) Add(owner string, refType string, object string) (string, error) {
    // do something
    return // a string and error
}

func (f *Mysql) Get(Uuid string) (dbinit.Object, bool) {
    // do something
    return // an object and a bool
}

Mongo:

type Mongo struct{
    session *mgo.Session
}

// Connect to mongo
func (f *Mongo) Connect() error {
    info := &mgo.DialInfo{
        // some data
    }

    session, err := mgo.DialWithInfo(info)
    if err != nil {
        return error
    }
    f.session = session
    return nil
}

// Add item to DB
func (f *Mongo) Add(owner string, refType string, object string) (string, error) {
    // do something
    return // a string and error (it could be nil at success)
}

func (f *Mongo) Get(Uuid string) (dbinit.Object, bool) {
    // do something
    return // an object and a bool
}

Main:

var selectedDb dbinit.Intfc

commandLineInput := "mysql"

if commandLineInput == "mysql" {
    selectedDb = &mysqlConnector.Mysql{}
} else if commandLineInput == "mongo" {
    selectedDb = &mongoConnector.Mongo{}
}

err := selectedDb.Connect()
if err != nil {
    panic(err)
}

// this runs everytime the API is called
api.HandlerFoobar = foobar.handlerFunction(func(params foobar.Params) middleware.Responder {
    data, err := selectedDb.Add(addStringA, addStringB, addStringC)
    if err != nil {
        // do something
    }

    return // the API response
})

但您也可以删除Connect() error方法来自Intfc只需使用Add and Get,但您应该更新软件包,例如:

Mysql

// Connect to mysql, it could be any function name
func Connect() (*Mysql, error) {
    connection, err := sql.Open("mysql", "yourusername:yourpassword@/yourdatabase")
    if err != nil {
        return nil, error
    }
    return &Mysql{conn: connection}
}

Mongo

// Connect to mongo, it could be any function name
func Connect() (*Mongo, error) {
    info := &mgo.DialInfo{
        // some data
    }

    s, err := mgo.DialWithInfo(info)
    if err != nil {
        return nil, error
    }
    return &Mongo{session: s}
}

Main

var selectedDb dbinit.Intfc
var err error
commandLineInput := "mysql"

if commandLineInput == "mysql" {
    selectedDb, err = mysqlConnector.Connect()
} else if commandLineInput == "mongo" {
    selectedDb, err = mongoConnector.Connect()
}

if err != nil {
    panic(err)
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何处理未知变量或如何处理多个数据库 的相关文章