How to get database tables list from MySQL (SHOW TABLES) - mysql

I have a problem with getting database table list (SHOW TABLES) in Go.
I use this packages
database/sql
gopkg.in/gorp.v1
github.com/ziutek/mymysql/godrv
and connect to MYSQL by this code:
db, err := sql.Open(
"mymysql",
"tcp:127.0.0.1:3306*test/root/root")
if err != nil {
panic(err)
}
dbmap := &DbMap{Conn:&gorp.DbMap{Db: db}}
And I use this code to get list of tables
result, _ := dbmap.Exec("SHOW TABLES")
But result is empty!

I use classic go-sql-driver/mysql:
db, _ := sql.Open("mysql", "root:qwerty#/dbname")
res, _ := db.Query("SHOW TABLES")
var table string
for res.Next() {
res.Scan(&table)
fmt.Println(table)
}
PS don't ignore errors! This is only an example

I'm trying this code and work successfully. I create a list of string and use Select query to get list of database tables.
tables := []string{}
dbmap.Select(&tables, "SHOW TABLES")
fmt.Println(tables)

Related

How do you use URL.Query().Get() to fill in a SELECT statement using Golang

func startHandler(w http.ResponseWriter, r *http.Request) {
conn_str := dbuser + ":" + dbpass + "#tcp(" + dbhost + ":" + dbport + ")/" + dbdb
log.Println(conn_str)
db, err := sql.Open("mysql", conn_str)
if err != nil {
log.Println("DB Error - Unable to connect:", err)
}
defer db.Close()
table := r.URL.Query().Get("table")
rows, _ := db.Query("SELECT * FROM "+ table) //selects all columns from table
cols, _ := rows.Columns()
fmt.Fprintf(w, "%s\n", cols)
When i try this, it does not fill in the value that i entered from my website. If i log.Println(table) it does show in my terminal. But it will not display on website or fill in the select statement with table...
Assuming you are calling this from an API, there a few things I would add, not mention avoiding wildcard (*) selects.
EDIT: I think I may have misunderstood your question, I will see if I can give a better answer.
You're saying that you have a printed value for table, but no response from the DB? Other commentor is correct, instead of "_", get a real error and fmt.Println(err.Error()).
EDIT 2: Another good point made by #jub0bs is that this is a huge vulnerability. Go supports this very well by allowing you to do:
db.Query("SELECT * FROM ?",table)
instead of what you have currently.
I just ran the following code:
results,err := publicDB.Query("SELECT * FROM "+r.URL.Query().Get("name"))+" LIMIT 1"
if err != nil {
fmt.Println(err.Error())
}
for results.Next(){
fmt.Println(results.Columns())
}
and it worked. I called the URL www.mysite.com/endpoint?name=tablename

Check if database table exists using golang

I am trying to do a simple thing, check if there is a table, if not then create that table in database.
Here this is the logic I used.
test := "June_2019"
sql_query := `select * from ` + test + `;`
read_err := db.QueryRow(sql_query, 5)
error_returned := read_err.Scan(read_err)
defer db.Close()
if error_returned == nil {
fmt.Println("table is there")
} else {
fmt.Println("table not there")
}
In my database I have June_2019 table. But still this code returns me not nil value. I used db.QueryRow(sql_query, 5) 5 as I have five colomns in my table.
What am I missing here? I am still learning golang.
Thanks in advance.
I have solved the problem using golang and MySQL.
_, table_check := db.Query("select * from " + table + ";")
if table_check == nil {
fmt.Println("table is there")
} else {
fmt.Println("table not there")
}
I have used db.Query() which returns values and and error, here I checked only error.
I think most people thought I want to do it in MySQL way, I just wanted to learn how to use golang to do MySQL operations.

loading multiple entries into sql table using Golang

for _,data := range Array {
stmt, err := db.Prepare(INSERT log SET a=?,b=?,c=?)
checkErr(err)
_, err = stmt.Exec(data.a,data.b,data.c)
checkErr(err)
}
This is the loop to add data into the table but the Go loop iterates faster than mysql can load entries into the table thus only the last few entries are populated, is there any way to load all the sql statements and populate the table at once?

Is it normal to have these many connections in MySQL?

I connect to the database in the init function of a controller, like:
db, err = sql.Open("mysql", "user:pass#tcp(<ip>:3306)/<db>")
if err != nil {
log.Fatal(err)
}
err = db.Ping()
if err != nil {
log.Fatal(err)
}
Then I prepare some statements (db.Prepare) and finally execute them somewhere in the code, without creating new db connections or anything weird. Just letting go handle the connection pool.
But as you can see in the image, I'm getting a lot of connections and aborted connections which make the server run slow and even crash.
Why is it happening? Also I have around 2000 simultaneous online users which result in about 20 queries per second. I don't think it's much, just in case it mattered.
EDIT:
Here's how I run the prepared statements. I have 2 selects, 1 update and 1 insert. Selects are being run like:
err = getStatement.QueryRow(apiKey).Scan(&keyId)
if err != nil {
res, _ := json.Marshal(RespError{"Statement Error"})
w.Write(res)
return
}
Inserts and updates:
insertStatement.Exec(a,b,c)

Golang query multiple databases with a JOIN

Using the golang example below, how can I query (JOIN) multiple databases.
For example, I want to have the relation db1.username.id = db2.comments.username_id.
id := 123
var username string
err := db.QueryRow("SELECT username FROM users WHERE id=?", id).Scan(&username)
switch {
case err == sql.ErrNoRows:
log.Printf("No user with that ID.")
case err != nil:
log.Fatal(err)
default:
fmt.Printf("Username is %s\n", username)
}
As you are using MySQL, you can select fields across databases. See this related question for
details. For example you should be able to do this:
err := db.QueryRow(`
SELECT
db1.users.username
FROM
db1.users
JOIN
db2.comments
ON db1.users.id = db2.comments.username_id
`).Scan(&username)
You can of course simply fetch all entries from db2.comments using a second database connection and use the values in a query to db1.users. This is, of course, not recommended as it is the job of the database server which it can, most likely, do better than you.