feat(database/gdb): add year field type support for ORM operations (#3805)

This commit is contained in:
John Guo 2024-09-25 16:33:52 +08:00 committed by GitHub
parent ab2c3b02ac
commit 3f2b1cb329
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 108 additions and 25 deletions

View File

@ -58,6 +58,11 @@ jobs:
- 6379:6379
# MySQL backend server.
# docker run -d --name mysql \
# -p 3306:3306 \
# -e MYSQL_DATABASE=test \
# -e MYSQL_ROOT_PASSWORD=12345678 \
# loads/mysql:5.7
mysql:
image: loads/mysql:5.7
env:

View File

@ -59,7 +59,7 @@ func (c cGF) Index(ctx context.Context, in cGFInput) (out *cGFOutput, err error)
answer := "n"
// No argument or option, do installation checks.
if data, isInstalled := service.Install.IsInstalled(); !isInstalled {
mlog.Print("hi, it seams it's the first time you installing gf cli.")
mlog.Print("hi, it seems it's the first time you installing gf cli.")
answer = gcmd.Scanf("do you want to install gf(%s) binary to your system? [y/n]: ", gf.VERSION)
} else if !data.IsSelf {
mlog.Print("hi, you have installed gf cli.")

View File

@ -4786,3 +4786,35 @@ func Test_Model_FixGdbJoin(t *testing.T) {
t.Assert(gtest.DataContent(`fix_gdb_join_expect.sql`), sqlSlice[len(sqlSlice)-1])
})
}
func Test_Model_Year_Date_Time_DateTime_Timestamp(t *testing.T) {
table := "date_time_example"
array := gstr.SplitAndTrim(gtest.DataContent(`date_time_example.sql`), ";")
for _, v := range array {
if _, err := db.Exec(ctx, v); err != nil {
gtest.Error(err)
}
}
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
// insert.
var now = gtime.Now()
_, err := db.Model("date_time_example").Insert(g.Map{
"year": now,
"date": now,
"time": now,
"datetime": now,
"timestamp": now,
})
t.AssertNil(err)
// select.
one, err := db.Model("date_time_example").One()
t.AssertNil(err)
t.Assert(one["year"].String(), now.Format("Y"))
t.Assert(one["date"].String(), now.Format("Y-m-d"))
t.Assert(one["time"].String(), now.Format("H:i:s"))
t.AssertLT(one["datetime"].GTime().Sub(now).Seconds(), 5)
t.AssertLT(one["timestamp"].GTime().Sub(now).Seconds(), 5)
})
}

View File

@ -0,0 +1,9 @@
CREATE TABLE `date_time_example` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`year` year DEFAULT NULL COMMENT 'year',
`date` date DEFAULT NULL COMMENT 'Date',
`time` time DEFAULT NULL COMMENT 'time',
`datetime` datetime DEFAULT NULL COMMENT 'datetime',
`timestamp` timestamp NULL DEFAULT NULL COMMENT 'Timestamp',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

View File

@ -493,10 +493,11 @@ const (
fieldTypeSmallmoney = "smallmoney"
fieldTypeBool = "bool"
fieldTypeBit = "bit"
fieldTypeDate = "date"
fieldTypeTime = "time"
fieldTypeDatetime = "datetime"
fieldTypeTimestamp = "timestamp"
fieldTypeYear = "year" // YYYY
fieldTypeDate = "date" // YYYY-MM-DD
fieldTypeTime = "time" // HH:MM:SS
fieldTypeDatetime = "datetime" // YYYY-MM-DD HH:MM:SS
fieldTypeTimestamp = "timestamp" // YYYYMMDD HHMMSS
fieldTypeTimestampz = "timestamptz"
fieldTypeJson = "json"
fieldTypeJsonb = "jsonb"

View File

@ -28,7 +28,19 @@ import (
func (c *Core) GetFieldTypeStr(ctx context.Context, fieldName, table, schema string) string {
field := c.GetFieldType(ctx, fieldName, table, schema)
if field != nil {
return field.Type
// Kinds of data type examples:
// year(4)
// datetime
// varchar(64)
// bigint(20)
// int(10) unsigned
typeName := gstr.StrTillEx(field.Type, "(") // int(10) unsigned -> int
if typeName != "" {
typeName = gstr.Trim(typeName)
} else {
typeName = field.Type
}
return typeName
}
return ""
}
@ -63,9 +75,10 @@ func (c *Core) ConvertDataForRecord(ctx context.Context, value interface{}, tabl
data = MapOrStructToMapDeep(value, true)
)
for fieldName, fieldValue := range data {
var fieldType = c.GetFieldTypeStr(ctx, fieldName, table, c.GetSchema())
data[fieldName], err = c.db.ConvertValueForField(
ctx,
c.GetFieldTypeStr(ctx, fieldName, table, c.GetSchema()),
fieldType,
fieldValue,
)
if err != nil {
@ -124,41 +137,63 @@ Default:
case time.Time:
if r.IsZero() {
convertedValue = nil
} else if fieldType == fieldTypeDate {
convertedValue = r.Format("2006-01-02")
} else if fieldType == fieldTypeTime {
convertedValue = r.Format("15:04:05")
} else {
switch fieldType {
case fieldTypeYear:
convertedValue = r.Format("2006")
case fieldTypeDate:
convertedValue = r.Format("2006-01-02")
case fieldTypeTime:
convertedValue = r.Format("15:04:05")
default:
}
}
case *time.Time:
if r == nil {
// Nothing to do.
} else if fieldType == fieldTypeDate {
convertedValue = r.Format("2006-01-02")
} else if fieldType == fieldTypeTime {
convertedValue = r.Format("15:04:05")
} else {
switch fieldType {
case fieldTypeYear:
convertedValue = r.Format("2006")
case fieldTypeDate:
convertedValue = r.Format("2006-01-02")
case fieldTypeTime:
convertedValue = r.Format("15:04:05")
default:
}
}
case gtime.Time:
if r.IsZero() {
convertedValue = nil
} else if fieldType == fieldTypeDate {
convertedValue = r.Layout("2006-01-02")
} else if fieldType == fieldTypeTime {
convertedValue = r.Layout("15:04:05")
} else {
convertedValue = r.Time
switch fieldType {
case fieldTypeYear:
convertedValue = r.Layout("2006")
case fieldTypeDate:
convertedValue = r.Layout("2006-01-02")
case fieldTypeTime:
convertedValue = r.Layout("15:04:05")
default:
convertedValue = r.Time
}
}
case *gtime.Time:
if r.IsZero() {
convertedValue = nil
} else if fieldType == fieldTypeDate {
convertedValue = r.Layout("2006-01-02")
} else if fieldType == fieldTypeTime {
convertedValue = r.Layout("15:04:05")
} else {
convertedValue = r.Time
switch fieldType {
case fieldTypeYear:
convertedValue = r.Layout("2006")
case fieldTypeDate:
convertedValue = r.Layout("2006-01-02")
case fieldTypeTime:
convertedValue = r.Layout("15:04:05")
default:
convertedValue = r.Time
}
}
case Counter, *Counter:
@ -181,6 +216,7 @@ Default:
}
}
}
default:
}
return convertedValue, nil