-
Notifications
You must be signed in to change notification settings - Fork 27
/
struct_select.go
124 lines (106 loc) · 3.44 KB
/
struct_select.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
package godb
// StructSelect builds a SELECT statement for the given object.
//
// Example (book is a struct instance, books a slice) :
//
// err := db.Select(&book).Where("id = ?", 123).Do()
//
// err = db.Select(&books).Where("id > 1").Where("id < 10").Do()
type StructSelect struct {
error error
selectStatement *SelectStatement
recordDescription *recordDescription
}
// Select initializes a SELECT statement with the given pointer as
// target. The pointer could point to a single instance or a slice.
func (db *DB) Select(record interface{}) *StructSelect {
var err error
ss := &StructSelect{}
ss.recordDescription, err = buildRecordDescription(record)
if err != nil {
ss.error = err
return ss
}
quotedTableName := db.quote(db.defaultTableNamer(ss.recordDescription.getTableName()))
ss.selectStatement = db.SelectFrom(quotedTableName)
return ss
}
// Where adds a condition using string and arguments.
func (ss *StructSelect) Where(sql string, args ...interface{}) *StructSelect {
if ss.error != nil {
return ss
}
ss.selectStatement = ss.selectStatement.WhereQ(Q(sql, args...))
return ss
}
// WhereQ adds a simple or complex predicate generated with Q and
// confunctions.
func (ss *StructSelect) WhereQ(condition *Condition) *StructSelect {
if ss.error != nil {
return ss
}
ss.selectStatement = ss.selectStatement.WhereQ(condition)
return ss
}
// OrderBy adds an expression for the ORDER BY clause.
func (ss *StructSelect) OrderBy(orderBy string) *StructSelect {
if ss.error != nil {
return ss
}
ss.selectStatement = ss.selectStatement.OrderBy(orderBy)
return ss
}
// Offset specifies the value for the OFFSET clause.
func (ss *StructSelect) Offset(offset int) *StructSelect {
if ss.error != nil {
return ss
}
ss.selectStatement = ss.selectStatement.Offset(offset)
return ss
}
// Limit specifies the value for the LIMIT clause.
func (ss *StructSelect) Limit(limit int) *StructSelect {
if ss.error != nil {
return ss
}
ss.selectStatement = ss.selectStatement.Limit(limit)
return ss
}
// Do executes the select statement, the record given to Select will contain
// the data.
func (ss *StructSelect) Do() error {
if ss.error != nil {
return ss.error
}
// Columns names
allColumns := ss.recordDescription.structMapping.GetAllColumnsNames()
ss.selectStatement = ss.selectStatement.Columns(ss.selectStatement.db.quoteAll(allColumns)...)
f := func(record interface{}, columns []string) ([]interface{}, error) {
pointers := ss.recordDescription.structMapping.GetAllFieldsPointers(record)
return pointers, nil
}
return ss.selectStatement.do(ss.recordDescription, f)
}
// Count run the request with COUNT(*) and returns the count
func (ss *StructSelect) Count() (int64, error) {
if ss.error != nil {
return 0, ss.error
}
return ss.selectStatement.Count()
}
// DoWithIterator executes the select query and returns an Iterator allowing
// the caller to fetch rows one at a time.
// Warning : it does not use an existing transation to avoid some pitfalls with
// drivers, nor the prepared statement.
func (ss *StructSelect) DoWithIterator() (Iterator, error) {
if ss.error != nil {
return nil, ss.error
}
allColumns := ss.recordDescription.structMapping.GetAllColumnsNames()
ss.selectStatement = ss.selectStatement.Columns(ss.selectStatement.db.quoteAll(allColumns)...)
sqlQuery, args, err := ss.selectStatement.ToSQL()
if err != nil {
return nil, err
}
return ss.selectStatement.db.doWithIterator(sqlQuery, args)
}