41dd6e58 by slene

orm 1. complete QueryRow/QueryRows api 2. QuerySeter.All support *[]Type and *[]*Type

1 parent 22d2de9f
...@@ -479,15 +479,19 @@ func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condi ...@@ -479,15 +479,19 @@ func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condi
479 ind := reflect.Indirect(val) 479 ind := reflect.Indirect(val)
480 480
481 errTyp := true 481 errTyp := true
482
483 one := true 482 one := true
483 isPtr := true
484 484
485 if val.Kind() == reflect.Ptr { 485 if val.Kind() == reflect.Ptr {
486 fn := "" 486 fn := ""
487 if ind.Kind() == reflect.Slice { 487 if ind.Kind() == reflect.Slice {
488 one = false 488 one = false
489 if ind.Type().Elem().Kind() == reflect.Ptr { 489 typ := ind.Type().Elem()
490 typ := ind.Type().Elem().Elem() 490 switch typ.Kind() {
491 case reflect.Ptr:
492 fn = getFullName(typ.Elem())
493 case reflect.Struct:
494 isPtr = false
491 fn = getFullName(typ) 495 fn = getFullName(typ)
492 } 496 }
493 } else { 497 } else {
...@@ -601,13 +605,21 @@ func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condi ...@@ -601,13 +605,21 @@ func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condi
601 if one { 605 if one {
602 ind.Set(mind) 606 ind.Set(mind)
603 } else { 607 } else {
608 if cnt == 0 {
609 slice = reflect.New(ind.Type()).Elem()
610 }
611
612 if isPtr {
604 slice = reflect.Append(slice, mind.Addr()) 613 slice = reflect.Append(slice, mind.Addr())
614 } else {
615 slice = reflect.Append(slice, mind)
616 }
605 } 617 }
606 } 618 }
607 cnt++ 619 cnt++
608 } 620 }
609 621
610 if one == false { 622 if one == false && cnt > 0 {
611 ind.Set(slice) 623 ind.Set(slice)
612 } 624 }
613 625
......
...@@ -10,6 +10,7 @@ const ( ...@@ -10,6 +10,7 @@ const (
10 od_SET_DEFAULT = "set_default" 10 od_SET_DEFAULT = "set_default"
11 od_DO_NOTHING = "do_nothing" 11 od_DO_NOTHING = "do_nothing"
12 defaultStructTagName = "orm" 12 defaultStructTagName = "orm"
13 defaultStructTagDelim = ";"
13 ) 14 )
14 15
15 var ( 16 var (
......
...@@ -16,7 +16,7 @@ type Data struct { ...@@ -16,7 +16,7 @@ type Data struct {
16 Char string `orm:"size(50)"` 16 Char string `orm:"size(50)"`
17 Text string `orm:"type(text)"` 17 Text string `orm:"type(text)"`
18 Date time.Time `orm:"type(date)"` 18 Date time.Time `orm:"type(date)"`
19 DateTime time.Time 19 DateTime time.Time `orm:"column(datetime)"`
20 Byte byte 20 Byte byte
21 Rune rune 21 Rune rune
22 Int int 22 Int int
...@@ -37,10 +37,10 @@ type Data struct { ...@@ -37,10 +37,10 @@ type Data struct {
37 type DataNull struct { 37 type DataNull struct {
38 Id int 38 Id int
39 Boolean bool `orm:"null"` 39 Boolean bool `orm:"null"`
40 Char string `orm:"size(50);null"` 40 Char string `orm:"null;size(50)"`
41 Text string `orm:"type(text);null"` 41 Text string `orm:"null;type(text)"`
42 Date time.Time `orm:"type(date);null"` 42 Date time.Time `orm:"null;type(date)"`
43 DateTime time.Time `orm:"null"` 43 DateTime time.Time `orm:"null;column(datetime)""`
44 Byte byte `orm:"null"` 44 Byte byte `orm:"null"`
45 Rune rune `orm:"null"` 45 Rune rune `orm:"null"`
46 Int int `orm:"null"` 46 Int int `orm:"null"`
...@@ -174,7 +174,10 @@ var ( ...@@ -174,7 +174,10 @@ var (
174 IsPostgres = DBARGS.Driver == "postgres" 174 IsPostgres = DBARGS.Driver == "postgres"
175 ) 175 )
176 176
177 var dORM Ormer 177 var (
178 dORM Ormer
179 dDbBaser dbBaser
180 )
178 181
179 func init() { 182 func init() {
180 Debug, _ = StrTo(DBARGS.Debug).Bool() 183 Debug, _ = StrTo(DBARGS.Debug).Bool()
......
...@@ -114,7 +114,7 @@ func getFieldType(val reflect.Value) (ft int, err error) { ...@@ -114,7 +114,7 @@ func getFieldType(val reflect.Value) (ft int, err error) {
114 func parseStructTag(data string, attrs *map[string]bool, tags *map[string]string) { 114 func parseStructTag(data string, attrs *map[string]bool, tags *map[string]string) {
115 attr := make(map[string]bool) 115 attr := make(map[string]bool)
116 tag := make(map[string]string) 116 tag := make(map[string]string)
117 for _, v := range strings.Split(data, ";") { 117 for _, v := range strings.Split(data, defaultStructTagDelim) {
118 v = strings.TrimSpace(v) 118 v = strings.TrimSpace(v)
119 if supportTag[v] == 1 { 119 if supportTag[v] == 1 {
120 attr[v] = true 120 attr[v] = true
......
...@@ -4,6 +4,8 @@ import ( ...@@ -4,6 +4,8 @@ import (
4 "database/sql" 4 "database/sql"
5 "fmt" 5 "fmt"
6 "reflect" 6 "reflect"
7 "strings"
8 "time"
7 ) 9 )
8 10
9 type rawPrepare struct { 11 type rawPrepare struct {
...@@ -64,14 +66,362 @@ func (o *rawSet) Exec() (sql.Result, error) { ...@@ -64,14 +66,362 @@ func (o *rawSet) Exec() (sql.Result, error) {
64 return o.orm.db.Exec(query, args...) 66 return o.orm.db.Exec(query, args...)
65 } 67 }
66 68
67 func (o *rawSet) QueryRow(...interface{}) error { 69 func (o *rawSet) setFieldValue(ind reflect.Value, value interface{}) {
68 //TODO 70 switch ind.Kind() {
71 case reflect.Bool:
72 if value == nil {
73 ind.SetBool(false)
74 } else if v, ok := value.(bool); ok {
75 ind.SetBool(v)
76 } else {
77 v, _ := StrTo(ToStr(value)).Bool()
78 ind.SetBool(v)
79 }
80
81 case reflect.String:
82 if value == nil {
83 ind.SetString("")
84 } else {
85 ind.SetString(ToStr(value))
86 }
87
88 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
89 if value == nil {
90 ind.SetInt(0)
91 } else {
92 val := reflect.ValueOf(value)
93 switch val.Kind() {
94 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
95 ind.SetInt(val.Int())
96 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
97 ind.SetInt(int64(val.Uint()))
98 default:
99 v, _ := StrTo(ToStr(value)).Int64()
100 ind.SetInt(v)
101 }
102 }
103 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
104 if value == nil {
105 ind.SetUint(0)
106 } else {
107 val := reflect.ValueOf(value)
108 switch val.Kind() {
109 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
110 ind.SetUint(uint64(val.Int()))
111 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
112 ind.SetUint(val.Uint())
113 default:
114 v, _ := StrTo(ToStr(value)).Uint64()
115 ind.SetUint(v)
116 }
117 }
118 case reflect.Float64, reflect.Float32:
119 if value == nil {
120 ind.SetFloat(0)
121 } else {
122 val := reflect.ValueOf(value)
123 switch val.Kind() {
124 case reflect.Float64:
125 ind.SetFloat(val.Float())
126 default:
127 v, _ := StrTo(ToStr(value)).Float64()
128 ind.SetFloat(v)
129 }
130 }
131
132 case reflect.Struct:
133 if value == nil {
134 ind.Set(reflect.Zero(ind.Type()))
135
136 } else if _, ok := ind.Interface().(time.Time); ok {
137 var str string
138 switch d := value.(type) {
139 case time.Time:
140 o.orm.alias.DbBaser.TimeFromDB(&d, o.orm.alias.TZ)
141 ind.Set(reflect.ValueOf(d))
142 case []byte:
143 str = string(d)
144 case string:
145 str = d
146 }
147 if str != "" {
148 if len(str) >= 19 {
149 str = str[:19]
150 t, err := time.ParseInLocation(format_DateTime, str, o.orm.alias.TZ)
151 if err == nil {
152 t = t.In(DefaultTimeLoc)
153 ind.Set(reflect.ValueOf(t))
154 }
155 } else if len(str) >= 10 {
156 str = str[:10]
157 t, err := time.ParseInLocation(format_Date, str, DefaultTimeLoc)
158 if err == nil {
159 ind.Set(reflect.ValueOf(t))
160 }
161 }
162 }
163 }
164 }
165 }
166
167 func (o *rawSet) loopInitRefs(typ reflect.Type, refsPtr *[]interface{}, sIdxesPtr *[][]int) {
168 sIdxes := *sIdxesPtr
169 refs := *refsPtr
170
171 if typ.Kind() == reflect.Struct {
172 if typ.String() == "time.Time" {
173 var ref interface{}
174 refs = append(refs, &ref)
175 sIdxes = append(sIdxes, []int{0})
176 } else {
177 idxs := []int{}
178 outFor:
179 for idx := 0; idx < typ.NumField(); idx++ {
180 ctyp := typ.Field(idx)
181
182 tag := ctyp.Tag.Get(defaultStructTagName)
183 for _, v := range strings.Split(tag, defaultStructTagDelim) {
184 if v == "-" {
185 continue outFor
186 }
187 }
188
189 tp := ctyp.Type
190 if tp.Kind() == reflect.Ptr {
191 tp = tp.Elem()
192 }
193
194 if tp.String() == "time.Time" {
195 var ref interface{}
196 refs = append(refs, &ref)
197
198 } else if tp.Kind() != reflect.Struct {
199 var ref interface{}
200 refs = append(refs, &ref)
201
202 } else {
203 // skip other type
204 continue
205 }
206
207 idxs = append(idxs, idx)
208 }
209 sIdxes = append(sIdxes, idxs)
210 }
211 } else {
212 var ref interface{}
213 refs = append(refs, &ref)
214 sIdxes = append(sIdxes, []int{0})
215 }
216
217 *sIdxesPtr = sIdxes
218 *refsPtr = refs
219 }
220
221 func (o *rawSet) loopSetRefs(refs []interface{}, sIdxes [][]int, sInds []reflect.Value, nIndsPtr *[]reflect.Value, eTyps []reflect.Type, init bool) {
222 nInds := *nIndsPtr
223
224 cur := 0
225 for i, idxs := range sIdxes {
226 sInd := sInds[i]
227 eTyp := eTyps[i]
228
229 typ := eTyp
230 isPtr := false
231 if typ.Kind() == reflect.Ptr {
232 isPtr = true
233 typ = typ.Elem()
234 }
235 if typ.Kind() == reflect.Ptr {
236 isPtr = true
237 typ = typ.Elem()
238 }
239
240 var nInd reflect.Value
241 if init {
242 nInd = reflect.New(sInd.Type()).Elem()
243 } else {
244 nInd = nInds[i]
245 }
246
247 val := reflect.New(typ)
248 ind := val.Elem()
249
250 tpName := ind.Type().String()
251
252 if ind.Kind() == reflect.Struct {
253 if tpName == "time.Time" {
254 value := reflect.ValueOf(refs[cur]).Elem().Interface()
255 if isPtr && value == nil {
256 val = reflect.New(val.Type()).Elem()
257 } else {
258 o.setFieldValue(ind, value)
259 }
260 cur++
261 } else {
262 hasValue := false
263 for _, idx := range idxs {
264 tind := ind.Field(idx)
265 value := reflect.ValueOf(refs[cur]).Elem().Interface()
266 if value != nil {
267 hasValue = true
268 }
269 if tind.Kind() == reflect.Ptr {
270 if value == nil {
271 tindV := reflect.New(tind.Type()).Elem()
272 tind.Set(tindV)
273 } else {
274 tindV := reflect.New(tind.Type().Elem())
275 o.setFieldValue(tindV.Elem(), value)
276 tind.Set(tindV)
277 }
278 } else {
279 o.setFieldValue(tind, value)
280 }
281 cur++
282 }
283 if hasValue == false && isPtr {
284 val = reflect.New(val.Type()).Elem()
285 }
286 }
287 } else {
288 value := reflect.ValueOf(refs[cur]).Elem().Interface()
289 if isPtr && value == nil {
290 val = reflect.New(val.Type()).Elem()
291 } else {
292 o.setFieldValue(ind, value)
293 }
294 cur++
295 }
296
297 if nInd.Kind() == reflect.Slice {
298 if isPtr {
299 nInd = reflect.Append(nInd, val)
300 } else {
301 nInd = reflect.Append(nInd, ind)
302 }
303 } else {
304 if isPtr {
305 nInd.Set(val)
306 } else {
307 nInd.Set(ind)
308 }
309 }
310
311 nInds[i] = nInd
312 }
313 }
314
315 func (o *rawSet) QueryRow(containers ...interface{}) error {
316 if len(containers) == 0 {
317 panic("<RawSeter.QueryRow> need at least one arg")
318 }
319
320 refs := make([]interface{}, 0, len(containers))
321 sIdxes := make([][]int, 0)
322 sInds := make([]reflect.Value, 0)
323 eTyps := make([]reflect.Type, 0)
324
325 for _, container := range containers {
326 val := reflect.ValueOf(container)
327 ind := reflect.Indirect(val)
328
329 if val.Kind() != reflect.Ptr {
330 panic("<RawSeter.QueryRow> all args must be use ptr")
331 }
332
333 etyp := ind.Type()
334 typ := etyp
335 if typ.Kind() == reflect.Ptr {
336 typ = typ.Elem()
337 }
338 if typ.Kind() == reflect.Ptr {
339 typ = typ.Elem()
340 }
341
342 sInds = append(sInds, ind)
343 eTyps = append(eTyps, etyp)
344
345 o.loopInitRefs(typ, &refs, &sIdxes)
346 }
347
348 query := o.query
349 o.orm.alias.DbBaser.ReplaceMarks(&query)
350
351 args := getFlatParams(nil, o.args, o.orm.alias.TZ)
352 row := o.orm.db.QueryRow(query, args...)
353
354 if err := row.Scan(refs...); err == sql.ErrNoRows {
355 return ErrNoRows
356 } else if err != nil {
357 return err
358 }
359
360 nInds := make([]reflect.Value, len(sInds))
361 o.loopSetRefs(refs, sIdxes, sInds, &nInds, eTyps, true)
362 for i, sInd := range sInds {
363 nInd := nInds[i]
364 sInd.Set(nInd)
365 }
366
69 return nil 367 return nil
70 } 368 }
71 369
72 func (o *rawSet) QueryRows(...interface{}) (int64, error) { 370 func (o *rawSet) QueryRows(containers ...interface{}) (int64, error) {
73 //TODO 371 refs := make([]interface{}, 0)
74 return 0, nil 372 sIdxes := make([][]int, 0)
373 sInds := make([]reflect.Value, 0)
374 eTyps := make([]reflect.Type, 0)
375
376 for _, container := range containers {
377 val := reflect.ValueOf(container)
378 sInd := reflect.Indirect(val)
379 if val.Kind() != reflect.Ptr || sInd.Kind() != reflect.Slice {
380 panic("<RawSeter.QueryRows> all args must be use ptr slice")
381 }
382
383 etyp := sInd.Type().Elem()
384 typ := etyp
385 if typ.Kind() == reflect.Ptr {
386 typ = typ.Elem()
387 }
388
389 sInds = append(sInds, sInd)
390 eTyps = append(eTyps, etyp)
391
392 o.loopInitRefs(typ, &refs, &sIdxes)
393 }
394
395 query := o.query
396 o.orm.alias.DbBaser.ReplaceMarks(&query)
397
398 args := getFlatParams(nil, o.args, o.orm.alias.TZ)
399 rows, err := o.orm.db.Query(query, args...)
400 if err != nil {
401 return 0, err
402 }
403
404 nInds := make([]reflect.Value, len(sInds))
405
406 var cnt int64
407 for rows.Next() {
408 if err := rows.Scan(refs...); err != nil {
409 return 0, err
410 }
411
412 o.loopSetRefs(refs, sIdxes, sInds, &nInds, eTyps, cnt == 0)
413
414 cnt++
415 }
416
417 if cnt > 0 {
418 for i, sInd := range sInds {
419 nInd := nInds[i]
420 sInd.Set(nInd)
421 }
422 }
423
424 return cnt, nil
75 } 425 }
76 426
77 func (o *rawSet) readValues(container interface{}) (int64, error) { 427 func (o *rawSet) readValues(container interface{}) (int64, error) {
......
...@@ -115,6 +115,8 @@ func ToStr(value interface{}, args ...int) (s string) { ...@@ -115,6 +115,8 @@ func ToStr(value interface{}, args ...int) (s string) {
115 s = strconv.FormatUint(v, argInt(args).Get(0, 10)) 115 s = strconv.FormatUint(v, argInt(args).Get(0, 10))
116 case string: 116 case string:
117 s = v 117 s = v
118 case []byte:
119 s = string(v)
118 default: 120 default:
119 s = fmt.Sprintf("%v", v) 121 s = fmt.Sprintf("%v", v)
120 } 122 }
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!