27b84841 by slene

orm add full regular go type support, such as int8, uint8, byte, rune. add date/…

…datetime timezone support very well.
1 parent deb00809
...@@ -49,7 +49,7 @@ type dbBase struct { ...@@ -49,7 +49,7 @@ type dbBase struct {
49 ins dbBaser 49 ins dbBaser
50 } 50 }
51 51
52 func (d *dbBase) collectValues(mi *modelInfo, ind reflect.Value, skipAuto bool, insert bool) (columns []string, values []interface{}, err error) { 52 func (d *dbBase) collectValues(mi *modelInfo, ind reflect.Value, skipAuto bool, insert bool, tz *time.Location) (columns []string, values []interface{}, err error) {
53 _, pkValue, _ := getExistPk(mi, ind) 53 _, pkValue, _ := getExistPk(mi, ind)
54 for _, column := range mi.fields.orders { 54 for _, column := range mi.fields.orders {
55 fi := mi.fields.columns[column] 55 fi := mi.fields.columns[column]
...@@ -71,9 +71,22 @@ func (d *dbBase) collectValues(mi *modelInfo, ind reflect.Value, skipAuto bool, ...@@ -71,9 +71,22 @@ func (d *dbBase) collectValues(mi *modelInfo, ind reflect.Value, skipAuto bool,
71 case TypeCharField, TypeTextField: 71 case TypeCharField, TypeTextField:
72 value = field.String() 72 value = field.String()
73 case TypeFloatField, TypeDecimalField: 73 case TypeFloatField, TypeDecimalField:
74 vu := field.Interface()
75 if _, ok := vu.(float32); ok {
76 value, _ = StrTo(ToStr(vu)).Float64()
77 } else {
74 value = field.Float() 78 value = field.Float()
79 }
75 case TypeDateField, TypeDateTimeField: 80 case TypeDateField, TypeDateTimeField:
76 value = field.Interface() 81 value = field.Interface()
82 if t, ok := value.(time.Time); ok {
83 if fi.fieldType == TypeDateField {
84 d.ins.TimeToDB(&t, DefaultTimeLoc)
85 } else {
86 d.ins.TimeToDB(&t, tz)
87 }
88 value = t
89 }
77 default: 90 default:
78 switch { 91 switch {
79 case fi.fieldType&IsPostiveIntegerField > 0: 92 case fi.fieldType&IsPostiveIntegerField > 0:
...@@ -101,15 +114,16 @@ func (d *dbBase) collectValues(mi *modelInfo, ind reflect.Value, skipAuto bool, ...@@ -101,15 +114,16 @@ func (d *dbBase) collectValues(mi *modelInfo, ind reflect.Value, skipAuto bool,
101 if fi.auto_now || fi.auto_now_add && insert { 114 if fi.auto_now || fi.auto_now_add && insert {
102 tnow := time.Now() 115 tnow := time.Now()
103 if fi.fieldType == TypeDateField { 116 if fi.fieldType == TypeDateField {
104 value = timeFormat(tnow, format_Date) 117 d.ins.TimeToDB(&tnow, DefaultTimeLoc)
105 } else { 118 } else {
106 value = timeFormat(tnow, format_DateTime) 119 d.ins.TimeToDB(&tnow, tz)
107 } 120 }
121 value = tnow
108 if fi.isFielder { 122 if fi.isFielder {
109 f := field.Addr().Interface().(Fielder) 123 f := field.Addr().Interface().(Fielder)
110 f.SetRaw(tnow) 124 f.SetRaw(tnow.In(DefaultTimeLoc))
111 } else { 125 } else {
112 field.Set(reflect.ValueOf(tnow)) 126 field.Set(reflect.ValueOf(tnow.In(DefaultTimeLoc)))
113 } 127 }
114 } 128 }
115 } 129 }
...@@ -145,8 +159,8 @@ func (d *dbBase) PrepareInsert(q dbQuerier, mi *modelInfo) (stmtQuerier, string, ...@@ -145,8 +159,8 @@ func (d *dbBase) PrepareInsert(q dbQuerier, mi *modelInfo) (stmtQuerier, string,
145 return stmt, query, err 159 return stmt, query, err
146 } 160 }
147 161
148 func (d *dbBase) InsertStmt(stmt stmtQuerier, mi *modelInfo, ind reflect.Value) (int64, error) { 162 func (d *dbBase) InsertStmt(stmt stmtQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location) (int64, error) {
149 _, values, err := d.collectValues(mi, ind, true, true) 163 _, values, err := d.collectValues(mi, ind, true, true, tz)
150 if err != nil { 164 if err != nil {
151 return 0, err 165 return 0, err
152 } 166 }
...@@ -165,7 +179,7 @@ func (d *dbBase) InsertStmt(stmt stmtQuerier, mi *modelInfo, ind reflect.Value) ...@@ -165,7 +179,7 @@ func (d *dbBase) InsertStmt(stmt stmtQuerier, mi *modelInfo, ind reflect.Value)
165 } 179 }
166 } 180 }
167 181
168 func (d *dbBase) Read(q dbQuerier, mi *modelInfo, ind reflect.Value) error { 182 func (d *dbBase) Read(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location) error {
169 pkColumn, pkValue, ok := getExistPk(mi, ind) 183 pkColumn, pkValue, ok := getExistPk(mi, ind)
170 if ok == false { 184 if ok == false {
171 return ErrMissPK 185 return ErrMissPK
...@@ -187,6 +201,10 @@ func (d *dbBase) Read(q dbQuerier, mi *modelInfo, ind reflect.Value) error { ...@@ -187,6 +201,10 @@ func (d *dbBase) Read(q dbQuerier, mi *modelInfo, ind reflect.Value) error {
187 201
188 d.ins.ReplaceMarks(&query) 202 d.ins.ReplaceMarks(&query)
189 203
204 if len(refs) == 21 {
205 fmt.Println(query, pkValue)
206 }
207
190 row := q.QueryRow(query, pkValue) 208 row := q.QueryRow(query, pkValue)
191 if err := row.Scan(refs...); err != nil { 209 if err := row.Scan(refs...); err != nil {
192 if err == sql.ErrNoRows { 210 if err == sql.ErrNoRows {
...@@ -197,7 +215,7 @@ func (d *dbBase) Read(q dbQuerier, mi *modelInfo, ind reflect.Value) error { ...@@ -197,7 +215,7 @@ func (d *dbBase) Read(q dbQuerier, mi *modelInfo, ind reflect.Value) error {
197 elm := reflect.New(mi.addrField.Elem().Type()) 215 elm := reflect.New(mi.addrField.Elem().Type())
198 mind := reflect.Indirect(elm) 216 mind := reflect.Indirect(elm)
199 217
200 d.setColsValues(mi, &mind, mi.fields.dbcols, refs) 218 d.setColsValues(mi, &mind, mi.fields.dbcols, refs, tz)
201 219
202 ind.Set(mind) 220 ind.Set(mind)
203 } 221 }
...@@ -205,8 +223,8 @@ func (d *dbBase) Read(q dbQuerier, mi *modelInfo, ind reflect.Value) error { ...@@ -205,8 +223,8 @@ func (d *dbBase) Read(q dbQuerier, mi *modelInfo, ind reflect.Value) error {
205 return nil 223 return nil
206 } 224 }
207 225
208 func (d *dbBase) Insert(q dbQuerier, mi *modelInfo, ind reflect.Value) (int64, error) { 226 func (d *dbBase) Insert(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location) (int64, error) {
209 names, values, err := d.collectValues(mi, ind, true, true) 227 names, values, err := d.collectValues(mi, ind, true, true, tz)
210 if err != nil { 228 if err != nil {
211 return 0, err 229 return 0, err
212 } 230 }
...@@ -240,12 +258,12 @@ func (d *dbBase) Insert(q dbQuerier, mi *modelInfo, ind reflect.Value) (int64, e ...@@ -240,12 +258,12 @@ func (d *dbBase) Insert(q dbQuerier, mi *modelInfo, ind reflect.Value) (int64, e
240 } 258 }
241 } 259 }
242 260
243 func (d *dbBase) Update(q dbQuerier, mi *modelInfo, ind reflect.Value) (int64, error) { 261 func (d *dbBase) Update(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location) (int64, error) {
244 pkName, pkValue, ok := getExistPk(mi, ind) 262 pkName, pkValue, ok := getExistPk(mi, ind)
245 if ok == false { 263 if ok == false {
246 return 0, ErrMissPK 264 return 0, ErrMissPK
247 } 265 }
248 setNames, setValues, err := d.collectValues(mi, ind, true, false) 266 setNames, setValues, err := d.collectValues(mi, ind, true, false, tz)
249 if err != nil { 267 if err != nil {
250 return 0, err 268 return 0, err
251 } 269 }
...@@ -269,7 +287,7 @@ func (d *dbBase) Update(q dbQuerier, mi *modelInfo, ind reflect.Value) (int64, e ...@@ -269,7 +287,7 @@ func (d *dbBase) Update(q dbQuerier, mi *modelInfo, ind reflect.Value) (int64, e
269 return 0, nil 287 return 0, nil
270 } 288 }
271 289
272 func (d *dbBase) Delete(q dbQuerier, mi *modelInfo, ind reflect.Value) (int64, error) { 290 func (d *dbBase) Delete(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location) (int64, error) {
273 pkName, pkValue, ok := getExistPk(mi, ind) 291 pkName, pkValue, ok := getExistPk(mi, ind)
274 if ok == false { 292 if ok == false {
275 return 0, ErrMissPK 293 return 0, ErrMissPK
...@@ -293,7 +311,7 @@ func (d *dbBase) Delete(q dbQuerier, mi *modelInfo, ind reflect.Value) (int64, e ...@@ -293,7 +311,7 @@ func (d *dbBase) Delete(q dbQuerier, mi *modelInfo, ind reflect.Value) (int64, e
293 ind.Field(mi.fields.pk.fieldIndex).SetInt(0) 311 ind.Field(mi.fields.pk.fieldIndex).SetInt(0)
294 } 312 }
295 313
296 err := d.deleteRels(q, mi, []interface{}{pkValue}) 314 err := d.deleteRels(q, mi, []interface{}{pkValue}, tz)
297 if err != nil { 315 if err != nil {
298 return num, err 316 return num, err
299 } 317 }
...@@ -306,7 +324,7 @@ func (d *dbBase) Delete(q dbQuerier, mi *modelInfo, ind reflect.Value) (int64, e ...@@ -306,7 +324,7 @@ func (d *dbBase) Delete(q dbQuerier, mi *modelInfo, ind reflect.Value) (int64, e
306 return 0, nil 324 return 0, nil
307 } 325 }
308 326
309 func (d *dbBase) UpdateBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition, params Params) (int64, error) { 327 func (d *dbBase) UpdateBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition, params Params, tz *time.Location) (int64, error) {
310 columns := make([]string, 0, len(params)) 328 columns := make([]string, 0, len(params))
311 values := make([]interface{}, 0, len(params)) 329 values := make([]interface{}, 0, len(params))
312 for col, val := range params { 330 for col, val := range params {
...@@ -327,7 +345,7 @@ func (d *dbBase) UpdateBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Con ...@@ -327,7 +345,7 @@ func (d *dbBase) UpdateBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Con
327 tables.parseRelated(qs.related, qs.relDepth) 345 tables.parseRelated(qs.related, qs.relDepth)
328 } 346 }
329 347
330 where, args := tables.getCondSql(cond, false) 348 where, args := tables.getCondSql(cond, false, tz)
331 349
332 values = append(values, args...) 350 values = append(values, args...)
333 351
...@@ -356,13 +374,13 @@ func (d *dbBase) UpdateBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Con ...@@ -356,13 +374,13 @@ func (d *dbBase) UpdateBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Con
356 return 0, nil 374 return 0, nil
357 } 375 }
358 376
359 func (d *dbBase) deleteRels(q dbQuerier, mi *modelInfo, args []interface{}) error { 377 func (d *dbBase) deleteRels(q dbQuerier, mi *modelInfo, args []interface{}, tz *time.Location) error {
360 for _, fi := range mi.fields.fieldsReverse { 378 for _, fi := range mi.fields.fieldsReverse {
361 fi = fi.reverseFieldInfo 379 fi = fi.reverseFieldInfo
362 switch fi.onDelete { 380 switch fi.onDelete {
363 case od_CASCADE: 381 case od_CASCADE:
364 cond := NewCondition().And(fmt.Sprintf("%s__in", fi.name), args...) 382 cond := NewCondition().And(fmt.Sprintf("%s__in", fi.name), args...)
365 _, err := d.DeleteBatch(q, nil, fi.mi, cond) 383 _, err := d.DeleteBatch(q, nil, fi.mi, cond, tz)
366 if err != nil { 384 if err != nil {
367 return err 385 return err
368 } 386 }
...@@ -372,7 +390,7 @@ func (d *dbBase) deleteRels(q dbQuerier, mi *modelInfo, args []interface{}) erro ...@@ -372,7 +390,7 @@ func (d *dbBase) deleteRels(q dbQuerier, mi *modelInfo, args []interface{}) erro
372 if fi.onDelete == od_SET_DEFAULT { 390 if fi.onDelete == od_SET_DEFAULT {
373 params[fi.column] = fi.initial.String() 391 params[fi.column] = fi.initial.String()
374 } 392 }
375 _, err := d.UpdateBatch(q, nil, fi.mi, cond, params) 393 _, err := d.UpdateBatch(q, nil, fi.mi, cond, params, tz)
376 if err != nil { 394 if err != nil {
377 return err 395 return err
378 } 396 }
...@@ -382,7 +400,7 @@ func (d *dbBase) deleteRels(q dbQuerier, mi *modelInfo, args []interface{}) erro ...@@ -382,7 +400,7 @@ func (d *dbBase) deleteRels(q dbQuerier, mi *modelInfo, args []interface{}) erro
382 return nil 400 return nil
383 } 401 }
384 402
385 func (d *dbBase) DeleteBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition) (int64, error) { 403 func (d *dbBase) DeleteBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition, tz *time.Location) (int64, error) {
386 tables := newDbTables(mi, d.ins) 404 tables := newDbTables(mi, d.ins)
387 if qs != nil { 405 if qs != nil {
388 tables.parseRelated(qs.related, qs.relDepth) 406 tables.parseRelated(qs.related, qs.relDepth)
...@@ -394,7 +412,7 @@ func (d *dbBase) DeleteBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Con ...@@ -394,7 +412,7 @@ func (d *dbBase) DeleteBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Con
394 412
395 Q := d.ins.TableQuote() 413 Q := d.ins.TableQuote()
396 414
397 where, args := tables.getCondSql(cond, false) 415 where, args := tables.getCondSql(cond, false, tz)
398 join := tables.getJoinSql() 416 join := tables.getJoinSql()
399 417
400 cols := fmt.Sprintf("T0.%s%s%s", Q, mi.fields.pk.column, Q) 418 cols := fmt.Sprintf("T0.%s%s%s", Q, mi.fields.pk.column, Q)
...@@ -425,7 +443,11 @@ func (d *dbBase) DeleteBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Con ...@@ -425,7 +443,11 @@ func (d *dbBase) DeleteBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Con
425 return 0, nil 443 return 0, nil
426 } 444 }
427 445
428 sql, args := d.ins.GenerateOperatorSql(mi, mi.fields.pk, "in", args) 446 marks := make([]string, len(args))
447 for i, _ := range marks {
448 marks[i] = "?"
449 }
450 sql := fmt.Sprintf("IN (%s)", strings.Join(marks, ", "))
429 query = fmt.Sprintf("DELETE FROM %s%s%s WHERE %s%s%s %s", Q, mi.table, Q, Q, mi.fields.pk.column, Q, sql) 451 query = fmt.Sprintf("DELETE FROM %s%s%s WHERE %s%s%s %s", Q, mi.table, Q, Q, mi.fields.pk.column, Q, sql)
430 452
431 d.ins.ReplaceMarks(&query) 453 d.ins.ReplaceMarks(&query)
...@@ -437,7 +459,7 @@ func (d *dbBase) DeleteBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Con ...@@ -437,7 +459,7 @@ func (d *dbBase) DeleteBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Con
437 } 459 }
438 460
439 if num > 0 { 461 if num > 0 {
440 err := d.deleteRels(q, mi, args) 462 err := d.deleteRels(q, mi, args, tz)
441 if err != nil { 463 if err != nil {
442 return num, err 464 return num, err
443 } 465 }
...@@ -451,7 +473,7 @@ func (d *dbBase) DeleteBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Con ...@@ -451,7 +473,7 @@ func (d *dbBase) DeleteBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Con
451 return 0, nil 473 return 0, nil
452 } 474 }
453 475
454 func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition, container interface{}) (int64, error) { 476 func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition, container interface{}, tz *time.Location) (int64, error) {
455 477
456 val := reflect.ValueOf(container) 478 val := reflect.ValueOf(container)
457 ind := reflect.Indirect(val) 479 ind := reflect.Indirect(val)
...@@ -490,7 +512,7 @@ func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condi ...@@ -490,7 +512,7 @@ func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condi
490 tables := newDbTables(mi, d.ins) 512 tables := newDbTables(mi, d.ins)
491 tables.parseRelated(qs.related, qs.relDepth) 513 tables.parseRelated(qs.related, qs.relDepth)
492 514
493 where, args := tables.getCondSql(cond, false) 515 where, args := tables.getCondSql(cond, false, tz)
494 orderBy := tables.getOrderSql(qs.orders) 516 orderBy := tables.getOrderSql(qs.orders)
495 limit := tables.getLimitSql(mi, offset, rlimit) 517 limit := tables.getLimitSql(mi, offset, rlimit)
496 join := tables.getJoinSql() 518 join := tables.getJoinSql()
...@@ -539,7 +561,7 @@ func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condi ...@@ -539,7 +561,7 @@ func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condi
539 cacheM := make(map[string]*modelInfo) 561 cacheM := make(map[string]*modelInfo)
540 trefs := refs 562 trefs := refs
541 563
542 d.setColsValues(mi, &mind, mi.fields.dbcols, refs[:len(mi.fields.dbcols)]) 564 d.setColsValues(mi, &mind, mi.fields.dbcols, refs[:len(mi.fields.dbcols)], tz)
543 trefs = refs[len(mi.fields.dbcols):] 565 trefs = refs[len(mi.fields.dbcols):]
544 566
545 for _, tbl := range tables.tables { 567 for _, tbl := range tables.tables {
...@@ -558,7 +580,7 @@ func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condi ...@@ -558,7 +580,7 @@ func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condi
558 mmi := fi.relModelInfo 580 mmi := fi.relModelInfo
559 field := reflect.Indirect(last.Field(fi.fieldIndex)) 581 field := reflect.Indirect(last.Field(fi.fieldIndex))
560 if field.IsValid() { 582 if field.IsValid() {
561 d.setColsValues(mmi, &field, mmi.fields.dbcols, trefs[:len(mmi.fields.dbcols)]) 583 d.setColsValues(mmi, &field, mmi.fields.dbcols, trefs[:len(mmi.fields.dbcols)], tz)
562 for _, fi := range mmi.fields.fieldsReverse { 584 for _, fi := range mmi.fields.fieldsReverse {
563 if fi.reverseFieldInfo.mi == lastm { 585 if fi.reverseFieldInfo.mi == lastm {
564 if fi.reverseFieldInfo != nil { 586 if fi.reverseFieldInfo != nil {
...@@ -592,11 +614,11 @@ func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condi ...@@ -592,11 +614,11 @@ func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condi
592 return cnt, nil 614 return cnt, nil
593 } 615 }
594 616
595 func (d *dbBase) Count(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition) (cnt int64, err error) { 617 func (d *dbBase) Count(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition, tz *time.Location) (cnt int64, err error) {
596 tables := newDbTables(mi, d.ins) 618 tables := newDbTables(mi, d.ins)
597 tables.parseRelated(qs.related, qs.relDepth) 619 tables.parseRelated(qs.related, qs.relDepth)
598 620
599 where, args := tables.getCondSql(cond, false) 621 where, args := tables.getCondSql(cond, false, tz)
600 tables.getOrderSql(qs.orders) 622 tables.getOrderSql(qs.orders)
601 join := tables.getJoinSql() 623 join := tables.getJoinSql()
602 624
...@@ -612,9 +634,9 @@ func (d *dbBase) Count(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition ...@@ -612,9 +634,9 @@ func (d *dbBase) Count(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition
612 return 634 return
613 } 635 }
614 636
615 func (d *dbBase) GenerateOperatorSql(mi *modelInfo, fi *fieldInfo, operator string, args []interface{}) (string, []interface{}) { 637 func (d *dbBase) GenerateOperatorSql(mi *modelInfo, fi *fieldInfo, operator string, args []interface{}, tz *time.Location) (string, []interface{}) {
616 sql := "" 638 sql := ""
617 params := getFlatParams(fi, args) 639 params := getFlatParams(fi, args, tz)
618 640
619 if len(params) == 0 { 641 if len(params) == 0 {
620 panic(fmt.Sprintf("operator `%s` need at least one args", operator)) 642 panic(fmt.Sprintf("operator `%s` need at least one args", operator))
...@@ -665,11 +687,11 @@ func (d *dbBase) GenerateOperatorSql(mi *modelInfo, fi *fieldInfo, operator stri ...@@ -665,11 +687,11 @@ func (d *dbBase) GenerateOperatorSql(mi *modelInfo, fi *fieldInfo, operator stri
665 return sql, params 687 return sql, params
666 } 688 }
667 689
668 func (d *dbBase) GenerateOperatorLeftCol(string, *string) { 690 func (d *dbBase) GenerateOperatorLeftCol(*fieldInfo, string, *string) {
669 691 // default not use
670 } 692 }
671 693
672 func (d *dbBase) setColsValues(mi *modelInfo, ind *reflect.Value, cols []string, values []interface{}) { 694 func (d *dbBase) setColsValues(mi *modelInfo, ind *reflect.Value, cols []string, values []interface{}, tz *time.Location) {
673 for i, column := range cols { 695 for i, column := range cols {
674 val := reflect.Indirect(reflect.ValueOf(values[i])).Interface() 696 val := reflect.Indirect(reflect.ValueOf(values[i])).Interface()
675 697
...@@ -677,12 +699,12 @@ func (d *dbBase) setColsValues(mi *modelInfo, ind *reflect.Value, cols []string, ...@@ -677,12 +699,12 @@ func (d *dbBase) setColsValues(mi *modelInfo, ind *reflect.Value, cols []string,
677 699
678 field := ind.Field(fi.fieldIndex) 700 field := ind.Field(fi.fieldIndex)
679 701
680 value, err := d.getValue(fi, val) 702 value, err := d.convertValueFromDB(fi, val, tz)
681 if err != nil { 703 if err != nil {
682 panic(fmt.Sprintf("Raw value: `%v` %s", val, err.Error())) 704 panic(fmt.Sprintf("Raw value: `%v` %s", val, err.Error()))
683 } 705 }
684 706
685 _, err = d.setValue(fi, value, &field) 707 _, err = d.setFieldValue(fi, value, &field)
686 708
687 if err != nil { 709 if err != nil {
688 panic(fmt.Sprintf("Raw value: `%v` %s", val, err.Error())) 710 panic(fmt.Sprintf("Raw value: `%v` %s", val, err.Error()))
...@@ -690,7 +712,7 @@ func (d *dbBase) setColsValues(mi *modelInfo, ind *reflect.Value, cols []string, ...@@ -690,7 +712,7 @@ func (d *dbBase) setColsValues(mi *modelInfo, ind *reflect.Value, cols []string,
690 } 712 }
691 } 713 }
692 714
693 func (d *dbBase) getValue(fi *fieldInfo, val interface{}) (interface{}, error) { 715 func (d *dbBase) convertValueFromDB(fi *fieldInfo, val interface{}, tz *time.Location) (interface{}, error) {
694 if val == nil { 716 if val == nil {
695 return nil, nil 717 return nil, nil
696 } 718 }
...@@ -739,29 +761,32 @@ setValue: ...@@ -739,29 +761,32 @@ setValue:
739 } 761 }
740 case fieldType == TypeDateField || fieldType == TypeDateTimeField: 762 case fieldType == TypeDateField || fieldType == TypeDateTimeField:
741 if str == nil { 763 if str == nil {
742 switch v := val.(type) { 764 switch t := val.(type) {
743 case time.Time: 765 case time.Time:
744 value = v 766 d.ins.TimeFromDB(&t, tz)
767 value = t
745 default: 768 default:
746 s := StrTo(ToStr(v)) 769 s := StrTo(ToStr(t))
747 str = &s 770 str = &s
748 } 771 }
749 } 772 }
750 if str != nil { 773 if str != nil {
751 s := str.String() 774 s := str.String()
752 var format string 775 var (
776 t time.Time
777 err error
778 )
753 if fi.fieldType == TypeDateField { 779 if fi.fieldType == TypeDateField {
754 format = format_Date
755 if len(s) > 10 { 780 if len(s) > 10 {
756 s = s[:10] 781 s = s[:10]
757 } 782 }
783 t, err = time.ParseInLocation(format_Date, s, DefaultTimeLoc)
758 } else { 784 } else {
759 format = format_DateTime
760 if len(s) > 19 { 785 if len(s) > 19 {
761 s = s[:19] 786 s = s[:19]
762 } 787 }
788 t, err = time.ParseInLocation(format_DateTime, s, tz)
763 } 789 }
764 t, err := timeParse(s, format)
765 if err != nil && s != "0000-00-00" && s != "0000-00-00 00:00:00" { 790 if err != nil && s != "0000-00-00" && s != "0000-00-00 00:00:00" {
766 tErr = err 791 tErr = err
767 goto end 792 goto end
...@@ -776,12 +801,16 @@ setValue: ...@@ -776,12 +801,16 @@ setValue:
776 if str != nil { 801 if str != nil {
777 var err error 802 var err error
778 switch fieldType { 803 switch fieldType {
804 case TypeBitField:
805 _, err = str.Int8()
779 case TypeSmallIntegerField: 806 case TypeSmallIntegerField:
780 _, err = str.Int16() 807 _, err = str.Int16()
781 case TypeIntegerField: 808 case TypeIntegerField:
782 _, err = str.Int32() 809 _, err = str.Int32()
783 case TypeBigIntegerField: 810 case TypeBigIntegerField:
784 _, err = str.Int64() 811 _, err = str.Int64()
812 case TypePostiveBitField:
813 _, err = str.Uint8()
785 case TypePositiveSmallIntegerField: 814 case TypePositiveSmallIntegerField:
786 _, err = str.Uint16() 815 _, err = str.Uint16()
787 case TypePositiveIntegerField: 816 case TypePositiveIntegerField:
...@@ -835,7 +864,7 @@ end: ...@@ -835,7 +864,7 @@ end:
835 864
836 } 865 }
837 866
838 func (d *dbBase) setValue(fi *fieldInfo, value interface{}, field *reflect.Value) (interface{}, error) { 867 func (d *dbBase) setFieldValue(fi *fieldInfo, value interface{}, field *reflect.Value) (interface{}, error) {
839 868
840 fieldType := fi.fieldType 869 fieldType := fi.fieldType
841 isNative := fi.isFielder == false 870 isNative := fi.isFielder == false
...@@ -909,7 +938,7 @@ setValue: ...@@ -909,7 +938,7 @@ setValue:
909 return value, nil 938 return value, nil
910 } 939 }
911 940
912 func (d *dbBase) ReadValues(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition, exprs []string, container interface{}) (int64, error) { 941 func (d *dbBase) ReadValues(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition, exprs []string, container interface{}, tz *time.Location) (int64, error) {
913 942
914 var ( 943 var (
915 maps []Params 944 maps []Params
...@@ -960,7 +989,7 @@ func (d *dbBase) ReadValues(q dbQuerier, qs *querySet, mi *modelInfo, cond *Cond ...@@ -960,7 +989,7 @@ func (d *dbBase) ReadValues(q dbQuerier, qs *querySet, mi *modelInfo, cond *Cond
960 } 989 }
961 } 990 }
962 991
963 where, args := tables.getCondSql(cond, false) 992 where, args := tables.getCondSql(cond, false, tz)
964 orderBy := tables.getOrderSql(qs.orders) 993 orderBy := tables.getOrderSql(qs.orders)
965 limit := tables.getLimitSql(mi, qs.offset, qs.limit) 994 limit := tables.getLimitSql(mi, qs.offset, qs.limit)
966 join := tables.getJoinSql() 995 join := tables.getJoinSql()
...@@ -1007,7 +1036,7 @@ func (d *dbBase) ReadValues(q dbQuerier, qs *querySet, mi *modelInfo, cond *Cond ...@@ -1007,7 +1036,7 @@ func (d *dbBase) ReadValues(q dbQuerier, qs *querySet, mi *modelInfo, cond *Cond
1007 1036
1008 val := reflect.Indirect(reflect.ValueOf(ref)).Interface() 1037 val := reflect.Indirect(reflect.ValueOf(ref)).Interface()
1009 1038
1010 value, err := d.getValue(fi, val) 1039 value, err := d.convertValueFromDB(fi, val, tz)
1011 if err != nil { 1040 if err != nil {
1012 panic(fmt.Sprintf("db value convert failed `%v` %s", val, err.Error())) 1041 panic(fmt.Sprintf("db value convert failed `%v` %s", val, err.Error()))
1013 } 1042 }
...@@ -1022,7 +1051,7 @@ func (d *dbBase) ReadValues(q dbQuerier, qs *querySet, mi *modelInfo, cond *Cond ...@@ -1022,7 +1051,7 @@ func (d *dbBase) ReadValues(q dbQuerier, qs *querySet, mi *modelInfo, cond *Cond
1022 1051
1023 val := reflect.Indirect(reflect.ValueOf(ref)).Interface() 1052 val := reflect.Indirect(reflect.ValueOf(ref)).Interface()
1024 1053
1025 value, err := d.getValue(fi, val) 1054 value, err := d.convertValueFromDB(fi, val, tz)
1026 if err != nil { 1055 if err != nil {
1027 panic(fmt.Sprintf("db value convert failed `%v` %s", val, err.Error())) 1056 panic(fmt.Sprintf("db value convert failed `%v` %s", val, err.Error()))
1028 } 1057 }
...@@ -1036,7 +1065,7 @@ func (d *dbBase) ReadValues(q dbQuerier, qs *querySet, mi *modelInfo, cond *Cond ...@@ -1036,7 +1065,7 @@ func (d *dbBase) ReadValues(q dbQuerier, qs *querySet, mi *modelInfo, cond *Cond
1036 1065
1037 val := reflect.Indirect(reflect.ValueOf(ref)).Interface() 1066 val := reflect.Indirect(reflect.ValueOf(ref)).Interface()
1038 1067
1039 value, err := d.getValue(fi, val) 1068 value, err := d.convertValueFromDB(fi, val, tz)
1040 if err != nil { 1069 if err != nil {
1041 panic(fmt.Sprintf("db value convert failed `%v` %s", val, err.Error())) 1070 panic(fmt.Sprintf("db value convert failed `%v` %s", val, err.Error()))
1042 } 1071 }
...@@ -1079,3 +1108,11 @@ func (d *dbBase) ReplaceMarks(query *string) { ...@@ -1079,3 +1108,11 @@ func (d *dbBase) ReplaceMarks(query *string) {
1079 func (d *dbBase) HasReturningID(*modelInfo, *string) bool { 1108 func (d *dbBase) HasReturningID(*modelInfo, *string) bool {
1080 return false 1109 return false
1081 } 1110 }
1111
1112 func (d *dbBase) TimeFromDB(t *time.Time, tz *time.Location) {
1113 *t = t.In(tz)
1114 }
1115
1116 func (d *dbBase) TimeToDB(t *time.Time, tz *time.Location) {
1117 *t = t.In(tz)
1118 }
......
...@@ -5,6 +5,7 @@ import ( ...@@ -5,6 +5,7 @@ import (
5 "fmt" 5 "fmt"
6 "os" 6 "os"
7 "sync" 7 "sync"
8 "time"
8 ) 9 )
9 10
10 const defaultMaxIdle = 30 11 const defaultMaxIdle = 30
...@@ -82,6 +83,7 @@ type alias struct { ...@@ -82,6 +83,7 @@ type alias struct {
82 MaxIdle int 83 MaxIdle int
83 DB *sql.DB 84 DB *sql.DB
84 DbBaser dbBaser 85 DbBaser dbBaser
86 TZ *time.Location
85 } 87 }
86 88
87 func RegisterDataBase(name, driverName, dataSource string, maxIdle int) { 89 func RegisterDataBase(name, driverName, dataSource string, maxIdle int) {
...@@ -120,6 +122,33 @@ func RegisterDataBase(name, driverName, dataSource string, maxIdle int) { ...@@ -120,6 +122,33 @@ func RegisterDataBase(name, driverName, dataSource string, maxIdle int) {
120 122
121 al.DB.SetMaxIdleConns(al.MaxIdle) 123 al.DB.SetMaxIdleConns(al.MaxIdle)
122 124
125 // orm timezone system match database
126 // default use Local
127 al.TZ = time.Local
128
129 switch al.Driver {
130 case DR_MySQL:
131 row := al.DB.QueryRow("SELECT @@session.time_zone")
132 var tz string
133 row.Scan(&tz)
134 if tz != "SYSTEM" {
135 t, err := time.Parse("-07:00", tz)
136 if err == nil {
137 al.TZ = t.Location()
138 }
139 }
140 case DR_Sqlite:
141 al.TZ = time.UTC
142 case DR_Postgres:
143 row := al.DB.QueryRow("SELECT current_setting('TIMEZONE')")
144 var tz string
145 row.Scan(&tz)
146 loc, err := time.LoadLocation(tz)
147 if err == nil {
148 al.TZ = loc
149 }
150 }
151
123 err = al.DB.Ping() 152 err = al.DB.Ping()
124 if err != nil { 153 if err != nil {
125 err = fmt.Errorf("register db `%s`, %s", name, err.Error()) 154 err = fmt.Errorf("register db `%s`, %s", name, err.Error())
...@@ -133,13 +162,22 @@ end: ...@@ -133,13 +162,22 @@ end:
133 } 162 }
134 } 163 }
135 164
136 func RegisterDriver(name string, typ DriverType) { 165 func RegisterDriver(driverName string, typ DriverType) {
137 if t, ok := drivers[name]; ok == false { 166 if t, ok := drivers[driverName]; ok == false {
138 drivers[name] = typ 167 drivers[driverName] = typ
139 } else { 168 } else {
140 if t != typ { 169 if t != typ {
141 fmt.Println("name `%s` db driver already registered and is other type") 170 fmt.Println("driverName `%s` db driver already registered and is other type")
142 os.Exit(2) 171 os.Exit(2)
143 } 172 }
144 } 173 }
145 } 174 }
175
176 func SetDataBaseTZ(name string, tz *time.Location) {
177 if al, ok := dataBaseCache.get(name); ok {
178 al.TZ = tz
179 } else {
180 err := fmt.Errorf("DataBase name `%s` not registered", name)
181 fmt.Println(err)
182 }
183 }
......
...@@ -30,7 +30,7 @@ func (d *dbBasePostgres) OperatorSql(operator string) string { ...@@ -30,7 +30,7 @@ func (d *dbBasePostgres) OperatorSql(operator string) string {
30 return postgresOperators[operator] 30 return postgresOperators[operator]
31 } 31 }
32 32
33 func (d *dbBasePostgres) GenerateOperatorLeftCol(operator string, leftCol *string) { 33 func (d *dbBasePostgres) GenerateOperatorLeftCol(fi *fieldInfo, operator string, leftCol *string) {
34 switch operator { 34 switch operator {
35 case "contains", "startswith", "endswith": 35 case "contains", "startswith", "endswith":
36 *leftCol = fmt.Sprintf("%s::text", *leftCol) 36 *leftCol = fmt.Sprintf("%s::text", *leftCol)
......
1 package orm 1 package orm
2 2
3 import (
4 "fmt"
5 )
6
3 var sqliteOperators = map[string]string{ 7 var sqliteOperators = map[string]string{
4 "exact": "= ?", 8 "exact": "= ?",
5 "iexact": "LIKE ? ESCAPE '\\'", 9 "iexact": "LIKE ? ESCAPE '\\'",
...@@ -25,6 +29,12 @@ func (d *dbBaseSqlite) OperatorSql(operator string) string { ...@@ -25,6 +29,12 @@ func (d *dbBaseSqlite) OperatorSql(operator string) string {
25 return sqliteOperators[operator] 29 return sqliteOperators[operator]
26 } 30 }
27 31
32 func (d *dbBaseSqlite) GenerateOperatorLeftCol(fi *fieldInfo, operator string, leftCol *string) {
33 if fi.fieldType == TypeDateField {
34 *leftCol = fmt.Sprintf("DATE(%s)", *leftCol)
35 }
36 }
37
28 func (d *dbBaseSqlite) SupportUpdateJoin() bool { 38 func (d *dbBaseSqlite) SupportUpdateJoin() bool {
29 return false 39 return false
30 } 40 }
......
...@@ -3,6 +3,7 @@ package orm ...@@ -3,6 +3,7 @@ package orm
3 import ( 3 import (
4 "fmt" 4 "fmt"
5 "strings" 5 "strings"
6 "time"
6 ) 7 )
7 8
8 type dbTable struct { 9 type dbTable struct {
...@@ -266,7 +267,7 @@ func (d *dbTables) parseExprs(mi *modelInfo, exprs []string) (index, name string ...@@ -266,7 +267,7 @@ func (d *dbTables) parseExprs(mi *modelInfo, exprs []string) (index, name string
266 return 267 return
267 } 268 }
268 269
269 func (d *dbTables) getCondSql(cond *Condition, sub bool) (where string, params []interface{}) { 270 func (d *dbTables) getCondSql(cond *Condition, sub bool, tz *time.Location) (where string, params []interface{}) {
270 if cond == nil || cond.IsEmpty() { 271 if cond == nil || cond.IsEmpty() {
271 return 272 return
272 } 273 }
...@@ -288,7 +289,7 @@ func (d *dbTables) getCondSql(cond *Condition, sub bool) (where string, params [ ...@@ -288,7 +289,7 @@ func (d *dbTables) getCondSql(cond *Condition, sub bool) (where string, params [
288 where += "NOT " 289 where += "NOT "
289 } 290 }
290 if p.isCond { 291 if p.isCond {
291 w, ps := d.getCondSql(p.cond, true) 292 w, ps := d.getCondSql(p.cond, true, tz)
292 if w != "" { 293 if w != "" {
293 w = fmt.Sprintf("( %s) ", w) 294 w = fmt.Sprintf("( %s) ", w)
294 } 295 }
...@@ -313,10 +314,10 @@ func (d *dbTables) getCondSql(cond *Condition, sub bool) (where string, params [ ...@@ -313,10 +314,10 @@ func (d *dbTables) getCondSql(cond *Condition, sub bool) (where string, params [
313 operator = "exact" 314 operator = "exact"
314 } 315 }
315 316
316 operSql, args := d.base.GenerateOperatorSql(mi, fi, operator, p.args) 317 operSql, args := d.base.GenerateOperatorSql(mi, fi, operator, p.args, tz)
317 318
318 leftCol := fmt.Sprintf("%s.%s%s%s", index, Q, fi.column, Q) 319 leftCol := fmt.Sprintf("%s.%s%s%s", index, Q, fi.column, Q)
319 d.base.GenerateOperatorLeftCol(operator, &leftCol) 320 d.base.GenerateOperatorLeftCol(fi, operator, &leftCol)
320 321
321 where += fmt.Sprintf("%s %s ", leftCol, operSql) 322 where += fmt.Sprintf("%s %s ", leftCol, operSql)
322 params = append(params, args...) 323 params = append(params, args...)
......
...@@ -24,7 +24,7 @@ func getExistPk(mi *modelInfo, ind reflect.Value) (column string, value interfac ...@@ -24,7 +24,7 @@ func getExistPk(mi *modelInfo, ind reflect.Value) (column string, value interfac
24 return 24 return
25 } 25 }
26 26
27 func getFlatParams(fi *fieldInfo, args []interface{}) (params []interface{}) { 27 func getFlatParams(fi *fieldInfo, args []interface{}, tz *time.Location) (params []interface{}) {
28 28
29 outFor: 29 outFor:
30 for _, arg := range args { 30 for _, arg := range args {
...@@ -39,9 +39,9 @@ outFor: ...@@ -39,9 +39,9 @@ outFor:
39 case []byte: 39 case []byte:
40 case time.Time: 40 case time.Time:
41 if fi != nil && fi.fieldType == TypeDateField { 41 if fi != nil && fi.fieldType == TypeDateField {
42 arg = v.Format(format_Date) 42 arg = v.In(DefaultTimeLoc).Format(format_Date)
43 } else { 43 } else {
44 arg = v.Format(format_DateTime) 44 arg = v.In(tz).Format(format_DateTime)
45 } 45 }
46 default: 46 default:
47 kind := val.Kind() 47 kind := val.Kind()
...@@ -65,7 +65,7 @@ outFor: ...@@ -65,7 +65,7 @@ outFor:
65 } 65 }
66 66
67 if len(args) > 0 { 67 if len(args) > 0 {
68 p := getFlatParams(fi, args) 68 p := getFlatParams(fi, args, tz)
69 params = append(params, p...) 69 params = append(params, p...)
70 } 70 }
71 continue outFor 71 continue outFor
......
...@@ -22,12 +22,16 @@ const ( ...@@ -22,12 +22,16 @@ const (
22 // time.Time 22 // time.Time
23 TypeDateTimeField 23 TypeDateTimeField
24 24
25 // int8
26 TypeBitField
25 // int16 27 // int16
26 TypeSmallIntegerField 28 TypeSmallIntegerField
27 // int32 29 // int32
28 TypeIntegerField 30 TypeIntegerField
29 // int64 31 // int64
30 TypeBigIntegerField 32 TypeBigIntegerField
33 // uint8
34 TypePostiveBitField
31 // uint16 35 // uint16
32 TypePositiveSmallIntegerField 36 TypePositiveSmallIntegerField
33 // uint32 37 // uint32
...@@ -49,8 +53,8 @@ const ( ...@@ -49,8 +53,8 @@ const (
49 53
50 const ( 54 const (
51 IsIntegerField = ^-TypePositiveBigIntegerField >> 4 << 5 55 IsIntegerField = ^-TypePositiveBigIntegerField >> 4 << 5
52 IsPostiveIntegerField = ^-TypePositiveBigIntegerField >> 7 << 8 56 IsPostiveIntegerField = ^-TypePositiveBigIntegerField >> 8 << 9
53 IsRelField = ^-RelReverseMany >> 12 << 13 57 IsRelField = ^-RelReverseMany >> 14 << 15
54 IsFieldType = ^-RelReverseMany<<1 + 1 58 IsFieldType = ^-RelReverseMany<<1 + 1
55 ) 59 )
56 60
......
...@@ -327,8 +327,8 @@ checkType: ...@@ -327,8 +327,8 @@ checkType:
327 case TypeDecimalField: 327 case TypeDecimalField:
328 d1 := digits 328 d1 := digits
329 d2 := decimals 329 d2 := decimals
330 v1, er1 := StrTo(d1).Int16() 330 v1, er1 := StrTo(d1).Int8()
331 v2, er2 := StrTo(d2).Int16() 331 v2, er2 := StrTo(d2).Int8()
332 if er1 != nil || er2 != nil { 332 if er1 != nil || er2 != nil {
333 err = fmt.Errorf("wrong digits/decimals value %s/%s", d2, d1) 333 err = fmt.Errorf("wrong digits/decimals value %s/%s", d2, d1)
334 goto end 334 goto end
...@@ -383,12 +383,16 @@ checkType: ...@@ -383,12 +383,16 @@ checkType:
383 _, err = v.Bool() 383 _, err = v.Bool()
384 case TypeFloatField, TypeDecimalField: 384 case TypeFloatField, TypeDecimalField:
385 _, err = v.Float64() 385 _, err = v.Float64()
386 case TypeBitField:
387 _, err = v.Int8()
386 case TypeSmallIntegerField: 388 case TypeSmallIntegerField:
387 _, err = v.Int16() 389 _, err = v.Int16()
388 case TypeIntegerField: 390 case TypeIntegerField:
389 _, err = v.Int32() 391 _, err = v.Int32()
390 case TypeBigIntegerField: 392 case TypeBigIntegerField:
391 _, err = v.Int64() 393 _, err = v.Int64()
394 case TypePostiveBitField:
395 _, err = v.Uint8()
392 case TypePositiveSmallIntegerField: 396 case TypePositiveSmallIntegerField:
393 _, err = v.Uint16() 397 _, err = v.Uint16()
394 case TypePositiveIntegerField: 398 case TypePositiveIntegerField:
......
...@@ -6,11 +6,60 @@ import ( ...@@ -6,11 +6,60 @@ import (
6 "strings" 6 "strings"
7 "time" 7 "time"
8 8
9 // _ "github.com/bylevel/pq"
9 _ "github.com/go-sql-driver/mysql" 10 _ "github.com/go-sql-driver/mysql"
10 _ "github.com/lib/pq" 11 _ "github.com/lib/pq"
11 _ "github.com/mattn/go-sqlite3" 12 _ "github.com/mattn/go-sqlite3"
12 ) 13 )
13 14
15 type Data struct {
16 Id int `orm:"auto"`
17 Boolean bool
18 Char string `orm:"size(50)"`
19 Text string
20 Date time.Time `orm:"type(date)"`
21 DateTime time.Time
22 Byte byte
23 Rune rune
24 Int int
25 Int8 int8
26 Int16 int16
27 Int32 int32
28 Int64 int64
29 Uint uint
30 Uint8 uint8
31 Uint16 uint16
32 Uint32 uint32
33 Uint64 uint64
34 Float32 float32
35 Float64 float64
36 Decimal float64 `orm:"digits(8);decimals(4)"`
37 }
38
39 type DataNull struct {
40 Id int `orm:"auto"`
41 Boolean bool `orm:"null"`
42 Char string `orm:"size(50);null"`
43 Text string `orm:"null"`
44 Date time.Time `orm:"type(date);null"`
45 DateTime time.Time `orm:"null"`
46 Byte byte `orm:"null"`
47 Rune rune `orm:"null"`
48 Int int `orm:"null"`
49 Int8 int8 `orm:"null"`
50 Int16 int16 `orm:"null"`
51 Int32 int32 `orm:"null"`
52 Int64 int64 `orm:"null"`
53 Uint uint `orm:"null"`
54 Uint8 uint8 `orm:"null"`
55 Uint16 uint16 `orm:"null"`
56 Uint32 uint32 `orm:"null"`
57 Uint64 uint64 `orm:"null"`
58 Float32 float32 `orm:"null"`
59 Float64 float64 `orm:"null"`
60 Decimal float64 `orm:"digits(8);decimals(4);null"`
61 }
62
14 type User struct { 63 type User struct {
15 Id int `orm:"auto"` 64 Id int `orm:"auto"`
16 UserName string `orm:"size(30);unique"` 65 UserName string `orm:"size(30);unique"`
...@@ -111,6 +160,8 @@ var initSQLs = map[string]string{ ...@@ -111,6 +160,8 @@ var initSQLs = map[string]string{
111 "DROP TABLE IF EXISTS `tag`;\n" + 160 "DROP TABLE IF EXISTS `tag`;\n" +
112 "DROP TABLE IF EXISTS `post_tags`;\n" + 161 "DROP TABLE IF EXISTS `post_tags`;\n" +
113 "DROP TABLE IF EXISTS `comment`;\n" + 162 "DROP TABLE IF EXISTS `comment`;\n" +
163 "DROP TABLE IF EXISTS `data`;\n" +
164 "DROP TABLE IF EXISTS `data_null`;\n" +
114 "CREATE TABLE `user_profile` (\n" + 165 "CREATE TABLE `user_profile` (\n" +
115 " `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,\n" + 166 " `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,\n" +
116 " `age` smallint NOT NULL,\n" + 167 " `age` smallint NOT NULL,\n" +
...@@ -153,6 +204,52 @@ var initSQLs = map[string]string{ ...@@ -153,6 +204,52 @@ var initSQLs = map[string]string{
153 " `parent_id` integer,\n" + 204 " `parent_id` integer,\n" +
154 " `created` datetime NOT NULL\n" + 205 " `created` datetime NOT NULL\n" +
155 ") ENGINE=INNODB;\n" + 206 ") ENGINE=INNODB;\n" +
207 "CREATE TABLE `data` (\n" +
208 " `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,\n" +
209 " `boolean` bool NOT NULL,\n" +
210 " `char` varchar(50) NOT NULL,\n" +
211 " `text` longtext NOT NULL,\n" +
212 " `date` date NOT NULL,\n" +
213 " `date_time` datetime NOT NULL,\n" +
214 " `byte` tinyint unsigned NOT NULL,\n" +
215 " `rune` integer NOT NULL,\n" +
216 " `int` integer NOT NULL,\n" +
217 " `int8` tinyint NOT NULL,\n" +
218 " `int16` smallint NOT NULL,\n" +
219 " `int32` integer NOT NULL,\n" +
220 " `int64` bigint NOT NULL,\n" +
221 " `uint` integer unsigned NOT NULL,\n" +
222 " `uint8` tinyint unsigned NULL,\n" +
223 " `uint16` smallint unsigned NOT NULL,\n" +
224 " `uint32` integer unsigned NOT NULL,\n" +
225 " `uint64` bigint unsigned NOT NULL,\n" +
226 " `float32` double precision NOT NULL,\n" +
227 " `float64` double precision NOT NULL,\n" +
228 " `decimal` numeric(8,4) NOT NULL\n" +
229 ") ENGINE=INNODB;\n" +
230 "CREATE TABLE `data_null` (\n" +
231 " `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,\n" +
232 " `boolean` bool,\n" +
233 " `char` varchar(50),\n" +
234 " `text` longtext,\n" +
235 " `date` date,\n" +
236 " `date_time` datetime,\n" +
237 " `byte` tinyint unsigned,\n" +
238 " `rune` integer,\n" +
239 " `int` integer,\n" +
240 " `int8` tinyint,\n" +
241 " `int16` smallint,\n" +
242 " `int32` integer,\n" +
243 " `int64` bigint,\n" +
244 " `uint` integer unsigned,\n" +
245 " `uint8` tinyint unsigned,\n" +
246 " `uint16` smallint unsigned,\n" +
247 " `uint32` integer unsigned,\n" +
248 " `uint64` bigint unsigned,\n" +
249 " `float32` double precision,\n" +
250 " `float64` double precision,\n" +
251 " `decimal` numeric(8,4)\n" +
252 ") ENGINE=INNODB;\n" +
156 "CREATE INDEX `user_141c6eec` ON `user` (`profile_id`);\n" + 253 "CREATE INDEX `user_141c6eec` ON `user` (`profile_id`);\n" +
157 "CREATE INDEX `post_fbfc09f1` ON `post` (`user_id`);\n" + 254 "CREATE INDEX `post_fbfc09f1` ON `post` (`user_id`);\n" +
158 "CREATE INDEX `comment_699ae8ca` ON `comment` (`post_id`);\n" + 255 "CREATE INDEX `comment_699ae8ca` ON `comment` (`post_id`);\n" +
...@@ -165,6 +262,8 @@ DROP TABLE IF EXISTS "post"; ...@@ -165,6 +262,8 @@ DROP TABLE IF EXISTS "post";
165 DROP TABLE IF EXISTS "tag"; 262 DROP TABLE IF EXISTS "tag";
166 DROP TABLE IF EXISTS "post_tags"; 263 DROP TABLE IF EXISTS "post_tags";
167 DROP TABLE IF EXISTS "comment"; 264 DROP TABLE IF EXISTS "comment";
265 DROP TABLE IF EXISTS "data";
266 DROP TABLE IF EXISTS "data_null";
168 CREATE TABLE "user_profile" ( 267 CREATE TABLE "user_profile" (
169 "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, 268 "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
170 "age" smallint NOT NULL, 269 "age" smallint NOT NULL,
...@@ -207,6 +306,52 @@ CREATE TABLE "comment" ( ...@@ -207,6 +306,52 @@ CREATE TABLE "comment" (
207 "parent_id" integer, 306 "parent_id" integer,
208 "created" datetime NOT NULL 307 "created" datetime NOT NULL
209 ); 308 );
309 CREATE TABLE "data" (
310 "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
311 "boolean" bool NOT NULL,
312 "char" varchar(50) NOT NULL,
313 "text" text NOT NULL,
314 "date" date NOT NULL,
315 "date_time" datetime NOT NULL,
316 "byte" tinyint unsigned NOT NULL,
317 "rune" integer NOT NULL,
318 "int" integer NOT NULL,
319 "int8" tinyint NOT NULL,
320 "int16" smallint NOT NULL,
321 "int32" integer NOT NULL,
322 "int64" bigint NOT NULL,
323 "uint" integer unsigned NOT NULL,
324 "uint8" tinyint unsigned NOT NULL,
325 "uint16" smallint unsigned NOT NULL,
326 "uint32" integer unsigned NOT NULL,
327 "uint64" bigint unsigned NOT NULL,
328 "float32" real NOT NULL,
329 "float64" real NOT NULL,
330 "decimal" decimal
331 );
332 CREATE TABLE "data_null" (
333 "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
334 "boolean" bool,
335 "char" varchar(50),
336 "text" text,
337 "date" date,
338 "date_time" datetime,
339 "byte" tinyint unsigned,
340 "rune" integer,
341 "int" integer,
342 "int8" tinyint,
343 "int16" smallint,
344 "int32" integer,
345 "int64" bigint,
346 "uint" integer unsigned,
347 "uint8" tinyint unsigned,
348 "uint16" smallint unsigned,
349 "uint32" integer unsigned,
350 "uint64" bigint unsigned,
351 "float32" real,
352 "float64" real,
353 "decimal" decimal
354 );
210 CREATE INDEX "user_141c6eec" ON "user" ("profile_id"); 355 CREATE INDEX "user_141c6eec" ON "user" ("profile_id");
211 CREATE INDEX "post_fbfc09f1" ON "post" ("user_id"); 356 CREATE INDEX "post_fbfc09f1" ON "post" ("user_id");
212 CREATE INDEX "comment_699ae8ca" ON "comment" ("post_id"); 357 CREATE INDEX "comment_699ae8ca" ON "comment" ("post_id");
...@@ -220,6 +365,8 @@ DROP TABLE IF EXISTS "post"; ...@@ -220,6 +365,8 @@ DROP TABLE IF EXISTS "post";
220 DROP TABLE IF EXISTS "tag"; 365 DROP TABLE IF EXISTS "tag";
221 DROP TABLE IF EXISTS "post_tags"; 366 DROP TABLE IF EXISTS "post_tags";
222 DROP TABLE IF EXISTS "comment"; 367 DROP TABLE IF EXISTS "comment";
368 DROP TABLE IF EXISTS "data";
369 DROP TABLE IF EXISTS "data_null";
223 CREATE TABLE "user_profile" ( 370 CREATE TABLE "user_profile" (
224 "id" serial NOT NULL PRIMARY KEY, 371 "id" serial NOT NULL PRIMARY KEY,
225 "age" smallint NOT NULL, 372 "age" smallint NOT NULL,
...@@ -262,6 +409,52 @@ CREATE TABLE "comment" ( ...@@ -262,6 +409,52 @@ CREATE TABLE "comment" (
262 "parent_id" integer, 409 "parent_id" integer,
263 "created" timestamp with time zone NOT NULL 410 "created" timestamp with time zone NOT NULL
264 ); 411 );
412 CREATE TABLE "data" (
413 "id" serial NOT NULL PRIMARY KEY,
414 "boolean" bool NOT NULL,
415 "char" varchar(50) NOT NULL,
416 "text" text NOT NULL,
417 "date" date NOT NULL,
418 "date_time" timestamp with time zone NOT NULL,
419 "byte" smallint CHECK("byte" >= 0 AND "byte" <= 255) NOT NULL,
420 "rune" integer NOT NULL,
421 "int" integer NOT NULL,
422 "int8" smallint CHECK("int8" >= -127 AND "int8" <= 128) NOT NULL,
423 "int16" smallint NOT NULL,
424 "int32" integer NOT NULL,
425 "int64" bigint NOT NULL,
426 "uint" bigint CHECK("uint" >= 0) NOT NULL,
427 "uint8" smallint CHECK("uint8" >= 0 AND "uint8" <= 255) NOT NULL,
428 "uint16" integer CHECK("uint16" >= 0) NOT NULL,
429 "uint32" bigint CHECK("uint32" >= 0) NOT NULL,
430 "uint64" bigint CHECK("uint64" >= 0) NOT NULL,
431 "float32" double precision NOT NULL,
432 "float64" double precision NOT NULL,
433 "decimal" numeric(8, 4)
434 );
435 CREATE TABLE "data_null" (
436 "id" serial NOT NULL PRIMARY KEY,
437 "boolean" bool,
438 "char" varchar(50),
439 "text" text,
440 "date" date,
441 "date_time" timestamp with time zone,
442 "byte" smallint CHECK("byte" >= 0 AND "byte" <= 255),
443 "rune" integer,
444 "int" integer,
445 "int8" smallint CHECK("int8" >= -127 AND "int8" <= 128),
446 "int16" smallint,
447 "int32" integer,
448 "int64" bigint,
449 "uint" bigint CHECK("uint" >= 0),
450 "uint8" smallint CHECK("uint8" >= 0 AND "uint8" <= 255),
451 "uint16" integer CHECK("uint16" >= 0),
452 "uint32" bigint CHECK("uint32" >= 0),
453 "uint64" bigint CHECK("uint64" >= 0),
454 "float32" double precision,
455 "float64" double precision,
456 "decimal" numeric(8, 4)
457 );
265 CREATE INDEX "user_profile_id" ON "user" ("profile_id"); 458 CREATE INDEX "user_profile_id" ON "user" ("profile_id");
266 CREATE INDEX "post_user_id" ON "post" ("user_id"); 459 CREATE INDEX "post_user_id" ON "post" ("user_id");
267 CREATE INDEX "comment_post_id" ON "comment" ("post_id"); 460 CREATE INDEX "comment_post_id" ON "comment" ("post_id");
...@@ -269,6 +462,10 @@ CREATE INDEX "comment_parent_id" ON "comment" ("parent_id"); ...@@ -269,6 +462,10 @@ CREATE INDEX "comment_parent_id" ON "comment" ("parent_id");
269 `} 462 `}
270 463
271 func init() { 464 func init() {
465 // err := os.Setenv("TZ", "+00:00")
466 // fmt.Println(err)
467
468 RegisterModel(new(Data), new(DataNull))
272 RegisterModel(new(User)) 469 RegisterModel(new(User))
273 RegisterModel(new(Profile)) 470 RegisterModel(new(Profile))
274 RegisterModel(new(Post)) 471 RegisterModel(new(Post))
......
...@@ -43,15 +43,19 @@ func getColumnName(ft int, addrField reflect.Value, sf reflect.StructField, col ...@@ -43,15 +43,19 @@ func getColumnName(ft int, addrField reflect.Value, sf reflect.StructField, col
43 func getFieldType(val reflect.Value) (ft int, err error) { 43 func getFieldType(val reflect.Value) (ft int, err error) {
44 elm := reflect.Indirect(val) 44 elm := reflect.Indirect(val)
45 switch elm.Kind() { 45 switch elm.Kind() {
46 case reflect.Int8:
47 ft = TypeBitField
46 case reflect.Int16: 48 case reflect.Int16:
47 ft = TypeSmallIntegerField 49 ft = TypeSmallIntegerField
48 case reflect.Int32, reflect.Int: 50 case reflect.Int32, reflect.Int:
49 ft = TypeIntegerField 51 ft = TypeIntegerField
50 case reflect.Int64: 52 case reflect.Int64:
51 ft = TypeBigIntegerField 53 ft = TypeBigIntegerField
54 case reflect.Uint8:
55 ft = TypePostiveBitField
52 case reflect.Uint16: 56 case reflect.Uint16:
53 ft = TypePositiveSmallIntegerField 57 ft = TypePositiveSmallIntegerField
54 case reflect.Uint32: 58 case reflect.Uint32, reflect.Uint:
55 ft = TypePositiveIntegerField 59 ft = TypePositiveIntegerField
56 case reflect.Uint64: 60 case reflect.Uint64:
57 ft = TypePositiveBigIntegerField 61 ft = TypePositiveBigIntegerField
......
...@@ -55,7 +55,7 @@ func (o *orm) getMiInd(md interface{}) (mi *modelInfo, ind reflect.Value) { ...@@ -55,7 +55,7 @@ func (o *orm) getMiInd(md interface{}) (mi *modelInfo, ind reflect.Value) {
55 55
56 func (o *orm) Read(md interface{}) error { 56 func (o *orm) Read(md interface{}) error {
57 mi, ind := o.getMiInd(md) 57 mi, ind := o.getMiInd(md)
58 err := o.alias.DbBaser.Read(o.db, mi, ind) 58 err := o.alias.DbBaser.Read(o.db, mi, ind, o.alias.TZ)
59 if err != nil { 59 if err != nil {
60 return err 60 return err
61 } 61 }
...@@ -64,7 +64,7 @@ func (o *orm) Read(md interface{}) error { ...@@ -64,7 +64,7 @@ func (o *orm) Read(md interface{}) error {
64 64
65 func (o *orm) Insert(md interface{}) (int64, error) { 65 func (o *orm) Insert(md interface{}) (int64, error) {
66 mi, ind := o.getMiInd(md) 66 mi, ind := o.getMiInd(md)
67 id, err := o.alias.DbBaser.Insert(o.db, mi, ind) 67 id, err := o.alias.DbBaser.Insert(o.db, mi, ind, o.alias.TZ)
68 if err != nil { 68 if err != nil {
69 return id, err 69 return id, err
70 } 70 }
...@@ -78,7 +78,7 @@ func (o *orm) Insert(md interface{}) (int64, error) { ...@@ -78,7 +78,7 @@ func (o *orm) Insert(md interface{}) (int64, error) {
78 78
79 func (o *orm) Update(md interface{}) (int64, error) { 79 func (o *orm) Update(md interface{}) (int64, error) {
80 mi, ind := o.getMiInd(md) 80 mi, ind := o.getMiInd(md)
81 num, err := o.alias.DbBaser.Update(o.db, mi, ind) 81 num, err := o.alias.DbBaser.Update(o.db, mi, ind, o.alias.TZ)
82 if err != nil { 82 if err != nil {
83 return num, err 83 return num, err
84 } 84 }
...@@ -87,7 +87,7 @@ func (o *orm) Update(md interface{}) (int64, error) { ...@@ -87,7 +87,7 @@ func (o *orm) Update(md interface{}) (int64, error) {
87 87
88 func (o *orm) Delete(md interface{}) (int64, error) { 88 func (o *orm) Delete(md interface{}) (int64, error) {
89 mi, ind := o.getMiInd(md) 89 mi, ind := o.getMiInd(md)
90 num, err := o.alias.DbBaser.Delete(o.db, mi, ind) 90 num, err := o.alias.DbBaser.Delete(o.db, mi, ind, o.alias.TZ)
91 if err != nil { 91 if err != nil {
92 return num, err 92 return num, err
93 } 93 }
......
...@@ -28,7 +28,7 @@ func (o *insertSet) Insert(md interface{}) (int64, error) { ...@@ -28,7 +28,7 @@ func (o *insertSet) Insert(md interface{}) (int64, error) {
28 if name != o.mi.fullName { 28 if name != o.mi.fullName {
29 panic(fmt.Sprintf("<Inserter.Insert> need model `%s` but found `%s`", o.mi.fullName, name)) 29 panic(fmt.Sprintf("<Inserter.Insert> need model `%s` but found `%s`", o.mi.fullName, name))
30 } 30 }
31 id, err := o.orm.alias.DbBaser.InsertStmt(o.stmt, o.mi, ind) 31 id, err := o.orm.alias.DbBaser.InsertStmt(o.stmt, o.mi, ind, o.orm.alias.TZ)
32 if err != nil { 32 if err != nil {
33 return id, err 33 return id, err
34 } 34 }
......
...@@ -77,15 +77,15 @@ func (o querySet) SetCond(cond *Condition) QuerySeter { ...@@ -77,15 +77,15 @@ func (o querySet) SetCond(cond *Condition) QuerySeter {
77 } 77 }
78 78
79 func (o *querySet) Count() (int64, error) { 79 func (o *querySet) Count() (int64, error) {
80 return o.orm.alias.DbBaser.Count(o.orm.db, o, o.mi, o.cond) 80 return o.orm.alias.DbBaser.Count(o.orm.db, o, o.mi, o.cond, o.orm.alias.TZ)
81 } 81 }
82 82
83 func (o *querySet) Update(values Params) (int64, error) { 83 func (o *querySet) Update(values Params) (int64, error) {
84 return o.orm.alias.DbBaser.UpdateBatch(o.orm.db, o, o.mi, o.cond, values) 84 return o.orm.alias.DbBaser.UpdateBatch(o.orm.db, o, o.mi, o.cond, values, o.orm.alias.TZ)
85 } 85 }
86 86
87 func (o *querySet) Delete() (int64, error) { 87 func (o *querySet) Delete() (int64, error) {
88 return o.orm.alias.DbBaser.DeleteBatch(o.orm.db, o, o.mi, o.cond) 88 return o.orm.alias.DbBaser.DeleteBatch(o.orm.db, o, o.mi, o.cond, o.orm.alias.TZ)
89 } 89 }
90 90
91 func (o *querySet) PrepareInsert() (Inserter, error) { 91 func (o *querySet) PrepareInsert() (Inserter, error) {
...@@ -93,11 +93,11 @@ func (o *querySet) PrepareInsert() (Inserter, error) { ...@@ -93,11 +93,11 @@ func (o *querySet) PrepareInsert() (Inserter, error) {
93 } 93 }
94 94
95 func (o *querySet) All(container interface{}) (int64, error) { 95 func (o *querySet) All(container interface{}) (int64, error) {
96 return o.orm.alias.DbBaser.ReadBatch(o.orm.db, o, o.mi, o.cond, container) 96 return o.orm.alias.DbBaser.ReadBatch(o.orm.db, o, o.mi, o.cond, container, o.orm.alias.TZ)
97 } 97 }
98 98
99 func (o *querySet) One(container interface{}) error { 99 func (o *querySet) One(container interface{}) error {
100 num, err := o.orm.alias.DbBaser.ReadBatch(o.orm.db, o, o.mi, o.cond, container) 100 num, err := o.orm.alias.DbBaser.ReadBatch(o.orm.db, o, o.mi, o.cond, container, o.orm.alias.TZ)
101 if err != nil { 101 if err != nil {
102 return err 102 return err
103 } 103 }
...@@ -111,15 +111,15 @@ func (o *querySet) One(container interface{}) error { ...@@ -111,15 +111,15 @@ func (o *querySet) One(container interface{}) error {
111 } 111 }
112 112
113 func (o *querySet) Values(results *[]Params, exprs ...string) (int64, error) { 113 func (o *querySet) Values(results *[]Params, exprs ...string) (int64, error) {
114 return o.orm.alias.DbBaser.ReadValues(o.orm.db, o, o.mi, o.cond, exprs, results) 114 return o.orm.alias.DbBaser.ReadValues(o.orm.db, o, o.mi, o.cond, exprs, results, o.orm.alias.TZ)
115 } 115 }
116 116
117 func (o *querySet) ValuesList(results *[]ParamsList, exprs ...string) (int64, error) { 117 func (o *querySet) ValuesList(results *[]ParamsList, exprs ...string) (int64, error) {
118 return o.orm.alias.DbBaser.ReadValues(o.orm.db, o, o.mi, o.cond, exprs, results) 118 return o.orm.alias.DbBaser.ReadValues(o.orm.db, o, o.mi, o.cond, exprs, results, o.orm.alias.TZ)
119 } 119 }
120 120
121 func (o *querySet) ValuesFlat(result *ParamsList, expr string) (int64, error) { 121 func (o *querySet) ValuesFlat(result *ParamsList, expr string) (int64, error) {
122 return o.orm.alias.DbBaser.ReadValues(o.orm.db, o, o.mi, o.cond, []string{expr}, result) 122 return o.orm.alias.DbBaser.ReadValues(o.orm.db, o, o.mi, o.cond, []string{expr}, result, o.orm.alias.TZ)
123 } 123 }
124 124
125 func newQuerySet(orm *orm, mi *modelInfo) QuerySeter { 125 func newQuerySet(orm *orm, mi *modelInfo) QuerySeter {
......
...@@ -60,7 +60,7 @@ func (o *rawSet) Exec() (sql.Result, error) { ...@@ -60,7 +60,7 @@ func (o *rawSet) Exec() (sql.Result, error) {
60 query := o.query 60 query := o.query
61 o.orm.alias.DbBaser.ReplaceMarks(&query) 61 o.orm.alias.DbBaser.ReplaceMarks(&query)
62 62
63 args := getFlatParams(nil, o.args) 63 args := getFlatParams(nil, o.args, o.orm.alias.TZ)
64 return o.orm.db.Exec(query, args...) 64 return o.orm.db.Exec(query, args...)
65 } 65 }
66 66
...@@ -96,7 +96,7 @@ func (o *rawSet) readValues(container interface{}) (int64, error) { ...@@ -96,7 +96,7 @@ func (o *rawSet) readValues(container interface{}) (int64, error) {
96 query := o.query 96 query := o.query
97 o.orm.alias.DbBaser.ReplaceMarks(&query) 97 o.orm.alias.DbBaser.ReplaceMarks(&query)
98 98
99 args := getFlatParams(nil, o.args) 99 args := getFlatParams(nil, o.args, o.orm.alias.TZ)
100 100
101 var rs *sql.Rows 101 var rs *sql.Rows
102 if r, err := o.orm.db.Query(query, args...); err != nil { 102 if r, err := o.orm.db.Query(query, args...); err != nil {
......
...@@ -15,6 +15,11 @@ import ( ...@@ -15,6 +15,11 @@ import (
15 15
16 var _ = os.PathSeparator 16 var _ = os.PathSeparator
17 17
18 var (
19 test_Date = format_Date + " -0700"
20 test_DateTime = format_DateTime + " -0700"
21 )
22
18 type T_Code int 23 type T_Code int
19 24
20 const ( 25 const (
...@@ -141,7 +146,7 @@ func getCaller(skip int) string { ...@@ -141,7 +146,7 @@ func getCaller(skip int) string {
141 if cur == line { 146 if cur == line {
142 flag = ">>" 147 flag = ">>"
143 } 148 }
144 code := fmt.Sprintf(" %s %5d: %s", flag, cur, strings.TrimSpace(string(lines[o+i]))) 149 code := fmt.Sprintf(" %s %5d: %s", flag, cur, strings.Replace(string(lines[o+i]), "\t", " ", -1))
145 if code != "" { 150 if code != "" {
146 codes = append(codes, code) 151 codes = append(codes, code)
147 } 152 }
...@@ -158,7 +163,11 @@ func throwFail(t *testing.T, err error, args ...interface{}) { ...@@ -158,7 +163,11 @@ func throwFail(t *testing.T, err error, args ...interface{}) {
158 if err != nil { 163 if err != nil {
159 con := fmt.Sprintf("\t\nError: %s\n%s\n", err.Error(), getCaller(2)) 164 con := fmt.Sprintf("\t\nError: %s\n%s\n", err.Error(), getCaller(2))
160 if len(args) > 0 { 165 if len(args) > 0 {
161 con += fmt.Sprint(args...) 166 parts := make([]string, 0, len(args))
167 for _, arg := range args {
168 parts = append(parts, fmt.Sprintf("%v", arg))
169 }
170 con += " " + strings.Join(parts, ", ")
162 } 171 }
163 t.Error(con) 172 t.Error(con)
164 t.Fail() 173 t.Fail()
...@@ -169,7 +178,11 @@ func throwFailNow(t *testing.T, err error, args ...interface{}) { ...@@ -169,7 +178,11 @@ func throwFailNow(t *testing.T, err error, args ...interface{}) {
169 if err != nil { 178 if err != nil {
170 con := fmt.Sprintf("\t\nError: %s\n%s\n", err.Error(), getCaller(2)) 179 con := fmt.Sprintf("\t\nError: %s\n%s\n", err.Error(), getCaller(2))
171 if len(args) > 0 { 180 if len(args) > 0 {
172 con += fmt.Sprint(args...) 181 parts := make([]string, 0, len(args))
182 for _, arg := range args {
183 parts = append(parts, fmt.Sprintf("%v", arg))
184 }
185 con += " " + strings.Join(parts, ", ")
173 } 186 }
174 t.Error(con) 187 t.Error(con)
175 t.FailNow() 188 t.FailNow()
...@@ -177,13 +190,100 @@ func throwFailNow(t *testing.T, err error, args ...interface{}) { ...@@ -177,13 +190,100 @@ func throwFailNow(t *testing.T, err error, args ...interface{}) {
177 } 190 }
178 191
179 func TestModelSyntax(t *testing.T) { 192 func TestModelSyntax(t *testing.T) {
180 mi, ok := modelCache.get("user") 193 user := &User{}
194 ind := reflect.ValueOf(user).Elem()
195 fn := getFullName(ind.Type())
196 mi, ok := modelCache.getByFN(fn)
197 throwFail(t, AssertIs(ok, T_Equal, true))
198
199 mi, ok = modelCache.get("user")
181 throwFail(t, AssertIs(ok, T_Equal, true)) 200 throwFail(t, AssertIs(ok, T_Equal, true))
182 if ok { 201 if ok {
183 throwFail(t, AssertIs(mi.fields.GetByName("ShouldSkip") == nil, T_Equal, true)) 202 throwFail(t, AssertIs(mi.fields.GetByName("ShouldSkip") == nil, T_Equal, true))
184 } 203 }
185 } 204 }
186 205
206 func TestDataTypes(t *testing.T) {
207 values := map[string]interface{}{
208 "Boolean": true,
209 "Char": "char",
210 "Text": "text",
211 "Date": time.Now(),
212 "DateTime": time.Now(),
213 "Byte": byte(1<<8 - 1),
214 "Rune": rune(1<<31 - 1),
215 "Int": int(1<<31 - 1),
216 "Int8": int8(1<<7 - 1),
217 "Int16": int16(1<<15 - 1),
218 "Int32": int32(1<<31 - 1),
219 "Int64": int64(1<<63 - 1),
220 "Uint": uint(1<<32 - 1),
221 "Uint8": uint8(1<<8 - 1),
222 "Uint16": uint16(1<<16 - 1),
223 "Uint32": uint32(1<<32 - 1),
224 "Uint64": uint64(1<<63 - 1), // uint64 values with high bit set are not supported
225 "Float32": float32(100.1234),
226 "Float64": float64(100.1234),
227 "Decimal": float64(100.1234),
228 }
229 d := Data{}
230 ind := reflect.Indirect(reflect.ValueOf(&d))
231
232 for name, value := range values {
233 e := ind.FieldByName(name)
234 e.Set(reflect.ValueOf(value))
235 }
236
237 id, err := dORM.Insert(&d)
238 throwFail(t, err)
239 throwFail(t, AssertIs(id, T_Equal, 1))
240
241 d = Data{Id: 1}
242 err = dORM.Read(&d)
243 throwFail(t, err)
244
245 ind = reflect.Indirect(reflect.ValueOf(&d))
246
247 for name, value := range values {
248 e := ind.FieldByName(name)
249 vu := e.Interface()
250 switch name {
251 case "Date":
252 vu = vu.(time.Time).In(DefaultTimeLoc).Format(test_Date)
253 value = value.(time.Time).In(DefaultTimeLoc).Format(test_Date)
254 case "DateTime":
255 vu = vu.(time.Time).In(DefaultTimeLoc).Format(test_DateTime)
256 value = value.(time.Time).In(DefaultTimeLoc).Format(test_DateTime)
257 }
258 throwFail(t, AssertIs(vu == value, T_Equal, true), value, vu)
259 }
260 }
261
262 func TestNullDataTypes(t *testing.T) {
263 d := DataNull{}
264
265 if IsPostgres {
266 // can removed when this fixed
267 // https://github.com/lib/pq/pull/125
268 d.DateTime = time.Now()
269 }
270
271 id, err := dORM.Insert(&d)
272 throwFail(t, err)
273 throwFail(t, AssertIs(id, T_Equal, 1))
274
275 d = DataNull{Id: 1}
276 err = dORM.Read(&d)
277 throwFail(t, err)
278
279 _, err = dORM.Raw(`INSERT INTO data_null (boolean) VALUES (?)`, nil).Exec()
280 throwFail(t, err)
281
282 d = DataNull{Id: 2}
283 err = dORM.Read(&d)
284 throwFail(t, err)
285 }
286
187 func TestCRUD(t *testing.T) { 287 func TestCRUD(t *testing.T) {
188 profile := NewProfile() 288 profile := NewProfile()
189 profile.Age = 30 289 profile.Age = 30
...@@ -214,8 +314,8 @@ func TestCRUD(t *testing.T) { ...@@ -214,8 +314,8 @@ func TestCRUD(t *testing.T) {
214 throwFail(t, AssertIs(u.Status, T_Equal, 3)) 314 throwFail(t, AssertIs(u.Status, T_Equal, 3))
215 throwFail(t, AssertIs(u.IsStaff, T_Equal, true)) 315 throwFail(t, AssertIs(u.IsStaff, T_Equal, true))
216 throwFail(t, AssertIs(u.IsActive, T_Equal, true)) 316 throwFail(t, AssertIs(u.IsActive, T_Equal, true))
217 throwFail(t, AssertIs(u.Created, T_Equal, user.Created, format_Date)) 317 throwFail(t, AssertIs(u.Created.In(DefaultTimeLoc), T_Equal, user.Created.In(DefaultTimeLoc), test_Date))
218 throwFail(t, AssertIs(u.Updated, T_Equal, user.Updated, format_DateTime)) 318 throwFail(t, AssertIs(u.Updated.In(DefaultTimeLoc), T_Equal, user.Updated.In(DefaultTimeLoc), test_DateTime))
219 319
220 user.UserName = "astaxie" 320 user.UserName = "astaxie"
221 user.Profile = profile 321 user.Profile = profile
...@@ -360,7 +460,9 @@ The program—and web server—godoc processes Go source files to extract docume ...@@ -360,7 +460,9 @@ The program—and web server—godoc processes Go source files to extract docume
360 } 460 }
361 461
362 func TestExpr(t *testing.T) { 462 func TestExpr(t *testing.T) {
363 qs := dORM.QueryTable("User") 463 user := &User{}
464 qs := dORM.QueryTable(user)
465 qs = dORM.QueryTable("User")
364 qs = dORM.QueryTable("user") 466 qs = dORM.QueryTable("user")
365 num, err := qs.Filter("UserName", "slene").Filter("user_name", "slene").Filter("profile__Age", 28).Count() 467 num, err := qs.Filter("UserName", "slene").Filter("user_name", "slene").Filter("profile__Age", 28).Count()
366 throwFail(t, err) 468 throwFail(t, err)
...@@ -369,6 +471,10 @@ func TestExpr(t *testing.T) { ...@@ -369,6 +471,10 @@ func TestExpr(t *testing.T) {
369 num, err = qs.Filter("created", time.Now()).Count() 471 num, err = qs.Filter("created", time.Now()).Count()
370 throwFail(t, err) 472 throwFail(t, err)
371 throwFail(t, AssertIs(num, T_Equal, 3)) 473 throwFail(t, AssertIs(num, T_Equal, 3))
474
475 num, err = qs.Filter("created", time.Now().Format(format_Date)).Count()
476 throwFail(t, err)
477 throwFail(t, AssertIs(num, T_Equal, 3))
372 } 478 }
373 479
374 func TestOperators(t *testing.T) { 480 func TestOperators(t *testing.T) {
...@@ -820,11 +926,13 @@ func TestRaw(t *testing.T) { ...@@ -820,11 +926,13 @@ func TestRaw(t *testing.T) {
820 res, err := dORM.Raw(`DELETE FROM "tag" WHERE "name" IN (?, ?, ?)`, []string{"name1", "name2", "name3"}).Exec() 926 res, err := dORM.Raw(`DELETE FROM "tag" WHERE "name" IN (?, ?, ?)`, []string{"name1", "name2", "name3"}).Exec()
821 throwFail(t, err) 927 throwFail(t, err)
822 928
929 if err == nil {
823 num, err := res.RowsAffected() 930 num, err := res.RowsAffected()
824 throwFail(t, err) 931 throwFail(t, err)
825 throwFail(t, AssertIs(num, T_Equal, 3)) 932 throwFail(t, AssertIs(num, T_Equal, 3))
826 } 933 }
827 } 934 }
935 }
828 } 936 }
829 937
830 func TestUpdate(t *testing.T) { 938 func TestUpdate(t *testing.T) {
......
...@@ -3,6 +3,7 @@ package orm ...@@ -3,6 +3,7 @@ package orm
3 import ( 3 import (
4 "database/sql" 4 "database/sql"
5 "reflect" 5 "reflect"
6 "time"
6 ) 7 )
7 8
8 type Driver interface { 9 type Driver interface {
...@@ -110,23 +111,25 @@ type txEnder interface { ...@@ -110,23 +111,25 @@ type txEnder interface {
110 } 111 }
111 112
112 type dbBaser interface { 113 type dbBaser interface {
113 Read(dbQuerier, *modelInfo, reflect.Value) error 114 Read(dbQuerier, *modelInfo, reflect.Value, *time.Location) error
114 Insert(dbQuerier, *modelInfo, reflect.Value) (int64, error) 115 Insert(dbQuerier, *modelInfo, reflect.Value, *time.Location) (int64, error)
115 InsertStmt(stmtQuerier, *modelInfo, reflect.Value) (int64, error) 116 InsertStmt(stmtQuerier, *modelInfo, reflect.Value, *time.Location) (int64, error)
116 Update(dbQuerier, *modelInfo, reflect.Value) (int64, error) 117 Update(dbQuerier, *modelInfo, reflect.Value, *time.Location) (int64, error)
117 Delete(dbQuerier, *modelInfo, reflect.Value) (int64, error) 118 Delete(dbQuerier, *modelInfo, reflect.Value, *time.Location) (int64, error)
118 ReadBatch(dbQuerier, *querySet, *modelInfo, *Condition, interface{}) (int64, error) 119 ReadBatch(dbQuerier, *querySet, *modelInfo, *Condition, interface{}, *time.Location) (int64, error)
119 SupportUpdateJoin() bool 120 SupportUpdateJoin() bool
120 UpdateBatch(dbQuerier, *querySet, *modelInfo, *Condition, Params) (int64, error) 121 UpdateBatch(dbQuerier, *querySet, *modelInfo, *Condition, Params, *time.Location) (int64, error)
121 DeleteBatch(dbQuerier, *querySet, *modelInfo, *Condition) (int64, error) 122 DeleteBatch(dbQuerier, *querySet, *modelInfo, *Condition, *time.Location) (int64, error)
122 Count(dbQuerier, *querySet, *modelInfo, *Condition) (int64, error) 123 Count(dbQuerier, *querySet, *modelInfo, *Condition, *time.Location) (int64, error)
123 OperatorSql(string) string 124 OperatorSql(string) string
124 GenerateOperatorSql(*modelInfo, *fieldInfo, string, []interface{}) (string, []interface{}) 125 GenerateOperatorSql(*modelInfo, *fieldInfo, string, []interface{}, *time.Location) (string, []interface{})
125 GenerateOperatorLeftCol(string, *string) 126 GenerateOperatorLeftCol(*fieldInfo, string, *string)
126 PrepareInsert(dbQuerier, *modelInfo) (stmtQuerier, string, error) 127 PrepareInsert(dbQuerier, *modelInfo) (stmtQuerier, string, error)
127 ReadValues(dbQuerier, *querySet, *modelInfo, *Condition, []string, interface{}) (int64, error) 128 ReadValues(dbQuerier, *querySet, *modelInfo, *Condition, []string, interface{}, *time.Location) (int64, error)
128 MaxLimit() uint64 129 MaxLimit() uint64
129 TableQuote() string 130 TableQuote() string
130 ReplaceMarks(*string) 131 ReplaceMarks(*string)
131 HasReturningID(*modelInfo, *string) bool 132 HasReturningID(*modelInfo, *string) bool
133 TimeFromDB(*time.Time, *time.Location)
134 TimeToDB(*time.Time, *time.Location)
132 } 135 }
......
...@@ -38,6 +38,11 @@ func (f StrTo) Float64() (float64, error) { ...@@ -38,6 +38,11 @@ func (f StrTo) Float64() (float64, error) {
38 return strconv.ParseFloat(f.String(), 64) 38 return strconv.ParseFloat(f.String(), 64)
39 } 39 }
40 40
41 func (f StrTo) Int8() (int8, error) {
42 v, err := strconv.ParseInt(f.String(), 10, 8)
43 return int8(v), err
44 }
45
41 func (f StrTo) Int16() (int16, error) { 46 func (f StrTo) Int16() (int16, error) {
42 v, err := strconv.ParseInt(f.String(), 10, 16) 47 v, err := strconv.ParseInt(f.String(), 10, 16)
43 return int16(v), err 48 return int16(v), err
...@@ -53,6 +58,11 @@ func (f StrTo) Int64() (int64, error) { ...@@ -53,6 +58,11 @@ func (f StrTo) Int64() (int64, error) {
53 return int64(v), err 58 return int64(v), err
54 } 59 }
55 60
61 func (f StrTo) Uint8() (uint8, error) {
62 v, err := strconv.ParseUint(f.String(), 10, 8)
63 return uint8(v), err
64 }
65
56 func (f StrTo) Uint16() (uint16, error) { 66 func (f StrTo) Uint16() (uint16, error) {
57 v, err := strconv.ParseUint(f.String(), 10, 16) 67 v, err := strconv.ParseUint(f.String(), 10, 16)
58 return uint16(v), err 68 return uint16(v), err
...@@ -85,6 +95,8 @@ func ToStr(value interface{}, args ...int) (s string) { ...@@ -85,6 +95,8 @@ func ToStr(value interface{}, args ...int) (s string) {
85 s = strconv.FormatFloat(v, 'f', argInt(args).Get(0, -1), argInt(args).Get(1, 64)) 95 s = strconv.FormatFloat(v, 'f', argInt(args).Get(0, -1), argInt(args).Get(1, 64))
86 case int: 96 case int:
87 s = strconv.FormatInt(int64(v), argInt(args).Get(0, 10)) 97 s = strconv.FormatInt(int64(v), argInt(args).Get(0, 10))
98 case int8:
99 s = strconv.FormatInt(int64(v), argInt(args).Get(0, 10))
88 case int16: 100 case int16:
89 s = strconv.FormatInt(int64(v), argInt(args).Get(0, 10)) 101 s = strconv.FormatInt(int64(v), argInt(args).Get(0, 10))
90 case int32: 102 case int32:
...@@ -93,6 +105,8 @@ func ToStr(value interface{}, args ...int) (s string) { ...@@ -93,6 +105,8 @@ func ToStr(value interface{}, args ...int) (s string) {
93 s = strconv.FormatInt(v, argInt(args).Get(0, 10)) 105 s = strconv.FormatInt(v, argInt(args).Get(0, 10))
94 case uint: 106 case uint:
95 s = strconv.FormatUint(uint64(v), argInt(args).Get(0, 10)) 107 s = strconv.FormatUint(uint64(v), argInt(args).Get(0, 10))
108 case uint8:
109 s = strconv.FormatUint(uint64(v), argInt(args).Get(0, 10))
96 case uint16: 110 case uint16:
97 s = strconv.FormatUint(uint64(v), argInt(args).Get(0, 10)) 111 s = strconv.FormatUint(uint64(v), argInt(args).Get(0, 10))
98 case uint32: 112 case uint32:
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!