Is there a right way to connect to MySQL? - mysql

I've come across documentation that says:
the sql.DB object is designed to be long-lived. Don’t Open() and
Close() databases frequently. Instead, create one sql.DB object for
each distinct datastore you need to access
source
And doing some poking around I mostly found code opening the connection in the handler file as so
func dbConn() (db *sql.DB) {
dbDriver := "mysql"
dbUser := "root"
dbPass := "root"
dbName := "goblog"
db, err := sql.Open(dbDriver, dbUser+":"+dbPass+"#/"+dbName)
if err != nil {
panic(err.Error())
}
return db
}
source
And to access the db
db := dbConn()
This is called in the functions that need to use it, to my understanding this would open the connection and then close it when it reaches the end of said function.
Wouldn't this be violating the quote above?

The example is simply poorly written, and Yes you shouldn't Open and Close unless its different datastores.
Open returns DB and
DB is a database handle representing a pool of zero or more underlying connections. It's safe for concurrent use by multiple goroutines

Related

how to excute conjunctive query crossing two mysql databases with gorm?

code like:
addr:=fmt.Sprintf(`%v:%v#tcp(%v:%v)/(%v,%v)?charset=utf8`, dbuser, dbpassword, dbhost, dbport, dbdatabase)
DB, err = gorm.Open("mysql", addr)
sql := "select * from db1.user join db2.salary"
rows, err := DB.Raw(sql).Rows()
it seems the method gorm.Open() only accept one source parameter, and it run error "unknown table name 'db1.user'"
is there a correct way to init the DB to excute the sql or other way to solve the problem?
many thanks
sovled by setting dbdatabase="" , which it means giving null database name connecting to the mysql instance. And database name shoud be presented as prefix on table name in sql.

How to switch between databases using GORM in golang?

I'm new to GORM in golang. I'm stuck at a point. Generally we select the database like this:
DBGorm, err = gorm.Open("mysql", user:password#tcp(host:port)/db_name)
But my problem is I'll get the 'db_name' in the request, which means I don't know which db_name might come and I'll have to query according to that db_name.
So now, I'll create the database pointer in the init function like this:
DBGorm, err = gorm.Open("mysql", user:password#tcp(host:port)/) which is without the db_name.
Now how will I switch to db_name coming to me in request. Because when I try to do DBGorm.Create(&con), it shows No database selected.
If I use 'database/sql', then I can make raw queries like this: "SELECT * FROM db_name.table_name", this can solve my problem. But how to do this in gorm?
You can explicitly specify db_name and table_name using .Table() when doing query or other operation on table.
DBGorm.Table("db_name.table_name").Create(&con)
I saw a related article on Github. https://github.com/go-sql-driver/mysql/issues/173#issuecomment-427721651
All you need to do is
start a transaction,
set you database
run your desired query.
and switch back to your desired DB
commit once you are done.
below is an example
tx := db.Begin() // start transaction
tx.Exec("use " + userDB) // switch to tenant db
tx.Exec("insert into ....") // do some work
tx.Exec("use `no-op-db`") // switch away from tenant db (there is no unuse, so I just use a dummy)
tx.Commit() // end transaction

Config for GoLang Returns "non-name" error

I am having trouble compiling code Google-Cloud offers on connecting to a mysql database remotely using Golang.
The code is a direct copy-paste from here: https://cloud.google.com/sql/docs/mysql/connect-external-app#go. One may also look here: https://github.com/GoogleCloudPlatform/cloudsql-proxy/blob/master/proxy/dialers/mysql/hook_test.go.
I've tried providing a second variable to the first line below, but there is an error as only one value is returned by the mysql function.
The troublesome code is on the second line, possibly due to the first line.
cfg := mysql.Cfg("haveibeenexploited:us-west1:hibe", "username", "password")
cfg.DBName := "mythril"
db, err := mysql.DialCfg(cfg)
searchcontract/searchcontract.go:67:5: non-name cfg.DBName on left side of := is the error message I get.
Change this line of code:
cfg.DBName := "mythril"
to:
cfg.DBName = "mythril"
The := operator declares a new variable and assigns it a value. This is called "Short Variable Declarations". Since DBName is part of the structure cfg you are using the wrong operator. The correct operator to use is the assignment operator =.

MySQL sharding in Golang

I want to scale out my MySQL database into few servers using horizontal sharding. Let's imagine that I have 5 database servers (not replicas) and I want to distribute the data from users table between 5 database servers:
Shard 1 (192.168.1.1)
Shard 2 (192.168.1.2)
Shard 3 (192.168.1.3)
Shard 4 (192.168.1.4)
Shard 5 (192.168.1.5)
Now I want to connect to one of them depending on user_id (server_id = user_id % 5). I will do this on each API request from users in my Go application.
I'm using go-sql-driver and standard database/sql package.
import "database/sql"
import _ "github.com/go-sql-driver/mysql"
shard1, _ := sql.Open("mysql", "user:password#tcp(192.168.1.1:3306)/dbname")
shard2, _ := sql.Open("mysql", "user:password#tcp(192.168.1.2:3306)/dbname")
shard3, _ := sql.Open("mysql", "user:password#tcp(192.168.1.3:3306)/dbname")
...
There is a basic connection pool in the database/sql package, but there is not a lot of control on it. There are also few methods: SetMaxIdleConns, SetMaxOpenConns, SetConnMaxLifetime, but it looks that they work only with single database server at once.
The question is how to properly handle and pool database connections in my Golang application? How to work with multiple database servers in Golang?
Should I create a singleton object with connection map with *DB values, store all connections there and use them across the whole application? For example:
connections := make(map[string]interface{})
connections["shard1"] = shard1
connections["shard2"] = shard2
...
How to close connections or don't close them after SQL query execution?

Unknown MYSQL server host 'ServerName'(11001)

I want to try connection with MySQLdatabase with my Delphi Application.
I am using dbXpress component TSQLConnection.
When I tried using the Graphic component and test it if it can connect Database.
It got connected with using Object inspector option.
But when I tried using the code I am getting error as Unknown MYSQL server host 'ServerName'(11001).
I am not able to get the right solution from google uncle.
Can anyone tell me whats wrong with my code?
Below is My Code.
Conn := TSQLConnection.Create(nil);
try
conn.DriverName:= 'MySQL';
conn.Params.Add('HostName=127.0.0.1');
conn.Params.Add('Database=test1');
conn.Params.Add('UserName=root');
conn.Params.Add('Password=test');
conn.LoginPrompt := false;
try
conn.Connected := true;
ShowMessage('Database connected');
Except
on E:exception do
ShowMessage(E.Message);
end;
finally
if Conn.Connected then
Conn.Connected := false;
FreeAndNil(Conn);
end;
Please let me know if any more information needed.
Thanks in advance.
The conn.Params list is already propagated with pre-existing values. Therefore you should not .add() your configuration to it, but rather change the current Params.
So, instead of using
conn.Params.Add('HostName=127.0.0.1'); // wrong - should update, not add
conn.Params.Add('Database=test1'); // wrong - should update, not add
conn.Params.Add('UserName=root'); // wrong - should update, not add
conn.Params.Add('Password=test'); // wrong - should update, not add
Use
conn.Params.Values['HostName'] := '127.0.0.1';
conn.Params.Values['Database'] := 'test1';
conn.Params.Values['UserName'] := 'root';
conn.Params.Values['Password'] := 'test';