我正在开发一个包含多个数据库的 Go RESTful API 应用程序。启动服务器时,用户提供他们想要使用的数据库。
在应用程序中,我有三个函数,其中一个处理连接:selectedDb.Get()、selectedDb.Add() , selectedDb.Connect().
如果有人选择 Mysql,它会为 Mysql 处理事情,如果有人选择 MongoDB,它会为 Mongo 处理事情等等。
这就是我尝试完成此任务的方式:
DbInterface.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 存储在 client 变量中。然而,问题是 Mongo 返回的客户端不是 Mysql 的,等等。
HERE_LIES_MY_PROBLEM 的地方应该是什么?最佳答案
如果你想保留这些方法的接口(interface),你应该改变你的接口(interface):
界面:
// 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
}
蒙哥:
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
}
主要:
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
})
但您也可以从 Intfc 中删除 Connect() error 方法,只需使用 Add 和 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}
}
蒙古人
// 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}
}
主要
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)
}
关于go - 如何处理未知变量或如何处理多个数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43755892/
Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题
我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何
我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击
我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是
我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2
我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这
我在理解Enumerator.new方法的工作原理时遇到了一些困难。假设文档中的示例:fib=Enumerator.newdo|y|a=b=1loopdoy[1,1,2,3,5,8,13,21,34,55]循环中断条件在哪里,它如何知道循环应该迭代多少次(因为它没有任何明确的中断条件并且看起来像无限循环)? 最佳答案 Enumerator使用Fibers在内部。您的示例等效于:require'fiber'fiber=Fiber.newdoa=b=1loopdoFiber.yieldaa,b=b,a+bendend10.times.m
我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R