How to ping remote mysql using golang - mysql

I am using go to ping some Linux machines.
But it is not work accurate, because it always needs almost 10 seconds to connect the remote mysql.
I use this command:
mysql -u USER -p PASSWORD -h REMOTE_IP
So i want to know how to use linux command to know whether it open or not.
Then I will use golang 's exec.Command to do that .
Here is my ping code:
package main
import (
"errors"
"fmt"
"github.com/tatsushid/go-fastping"
"net"
"net/smtp"
"strings"
"time"
)
func main(){
err := ping("192.168.2.1")
if err != nil{
fmt.Println("WARNING!!!!!!")
}
}
func ping(ip string) error {
p := fastping.NewPinger()
ra, err := net.ResolveIPAddr("ip", ip)
if err != nil {
return err
}
p.AddIPAddr(ra)
found := false
p.OnRecv = func(addr *net.IPAddr, rtt time.Duration) {
found = true
}
err = p.Run()
if err != nil {
return err
}
if !found {
return errors.New("response error")
}
return nil
}

I assume you want to know if mysql is reachable or not. You can use following example:
package main
import (
"database/sql"
"flag"
"fmt"
"log"
_ "github.com/go-sql-driver/mysql"
)
func main() {
var (
server = flag.String("mysql", "localhost:3306", "mysql server")
user = flag.String("user", "root", "mysql user")
pass = flag.String("password", "", "mysql password")
)
flag.Parse()
db, err := sql.Open("mysql", fmt.Sprintf("%s:%s#tcp(%s)/", *user, *pass, *server))
if err != nil {
log.Fatalln(err)
}
defer db.Close()
err = db.Ping()
if err != nil {
log.Fatalln(err)
} else {
log.Println("mysqld is alive")
}
}

If you just need to check connection to a specific host & port, you can do this as:
package main
import (
"fmt"
"net"
)
const (
host = "192.168.2.1"
port = "3306" // default MySQL port
)
func main() {
conn, err := net.Dial("tcp", host+":"+port)
if err != nil {
panic(err)
}
defer conn.Close()
fmt.Printf("Connected to %s \n", conn.RemoteAddr().String())
}

Related

golang sql.open() expects 0 arguments got 1

I am trying to connect to a mysql database I have locally, using golang, it builds just fine but running it gives me the following error:
panic: sql: expected 0 arguments, got 1
My connection looks like this:
package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
)
func DBConn() {
team := "software"
db, err := sql.Open("mysql", "root:12345678#tcp(localhost:3306)/flexlocal")
if err != nil {
fmt.Println("this is where it all went wrong")
fmt.Printf(err.Error())
panic(err)
}
}
According to my research this is how it works however it just isn't working for me.
Please try dbconn function to connect with mysql in go
package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
)
func dbConn(setDatbaseInstance string) (db *sql.DB) {
dbDriver := "mysql"
dbUser := "*****"
dbPass := "*****"
dbName := "*****"
db, err := sql.Open(dbDriver, dbUser+":"+dbPass+"#tcp("+setDatbaseInstance+":3306)/"+dbName)
if err != nil {
fmt.Printf("%#v\n DB_ERROR_CONNECTION\n", err.Error());
// return err.Error()
}else{
fmt.Println("Connection Established")
}
erro:=db.Ping()
if erro!=nil {
//do something here
fmt.Printf("%#v\n DB_PING_ERROR_CONNECTION\n", erro.Error());
}
return db
}

How do I select the database to query when using Cloud SQL through App Engine?

I get the following error:
Could not query db: Error 1046: No database selected
I understand what the error message means. But I haven't been able to find the documentation where it says how to select a database.
Here is my code:
package main
import (
"database/sql"
"fmt"
"log"
"net/http"
"os"
"time"
"google.golang.org/appengine"
_ "github.com/go-sql-driver/mysql"
)
var db *sql.DB
func main() {
var (
connectionName = mustGetenv("CLOUDSQL_CONNECTION_NAME")
user = mustGetenv("CLOUDSQL_USER")
password = os.Getenv("CLOUDSQL_PASSWORD")
)
var err error
db, err = sql.Open("mysql ", fmt.Sprintf("%s:%s#cloudsql(%s)/", user, password, connectionName))
if err != nil {
log.Fatalf("Could not open db: %v", err)
}
http.HandleFunc("/", handler)
appengine.Main()
}
func handler(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" {
http.NotFound(w, r)
return
}
w.Header().Set("Content-Type", "text/plain")
rows, err := db.Query("INSERT INTO ping ( ping ) VALUES ( '" + time.Now().Format("2006-01-02 03:04:05") + "' );")
if err != nil {
http.Error(w, fmt.Sprintf("Could not query db: %v", err), 500)
return
}
defer rows.Close()
w.Write([]byte("OK"))
}
func mustGetenv(k string) string {
v := os.Getenv(k)
if v == "" {
log.Panicf("%s environment variable not set.", k)
}
return v
}
It looks like you specified the CONNECTION_NAME, but not the DB_NAME. According to the documentation (scroll down to the "GO > Companion process" section), you should open the connection as:
import (
"github.com/go-sql-driver/mysql"
)
dsn := fmt.Sprintf("%s:%s#tcp(%s)/%s",
dbUser,
dbPassword,
"127.0.0.1:3306",
dbName)
db, err := sql.Open("mysql", dsn)
This piece of code resembles yours, but you did not specify the dbName parameter. Bear in mind that the rest of the configuration should remain the same as you shared in your code, but you should just append the name of your database to the second parameter of the sql.Open() function.
In the example of connecting from App Engine Flexible to Cloud SQL using GO, the same procedure is identified:
db, err = sql.Open("mysql", dbName)
So I guess you should try with this change:
// Old connection opening
db, err = sql.Open("mysql ", fmt.Sprintf("%s:%s#cloudsql(%s)/", user, password, connectionName))
// New connection opening, including dbName
db, err = sql.Open("mysql ", fmt.Sprintf("%s:%s#cloudsql(%s)/%s", user, password, connectionName, dbName))
I am not really familiar with GoLang myself, but according to the documentation, that should work.

Share database connection with packages

I'm new with golang. I'm trying to share mysql database connection in my package, latter maybe in several packages. To skip defining database connection in every package I've created Database package and now I'm trying to get that package, connect to db and use that object in whole package.
I'm using this mysql plugin: github.com/go-sql-driver/mysql
here is my code:
main.go
package main
import (
"log"
"./packages/db" // this is my custom database package
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
var dbType Database.DatabaseType
var db *sql.DB
func main() {
log.Printf("-- entering main...")
dbType := Database.New()
db = dbType.GetDb()
dbType.DbConnect()
delete_test_data()
dbType.DbClose()
}
func delete_test_data(){
log.Printf("-- entering delete_test_data...")
//db.Exec("DELETE FROM test;")
}
packages/db/db.go
package Database
import (
"log"
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
type DatabaseType struct {
DatabaseObject *sql.DB
}
func New()(d *DatabaseType) {
d = new(DatabaseType)
//db.DatabaseObject = db.DbConnect()
return d
}
func (d *DatabaseType) DbConnect() *DatabaseType{
log.Printf("-- entering DbConnect...")
var err error
if d.DatabaseObject == nil {
log.Printf("--------- > Database IS NIL...")
d.DatabaseObject, err = sql.Open("mysql", "...")
if err != nil {
panic(err.Error())
}
err = d.DatabaseObject.Ping()
if err != nil {
panic(err.Error())
}
}
return d
}
func (d *DatabaseType) DbClose(){
log.Printf("-- entering DbClose...")
defer d.DatabaseObject.Close()
}
func (d *DatabaseType) GetDb() *sql.DB{
return d.DatabaseObject
}
Everything is ok and without error until I uncomment this line:
db.Exec("DELETE FROM test;")
Can someone tell me what is correct way to share db connection?
Your dbType.DbConnect() method returns a DatabaseType with an initialized connection, but you're ignoring the return value entirely.
Further - to simplify your code - look at having New(host string) *DB instead of three different functions (New/DbConnect/GetDb) that do the same thing.
e.g.
package datastore
type DB struct {
// Directly embed this
*sql.DB
}
func NewDB(host string) (*DB, error) {
db, err := sql.Open(...)
if err != nil {
return nil, err
}
return &DB{db}, nil
}
package main
var db *datastore.DB
func main() {
var err error
db, err = datastore.NewDB(host)
if err != nil {
log.Fatal(err)
}
err := someFunc()
}
func someFunc() error {
rows, err := db.Exec("DELETE FROM ...")
// Handle the error, parse the result, etc.
}
This reduces the juggling you have to do, and you can still call close on your DB type because it embeds *sql.DB - there's no need to implement your own Close() method.

Can't connect Go to XAMPP MySQL

I'm new to Go.
I'm trying to use MySQL with Go.
I have installed XAMPP which has Apache and MySQL.
I'm also using the database/sql package and github.com/go-sql-driver/mysql driver.
I can't figure out the error. I'm using LiteIDE which doesn't show any error but the record is not inserted to my database.
My code is:
// RESTAPI project main.go
package main
import (
"database/sql"
"encoding/json"
"fmt"
"log"
"net/http"
_ "github.com/go-sql-driver/mysql"
"github.com/gorilla/mux"
)
type API struct {
Message string "json:message"
}
type User struct {
ID int "json:id"
Name string "json:username"
Email string "json:email"
First string "json:first"
Last string "json:last"
}
func CreateUser(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln("Create file")
NewUser := User{}
NewUser.Name = r.FormValue("user")
NewUser.Email = r.FormValue("email")
NewUser.First = r.FormValue("first")
NewUser.Last = r.FormValue("last")
output, err := json.Marshal(NewUser)
fmt.Println(string(output))
if err != nil {
fmt.Println("Something went wrong!")
}
dsn := "root:password#/dbname"
db, err := sql.Open("mysql", dsn)
sql := "INSERT INTO users set user_nickname='" + NewUser.Name + "', user_first='" + NewUser.First + "', user_last='" + NewUser.Last + "', user_email='" + NewUser.Email + "'"
q, err := db.Exec(sql)
if err != nil {
log.Fatal(err)
}
fmt.Println(q)
fmt.Println("User is created")
}
func main() {
routes := mux.NewRouter()
routes.HandleFunc("/api/user/create", CreateUser).Methods("GET")
http.ListenAndServe(":8080", nil)
}
As Tom mentioned, you should check for an error after sql.Open:
db, err := sql.Open("mysql", dsn)
if err != nil {
log.Fatal(err)
}
PS. Never use string concatenations in SQL.
To prevent SQL injections you should use prepared statements:
sql := "INSERT INTO users set user_nickname='?', user_first='?', user_last='?', user_email='?'"
q, err := db.Exec(sql, NewUser.Name, NewUser.First, NewUser.Last, NewUser.Email)

How do I connect to mysql server with Go and go-sql-driver?

I am following the tutorials here and here but I am unable to connect to the test database that came with mySQL installation. I can connect to mySql through the command line. What am I missing? When I run the code below I get the error "cannot ping":
package main
import (
"fmt"
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
func main() {
db, err := sql.Open("mysql", "/test")
if err != nil {
fmt.Println(err)
return
}
defer db.Close()
err = db.Ping()
if err != nil {
fmt.Println("cannot ping")
return
}
}
For example, substitute your MySQL user name and password for the words user and password,
package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
)
func main() {
db, err := sql.Open("mysql", "user:password#/test")
if err != nil {
fmt.Println(err)
return
}
defer db.Close()
err = db.Ping()
if err != nil {
fmt.Println(err)
return
}
fmt.Println("Ping")
}
Output:
Ping