github.com/fragmenta/query@v1.5.3/adapters/database_mysql.go (about) 1 package adapters 2 3 import ( 4 "database/sql" 5 "fmt" 6 7 // Mysql driver 8 _ "github.com/go-sql-driver/mysql" 9 ) 10 11 // MysqlAdapter conforms to the query.Database interface 12 type MysqlAdapter struct { 13 *Adapter 14 options map[string]string 15 sqlDB *sql.DB 16 debug bool 17 } 18 19 // Open this database 20 func (db *MysqlAdapter) Open(opts map[string]string) error { 21 22 db.debug = false 23 db.options = map[string]string{ 24 "adapter": "mysql", 25 "user": "root", // sub your user 26 "password": "", 27 "db": "query_test", 28 "protocol": "tcp", 29 "host": "localhost", 30 "port": "3306", 31 "params": "charset=utf8&parseTime=true", 32 } 33 34 if opts["debug"] == "true" { 35 db.debug = true 36 } 37 38 // Merge options 39 for k, v := range opts { 40 db.options[k] = v 41 } 42 43 // A typical connection string is of the form: 44 //"user:password@tcp(localhost:3306)/dbname?charset=utf8&parseTime=true") 45 options := fmt.Sprintf("%s:%s@%s(%s:%s)/%s?%s", 46 db.options["user"], 47 db.options["password"], 48 db.options["protocol"], 49 db.options["host"], 50 db.options["port"], 51 db.options["db"], 52 db.options["params"]) 53 54 var err error 55 db.sqlDB, err = sql.Open(db.options["adapter"], options) 56 if err != nil { 57 return err 58 } 59 60 if db.sqlDB == nil { 61 fmt.Printf("Mysql options:%s", options) 62 return fmt.Errorf("\nError creating database with options: %v", db.options) 63 } 64 65 // Call ping on the db to check it does actually exist! 66 err = db.sqlDB.Ping() 67 if err != nil { 68 return err 69 } 70 71 return err 72 73 } 74 75 // Close the database 76 func (db *MysqlAdapter) Close() error { 77 if db.sqlDB != nil { 78 return db.sqlDB.Close() 79 } 80 return nil 81 } 82 83 // SQLDB returns the internal db.sqlDB pointer 84 func (db *MysqlAdapter) SQLDB() *sql.DB { 85 return db.sqlDB 86 } 87 88 // Query SQL execute - NB caller must call use defer rows.Close() with rows returned 89 func (db *MysqlAdapter) Query(query string, args ...interface{}) (*sql.Rows, error) { 90 return db.performQuery(db.sqlDB, db.debug, query, args...) 91 } 92 93 // Exec - use this for non-select statements 94 func (db *MysqlAdapter) Exec(query string, args ...interface{}) (sql.Result, error) { 95 return db.performExec(db.sqlDB, db.debug, query, args...) 96 } 97 98 // QuoteField quotes a table name or column name 99 func (db *MysqlAdapter) QuoteField(name string) string { 100 return fmt.Sprintf("`%s`", name) 101 } 102 103 // Insert a record with params and return the id - psql behaves differently 104 func (db *MysqlAdapter) Insert(query string, args ...interface{}) (id int64, err error) { 105 106 tx, err := db.sqlDB.Begin() 107 if err != nil { 108 return 0, err 109 } 110 111 // Execute the sql using db 112 result, err := db.Exec(query, args...) 113 if err != nil { 114 return 0, err 115 } 116 117 // TODO - check this works on mysql under load with concurrent connections 118 // fine if connection not shared 119 id, err = result.LastInsertId() 120 if err != nil { 121 return 0, err 122 } 123 124 err = tx.Commit() 125 if err != nil { 126 return 0, err 127 } 128 129 return id, nil 130 131 }