mysql - GoLang Dynamic SQL Query in App Engine -
i want make dynamic sql in golang , cant seem find correct way it.
basically, want do:
query := "select id, email, user" var paramvalues []string filterstring := "" if userparams.name != "" { paramstring += " id = ?" paramvalues = append(paramvalues, userparams.name) } if userparams.userid != "" { if len(paramstring) > 0 { paramstring += " and" } else { paramstring += " where" } paramstring += " email = ?" paramvalues = append(paramvalues, userparams.userid) } stmtout, err := db.prepare(query + paramstring) err = stmtout.queryrow(paramvalues).scan(&id, &email, &something)
related building dynamic query in mysql , golang
i've been unable find solid way doesn't allow sql injection. issue above solution queryrow() not take []string parameter.
i want protect sql injection, fmt.sprintf doesn't solve problem.
this way can allow searches on user using either id or email, , use logic different objects more searchable fields.
i'm using go-sql-driver/mysql
here's can run on local machine (go1.8 linux/amd64 , current go mysql driver 1.3).
couple of ways demonstrated.
package main import ( "database/sql" "log" _ "github.com/go-sql-driver/mysql" "fmt" ) // var db *sql.db // var err error /* database name/schema : test123 table name: test table columns , types: number int (primary key) cube int */ func main() { //username root, password root db, err := sql.open("mysql", "root:root@tcp(127.0.0.1:3306)/test123?charset=utf8") if err != nil { fmt.println(err) // needs proper handling per app requirement return } defer db.close() err = db.ping() if err != nil { fmt.println(err) // needs proper handling per app requirement return } //prepared statement inserting data stmtins, err := db.prepare("insert test values( ?, ? )") // ? = placeholders if err != nil { panic(err.error()) // needs proper handling per app requirement } defer stmtins.close() //insert cubes of 1- 10 numbers := 1; < 10; i++ { _, err = stmtins.exec(i, (i * * i)) // insert tuples (i, i^3) if err != nil { panic(err.error()) // proper error handling instead of panic in app } } num := 3 // select statement dataentity := "cube" condition := "where number=? , cube > ?" finalstatement := "select " + dataentity + " test " + condition cubelowerlimit := 10 var mycube int err = db.queryrow(finalstatement, num, cubelowerlimit).scan(&mycube) switch { case err == sql.errnorows: log.printf("no row number %d", num) case err != nil: log.fatal(err) default: fmt.printf("cube %d %d\n", num, mycube) } var cubenum int // //prepared statement reading data stmtread, err := db.prepare(finalstatement) if err != nil { panic(err.error()) // needs proper err handling } defer stmtread.close() // query cube of 5 num = 5 err = stmtread.queryrow(num, cubelowerlimit).scan(&cubenum) switch { case err == sql.errnorows: log.printf("no row number %d", num) case err != nil: log.fatal(err) default: fmt.printf("cube number %d %d\n", num, cubenum) } }
if run subsequent times, need delete rows in database inserts won't create panic (or alternatively change insert rows code doesn't panic). haven't tried on google app engine. hope helps.
Comments
Post a Comment