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
...@@ -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,9 +926,11 @@ func TestRaw(t *testing.T) { ...@@ -820,9 +926,11 @@ 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
823 num, err := res.RowsAffected() 929 if err == nil {
824 throwFail(t, err) 930 num, err := res.RowsAffected()
825 throwFail(t, AssertIs(num, T_Equal, 3)) 931 throwFail(t, err)
932 throwFail(t, AssertIs(num, T_Equal, 3))
933 }
826 } 934 }
827 } 935 }
828 } 936 }
......
...@@ -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!