-
Notifications
You must be signed in to change notification settings - Fork 22
/
Copy pathsqlx-sqlite.go
135 lines (118 loc) · 4.37 KB
/
sqlx-sqlite.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
//
// Provides an example of the jmoiron/sqlx data mapping library with sqlite
//
package main
import (
"database/sql"
"fmt"
"github.com/jmoiron/sqlx"
_ "github.com/mattn/go-sqlite3"
"log"
)
var schema = `
DROP TABLE IF EXISTS user;
CREATE TABLE user (
user_id INTEGER PRIMARY KEY,
first_name VARCHAR(80) DEFAULT '',
last_name VARCHAR(80) DEFAULT '',
email VARCHAR(250) DEFAULT '',
password VARCHAR(250) DEFAULT NULL
);
`
type User struct {
UserId int `db:"user_id"`
FirstName string `db:"first_name"`
LastName string `db:"last_name"`
Email string
Password sql.NullString
}
func main() {
// this connects & tries a simple 'SELECT 1', panics on error
// use sqlx.Open() for sql.Open() semantics
db, err := sqlx.Connect("sqlite3", "__deleteme.db")
if err != nil {
log.Fatalln(err)
}
// exec the schema or fail; multi-statement Exec behavior varies between
// database drivers; pq will exec them all, sqlite3 won't, ymmv
db.MustExec(schema)
tx := db.MustBegin()
tx.MustExec("INSERT INTO user (first_name, last_name, email) VALUES ($1, $2, $3)", "Jason", "Moiron", "[email protected]")
tx.MustExec("INSERT INTO user (first_name, last_name, email, password) VALUES ($1, $2, $3, $4)", "John", "Doe", "[email protected]", "supersecret")
// Named queries can use structs, so if you have an existing struct (i.e. person := &User{}) that you have populated, you can pass it in as &person
tx.NamedExec("INSERT INTO user (first_name, last_name, email) VALUES (:first_name, :last_name, :email)", &User{FirstName: "Jane", LastName: "Citizen", Email: "[email protected]"})
tx.Commit()
// Query the database, storing results in a []User (wrapped in []interface{})
people := []User{}
db.Select(&people, "SELECT * FROM user ORDER BY first_name ASC")
jane, jason := people[0], people[1]
fmt.Printf("Jane: %#v\nJason: %#v\n", jane, jason)
// User{FirstName:"Jason", LastName:"Moiron", Email:"[email protected]"}
// User{FirstName:"John", LastName:"Doe", Email:"[email protected]"}
// You can also get a single result, a la QueryRow
jason1 := User{}
err = db.Get(&jason1, "SELECT * FROM user WHERE first_name=$1", "Jason")
fmt.Printf("Jason: %#v\n", jason1)
// User{FirstName:"Jason", LastName:"Moiron", Email:"[email protected]"}
// if you have null fields and use SELECT *, you must use sql.Null* in your struct
users := []User{}
err = db.Select(&users, "SELECT * FROM user ORDER BY email ASC")
if err != nil {
fmt.Println(err)
return
}
jane, jason, john := users[0], users[1], users[2]
fmt.Printf("Jane: %#v\nJason: %#v\nJohn: %#v\n", jane, jason, john)
// Loop through rows using only one struct
user := User{}
rows, err := db.Queryx("SELECT * FROM user WHERE first_name LIKE 'J%'")
for rows.Next() {
err := rows.StructScan(&user)
if err != nil {
log.Fatalln(err)
}
fmt.Printf("%#v\n", user)
}
// Named queries, using `:name` as the bindvar. Automatic bindvar support
// which takes into account the dbtype based on the driverName on sqlx.Open/Connect
_, err = db.NamedExec(`INSERT INTO user (first_name,last_name,email) VALUES (:first,:last,:email)`,
map[string]interface{}{
"first": "Bin",
"last": "Smuth",
"email": "[email protected]",
})
_, err = db.NamedExec(`UPDATE user SET first_name=:first, last_name=:last WHERE first_name = 'Bin'`,
map[string]interface{}{
"first": "Ben",
"last": "Smith",
"email": "[email protected]",
})
// Selects Mr. Smith from the database
rows, err = db.NamedQuery(`SELECT * FROM user WHERE first_name=:fn`, map[string]interface{}{"fn": "Ben"})
for rows.Next() {
err := rows.StructScan(&user)
if err != nil {
log.Fatalln(err)
}
fmt.Printf("Ben: %#v\n", user)
}
// Named queries can also use structs. Their bind names follow the same rules
// as the name -> db mapping, so struct fields are lowercased and the `db` tag
// is taken into consideration.
rows, err = db.NamedQuery(`SELECT * FROM user WHERE first_name=:first_name`, jason)
for rows.Next() {
err := rows.StructScan(&user)
if err != nil {
log.Fatalln(err)
}
fmt.Printf("Jason: %#v\n", user)
}
// fetch one column from the db
rows2, _ := db.Query("SELECT first_name FROM user WHERE last_name = 'Smith'")
// iterate over each row
for rows2.Next() {
var firstName string // if nullable, use the NullString type
err = rows2.Scan(&firstName)
fmt.Printf("Ben: %s\n", firstName)
}
}