-
Notifications
You must be signed in to change notification settings - Fork 8
/
doc.go
66 lines (52 loc) · 2.15 KB
/
doc.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
/*
Package crud provides a reflection-based wrapper around database/sql for common operations.
crud allows you to annotate struct fields with corresponding SQL field names.
Types annotated as such can then be easily inserted/updated/scanned from
sql/database connections without incurring the usual programmer overhead.
crud does not handle schema generation; it simply reduces the amount of
boilerplate you'd need to write to interact with an existing schema.
Consider this case:
type Foo struct {
Id int64 `crud:"foo_id"`
Num int64 `crud:"foo_num"`
Str string `crud:"foo_str"`
Time time.Time `crud:"foo_time"`
UnixTime time.Time `crud:"foo_unix_time,unix"`
}
And this existing schema:
CREATE TABLE foo
( foo_id INTEGER PRIMARY KEY
, foo_num INTEGER NOT NULL
, foo_str VARCHAR(24) NOT NULL
, foo_time TIMESTAMP NOT NULL
, foo_unix_time INTEGER NOT NULL
);
With vanilla database/sql, to extract values from an *sql.Rows you have to do a
considerable amount of hoop-jumping:
// old code
rows, _ := db.Query("SELECT foo_id, foo_num, foo_str, foo_time, foo_unix_time FROM foos")
defer rows.Close()
foos := []Foos{}
for rows.Next() {
var foo Foo
rows.Scan(&foo.Id, &foo.Num, &foo.Str, &foo.Time, &foo.UnixTime)
foos = append(foos, foo)
}
With a significant number of columns to extract one-by-one (or extracting
multiple objects from, e.g., a complex query with lots of JOINs) the amount of
noisy code increases significantly. crud provides the following alternative:
// new code
rows, _ := db.Query("SELECT * FROM foos")
foos := []Foos{}
crud.ScanAll(rows, &foos)
The magic of reflection handles the rest.
Each struct field that has a corresponding SQL row must be tagged with the SQL
row name. For time types, the "unix" tag can be used to trigger marshalling between
the Go time.Time type and a numeric SQL field.
Any pointer fields with a corresponding sql.Null* type are marshalled to/from
the Null type for proper interaction with database/sql.
Despite the wonder, crud is not without drawbacks. As with all interfaces that
use reflection internally, you lose both performance (untested as to how much)
and type safety.
*/
package crud