28
DATABASE/SQL

Go database/sql

Embed Size (px)

DESCRIPTION

I will show how to use Go's database/sql package, with MySQL as an example. Although the documentation is good, it's dense. I'll discuss idiomatic database/sql code, and cover some topics that can save you time and frustration, and perhaps even prevent serious mistakes.

Citation preview

Page 1: Go database/sql

DATABASE/SQL

Page 2: Go database/sql

• github.com/VividCortex

•@xaprb

[email protected]

• linkedin.com/in/xaprb

Optimization, Backups, Replication, and more

Baron Schwartz, Peter Zaitsev &

Vadim Tkachenko

High PerformanceMySQL

3rd Edition

Covers Version 5.5

ME

Page 3: Go database/sql

•Docs: golang.org/pkg/database/sql/

• Tutorial: go-database-sql.org/

•MySQL Driver : github.com/go-sql-driver/mysql/

RESOURCES

Page 4: Go database/sql

THINGS

Page 5: Go database/sql

DB

•Not a connection.

•Open() Close()

•Query() QueryRow() Exec()

Page 6: Go database/sql

ROWS

•Next()

• Scan()

Page 7: Go database/sql

PATTERNS

Page 8: Go database/sql

package main

import (! _ "github.com/go-sql-driver/mysql"! "database/sql"! "log")

func main() {! db, err := sql.Open("mysql",! ! "user:password@tcp(127.0.0.1:3306)/test")! if err != nil {! ! log.Println(err)! }

! // What do we have here?

! defer db.Close()}

Page 9: Go database/sql

var str stringerr = db.QueryRow( "select hello from world where id = 1"). Scan(&str)if err != nil && err != sql.ErrNoRows { log.Println(err)}log.Println(str)

Page 10: Go database/sql

q := "select id, hello from world where id = ?"

rows, err := db.Query(q, 1)if err != nil {! log.Fatal(err)}defer rows.Close()

var id intvar str stringfor rows.Next() {! err = rows.Scan(&id, &str)! if err != nil {! ! log.Fatal(err)! }! // Use the variables scanned from the row}

Page 11: Go database/sql

for rows.Next() {! // scan}

if err = rows.Err(); err != nil { rows.Close() log.Fatal(err)}

Page 12: Go database/sql

stmt, err := db.Prepare(! "select id, hello from world where id = ?")if err != nil {! log.Fatal(err)}defer stmt.Close()

rows, err := stmt.Query(1)if err != nil {! log.Fatal(err)}defer rows.Close()

for rows.Next() {! // ...}

Page 13: Go database/sql

stmt, err := db.Prepare(! "insert into world(hello) values(?)")if err != nil {! log.Fatal(err)}defer stmt.Close()

res, err := stmt.Exec("hello, Dolly")if err != nil {! log.Fatal(err)}

Page 14: Go database/sql

THINGS TO KNOW

Page 15: Go database/sql

THINGS TO KNOW

• There is a connection pool.

• You can’t use uint64 with high bit set in parameters.

Page 16: Go database/sql

DON’T BE LAZY

Page 17: Go database/sql

// Don’t do this!for i := 0; i < 50; i++ {! _, err := db.Query("DELETE FROM hello.world")}

// Use this instead!for i := 0; i < 50; i++ {! _, err := db.Exec("DELETE FROM hello.world")}

Page 18: Go database/sql

MORE HELPFUL ADVICE

•Don’t defer() in long-running functions.

•Don’t use cxn state. Use Tx to bind to a connection.

•Don’t use BEGIN and COMMIT via SQL.

Page 19: Go database/sql

SURPRISES

Page 20: Go database/sql

RETRY. RETRY. RETRY. RETRY. RETRY.RETRY. RETRY. RETRY. RETRY. RETRY.

Page 21: Go database/sql

// Exec executes a query without returning any rows.// The args are for any placeholder parameters in the query.func (db *DB) Exec(query string, args ...interface{}) (Result, error) {! var res Result! var err error! for i := 0; i < 10; i++ {! ! res, err = db.exec(query, args)! ! if err != driver.ErrBadConn {! ! ! break! ! }! }! return res, err}

Page 22: Go database/sql

PREPARED STATEMENTS

Page 23: Go database/sql

NULLThis page intentionally left blank.

Page 24: Go database/sql

var s sql.NullStringerr := db.QueryRow( "SELECT name FROM foo WHERE id=?", id).Scan(&s)

if s.Valid { // use s.String} else { // NULL value}

Page 25: Go database/sql

CUSTOM TYPES

Page 26: Go database/sql

CUSTOM TYPES

• You can implement the Valuer and Scanner interfaces.

•Why? Transparently transform data in <=> out of the DB.

• Compress and uncompress.

•Marshall/unmarshall JSON or another type.

• Encrypt and decrypt.

• See e.g. http://jmoiron.net/blog/built-in-interfaces/

Page 27: Go database/sql

RESOURCES

• http://golang.org/pkg/database/sql/

• http://go-database-sql.org/

• https://github.com/go-sql-driver/mysql

• http://jmoiron.net/blog/

•@VividCortex * not biased, not biased, not biased

Page 28: Go database/sql

IMAGE CREDITS

• http://www.flickr.com/photos/simens/6306917636/

• http://www.flickr.com/photos/dexxus/5794905716/

• http://www.flickr.com/photos/sebastian_bergmann/202396633/

• http://www.flickr.com/photos/doug88888/4794114114/

• http://www.flickr.com/photos/oatsy40/6443878013/

• http://www.sxc.hu/photo/1160562/

• Google Maps (screenshot)

• http://www.flickr.com/photos/estherase/13553883/

• http://www.flickr.com/photos/paperpariah/4150220583/

• http://www.flickr.com/photos/zooboing/4743616313/

• http://www.flickr.com/photos/dseneste/5912382808/

• http://www.flickr.com/photos/clickykbd/66165381/sizes/l/

• http://www.flickr.com/photos/mamnaimie/5576980406/

• https://www.flickr.com/photos/zachstern/87431231