Merge branch 'develop' of github.com:beego/beego into develop

This commit is contained in:
Deng Ming 2023-06-08 23:06:22 +08:00
commit 34c5f1d54d
27 changed files with 1327 additions and 1324 deletions

View File

@ -1,5 +1,6 @@
# developing # developing
- [httplib: fix unstable unit test which use the httplib.org](https://github.com/beego/beego/pull/5232) - [httplib: fix unstable unit test which use the httplib.org](https://github.com/beego/beego/pull/5232)
- [remove adapter package](https://github.com/beego/beego/pull/5239)
## ORM refactoring ## ORM refactoring
- [introducing internal/models pkg](https://github.com/beego/beego/pull/5238) - [introducing internal/models pkg](https://github.com/beego/beego/pull/5238)

View File

@ -1,261 +0,0 @@
// Copyright 2020 beego
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package httplib
import (
"errors"
"net"
"net/http"
"strings"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
type respCarrier struct {
bytes []byte
}
func (r *respCarrier) SetBytes(bytes []byte) {
r.bytes = bytes
}
func (r *respCarrier) String() string {
return string(r.bytes)
}
func TestOptionWithEnableCookie(t *testing.T) {
client, err := NewClient("test", "http://httpbin.org/",
WithEnableCookie(true))
if err != nil {
t.Fatal(err)
}
v := "smallfish"
resp := &respCarrier{}
err = client.Get(resp, "/cookies/set?k1="+v)
if err != nil {
t.Fatal(err)
}
t.Log(resp.String())
err = client.Get(resp, "/cookies")
if err != nil {
t.Fatal(err)
}
t.Log(resp.String())
n := strings.Index(resp.String(), v)
if n == -1 {
t.Fatal(v + " not found in cookie")
}
}
func TestOptionWithUserAgent(t *testing.T) {
v := "beego"
client, err := NewClient("test", "http://httpbin.org/",
WithUserAgent(v))
if err != nil {
t.Fatal(err)
}
resp := &respCarrier{}
err = client.Get(resp, "/headers")
if err != nil {
t.Fatal(err)
}
t.Log(resp.String())
n := strings.Index(resp.String(), v)
if n == -1 {
t.Fatal(v + " not found in user-agent")
}
}
func TestOptionWithCheckRedirect(t *testing.T) {
client, err := NewClient("test", "https://goolnk.com/33BD2j",
WithCheckRedirect(func(redirectReq *http.Request, redirectVia []*http.Request) error {
return errors.New("Redirect triggered")
}))
if err != nil {
t.Fatal(err)
}
err = client.Get(nil, "")
assert.NotNil(t, err)
}
func TestOptionWithHTTPSetting(t *testing.T) {
v := "beego"
var setting BeegoHTTPSettings
setting.EnableCookie = true
setting.UserAgent = v
setting.Transport = &http.Transport{
DialContext: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
DualStack: true,
}).DialContext,
MaxIdleConns: 50,
IdleConnTimeout: 90 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
}
setting.ReadWriteTimeout = 5 * time.Second
client, err := NewClient("test", "http://httpbin.org/",
WithHTTPSetting(setting))
if err != nil {
t.Fatal(err)
}
resp := &respCarrier{}
err = client.Get(resp, "/get")
if err != nil {
t.Fatal(err)
}
t.Log(resp.String())
n := strings.Index(resp.String(), v)
if n == -1 {
t.Fatal(v + " not found in user-agent")
}
}
func TestOptionWithHeader(t *testing.T) {
client, err := NewClient("test", "http://httpbin.org/")
if err != nil {
t.Fatal(err)
}
client.CommonOpts = append(client.CommonOpts, WithHeader("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36"))
resp := &respCarrier{}
err = client.Get(resp, "/headers")
if err != nil {
t.Fatal(err)
}
t.Log(resp.String())
n := strings.Index(resp.String(), "Mozilla/5.0")
if n == -1 {
t.Fatal("Mozilla/5.0 not found in user-agent")
}
}
func TestOptionWithTokenFactory(t *testing.T) {
client, err := NewClient("test", "http://httpbin.org/")
if err != nil {
t.Fatal(err)
}
client.CommonOpts = append(client.CommonOpts,
WithTokenFactory(func() string {
return "testauth"
}))
resp := &respCarrier{}
err = client.Get(resp, "/headers")
if err != nil {
t.Fatal(err)
}
t.Log(resp.String())
n := strings.Index(resp.String(), "testauth")
if n == -1 {
t.Fatal("Auth is not set in request")
}
}
func TestOptionWithBasicAuth(t *testing.T) {
client, err := NewClient("test", "http://httpbin.org/")
if err != nil {
t.Fatal(err)
}
resp := &respCarrier{}
err = client.Get(resp, "/basic-auth/user/passwd",
WithBasicAuth(func() (string, string) {
return "user", "passwd"
}))
if err != nil {
t.Fatal(err)
}
t.Log(resp.String())
n := strings.Index(resp.String(), "authenticated")
if n == -1 {
t.Fatal("authenticated not found in response")
}
}
func TestOptionWithContentType(t *testing.T) {
client, err := NewClient("test", "http://httpbin.org/")
if err != nil {
t.Fatal(err)
}
v := "application/json"
resp := &respCarrier{}
err = client.Get(resp, "/headers", WithContentType(v))
if err != nil {
t.Fatal(err)
}
t.Log(resp.String())
n := strings.Index(resp.String(), v)
if n == -1 {
t.Fatal(v + " not found in header")
}
}
func TestOptionWithParam(t *testing.T) {
client, err := NewClient("test", "http://httpbin.org/")
if err != nil {
t.Fatal(err)
}
v := "smallfish"
resp := &respCarrier{}
err = client.Get(resp, "/get", WithParam("username", v))
if err != nil {
t.Fatal(err)
}
t.Log(resp.String())
n := strings.Index(resp.String(), v)
if n == -1 {
t.Fatal(v + " not found in header")
}
}
func TestOptionWithRetry(t *testing.T) {
client, err := NewClient("test", "https://goolnk.com/33BD2j",
WithCheckRedirect(func(redirectReq *http.Request, redirectVia []*http.Request) error {
return errors.New("Redirect triggered")
}))
if err != nil {
t.Fatal(err)
}
retryAmount := 1
retryDelay := 800 * time.Millisecond
startTime := time.Now().UnixNano() / int64(time.Millisecond)
_ = client.Get(nil, "", WithRetry(retryAmount, retryDelay))
endTime := time.Now().UnixNano() / int64(time.Millisecond)
elapsedTime := endTime - startTime
delayedTime := int64(retryAmount) * retryDelay.Milliseconds()
if elapsedTime < delayedTime {
t.Errorf("Not enough retries. Took %dms. Delay was meant to take %dms", elapsedTime, delayedTime)
}
}

View File

@ -21,6 +21,8 @@ import (
"os" "os"
"strings" "strings"
"github.com/beego/beego/v2/client/orm/internal/utils"
"github.com/beego/beego/v2/client/orm/internal/models" "github.com/beego/beego/v2/client/orm/internal/models"
) )
@ -55,7 +57,7 @@ func RunCommand() {
BootStrap() BootStrap()
args := argString(os.Args[2:]) args := utils.ArgString(os.Args[2:])
name := args.Get(0) name := args.Get(0)
if name == "help" { if name == "help" {

View File

@ -23,17 +23,15 @@ import (
"strings" "strings"
"time" "time"
"github.com/beego/beego/v2/client/orm/internal/logs"
"github.com/beego/beego/v2/client/orm/internal/utils"
"github.com/beego/beego/v2/client/orm/internal/models" "github.com/beego/beego/v2/client/orm/internal/models"
"github.com/beego/beego/v2/client/orm/hints" "github.com/beego/beego/v2/client/orm/hints"
) )
const (
formatTime = "15:04:05"
formatDate = "2006-01-02"
formatDateTime = "2006-01-02 15:04:05"
)
// ErrMissPK missing pk error // ErrMissPK missing pk error
var ErrMissPK = errors.New("missed pk value") var ErrMissPK = errors.New("missed pk value")
@ -125,7 +123,7 @@ func (d *dbBase) collectFieldValue(mi *models.ModelInfo, fi *models.FieldInfo, i
} else { } else {
field := ind.FieldByIndex(fi.FieldIndex) field := ind.FieldByIndex(fi.FieldIndex)
if fi.IsFielder { if fi.IsFielder {
f := field.Addr().Interface().(Fielder) f := field.Addr().Interface().(models.Fielder)
value = f.RawValue() value = f.RawValue()
} else { } else {
switch fi.FieldType { switch fi.FieldType {
@ -174,7 +172,7 @@ func (d *dbBase) collectFieldValue(mi *models.ModelInfo, fi *models.FieldInfo, i
} else { } else {
vu := field.Interface() vu := field.Interface()
if _, ok := vu.(float32); ok { if _, ok := vu.(float32); ok {
value, _ = StrTo(ToStr(vu)).Float64() value, _ = utils.StrTo(utils.ToStr(vu)).Float64()
} else { } else {
value = field.Float() value = field.Float()
} }
@ -244,7 +242,7 @@ func (d *dbBase) collectFieldValue(mi *models.ModelInfo, fi *models.FieldInfo, i
d.ins.TimeToDB(&tnow, tz) d.ins.TimeToDB(&tnow, tz)
value = tnow value = tnow
if fi.IsFielder { if fi.IsFielder {
f := field.Addr().Interface().(Fielder) f := field.Addr().Interface().(models.Fielder)
f.SetRaw(tnow.In(DefaultTimeLoc)) f.SetRaw(tnow.In(DefaultTimeLoc))
} else if field.Kind() == reflect.Ptr { } else if field.Kind() == reflect.Ptr {
v := tnow.In(DefaultTimeLoc) v := tnow.In(DefaultTimeLoc)
@ -482,7 +480,7 @@ func (d *dbBase) InsertValue(ctx context.Context, q dbQuerier, mi *models.ModelI
lastInsertId, err := res.LastInsertId() lastInsertId, err := res.LastInsertId()
if err != nil { if err != nil {
DebugLog.Println(ErrLastInsertIdUnavailable, ':', err) logs.DebugLog.Println(ErrLastInsertIdUnavailable, ':', err)
return lastInsertId, ErrLastInsertIdUnavailable return lastInsertId, ErrLastInsertIdUnavailable
} else { } else {
return lastInsertId, nil return lastInsertId, nil
@ -589,7 +587,7 @@ func (d *dbBase) InsertOrUpdate(ctx context.Context, q dbQuerier, mi *models.Mod
lastInsertId, err := res.LastInsertId() lastInsertId, err := res.LastInsertId()
if err != nil { if err != nil {
DebugLog.Println(ErrLastInsertIdUnavailable, ':', err) logs.DebugLog.Println(ErrLastInsertIdUnavailable, ':', err)
return lastInsertId, ErrLastInsertIdUnavailable return lastInsertId, ErrLastInsertIdUnavailable
} else { } else {
return lastInsertId, nil return lastInsertId, nil
@ -1201,7 +1199,7 @@ func (d *dbBase) GenerateOperatorSQL(mi *models.ModelInfo, fi *models.FieldInfo,
params[0] = "IS NULL" params[0] = "IS NULL"
} }
case "iexact", "contains", "icontains", "startswith", "endswith", "istartswith", "iendswith": case "iexact", "contains", "icontains", "startswith", "endswith", "istartswith", "iendswith":
param := strings.Replace(ToStr(arg), `%`, `\%`, -1) param := strings.Replace(utils.ToStr(arg), `%`, `\%`, -1)
switch operator { switch operator {
case "iexact": case "iexact":
case "contains", "icontains": case "contains", "icontains":
@ -1264,13 +1262,13 @@ func (d *dbBase) convertValueFromDB(fi *models.FieldInfo, val interface{}, tz *t
var value interface{} var value interface{}
var tErr error var tErr error
var str *StrTo var str *utils.StrTo
switch v := val.(type) { switch v := val.(type) {
case []byte: case []byte:
s := StrTo(string(v)) s := utils.StrTo(string(v))
str = &s str = &s
case string: case string:
s := StrTo(v) s := utils.StrTo(v)
str = &s str = &s
} }
@ -1285,7 +1283,7 @@ setValue:
b := v == 1 b := v == 1
value = b value = b
default: default:
s := StrTo(ToStr(v)) s := utils.StrTo(utils.ToStr(v))
str = &s str = &s
} }
} }
@ -1299,7 +1297,7 @@ setValue:
} }
case fieldType == TypeVarCharField || fieldType == TypeCharField || fieldType == TypeTextField || fieldType == TypeJSONField || fieldType == TypeJsonbField: case fieldType == TypeVarCharField || fieldType == TypeCharField || fieldType == TypeTextField || fieldType == TypeJSONField || fieldType == TypeJsonbField:
if str == nil { if str == nil {
value = ToStr(val) value = utils.ToStr(val)
} else { } else {
value = str.String() value = str.String()
} }
@ -1310,7 +1308,7 @@ setValue:
d.ins.TimeFromDB(&t, tz) d.ins.TimeFromDB(&t, tz)
value = t value = t
default: default:
s := StrTo(ToStr(t)) s := utils.StrTo(utils.ToStr(t))
str = &s str = &s
} }
} }
@ -1322,24 +1320,24 @@ setValue:
) )
if fi.TimePrecision != nil && len(s) >= (20+*fi.TimePrecision) { if fi.TimePrecision != nil && len(s) >= (20+*fi.TimePrecision) {
layout := formatDateTime + "." layout := utils.FormatDateTime + "."
for i := 0; i < *fi.TimePrecision; i++ { for i := 0; i < *fi.TimePrecision; i++ {
layout += "0" layout += "0"
} }
t, err = time.ParseInLocation(layout, s[:20+*fi.TimePrecision], tz) t, err = time.ParseInLocation(layout, s[:20+*fi.TimePrecision], tz)
} else if len(s) >= 19 { } else if len(s) >= 19 {
s = s[:19] s = s[:19]
t, err = time.ParseInLocation(formatDateTime, s, tz) t, err = time.ParseInLocation(utils.FormatDateTime, s, tz)
} else if len(s) >= 10 { } else if len(s) >= 10 {
if len(s) > 10 { if len(s) > 10 {
s = s[:10] s = s[:10]
} }
t, err = time.ParseInLocation(formatDate, s, tz) t, err = time.ParseInLocation(utils.FormatDate, s, tz)
} else if len(s) >= 8 { } else if len(s) >= 8 {
if len(s) > 8 { if len(s) > 8 {
s = s[:8] s = s[:8]
} }
t, err = time.ParseInLocation(formatTime, s, tz) t, err = time.ParseInLocation(utils.FormatTime, s, tz)
} }
t = t.In(DefaultTimeLoc) t = t.In(DefaultTimeLoc)
@ -1351,7 +1349,7 @@ setValue:
} }
case fieldType&IsIntegerField > 0: case fieldType&IsIntegerField > 0:
if str == nil { if str == nil {
s := StrTo(ToStr(val)) s := utils.StrTo(utils.ToStr(val))
str = &s str = &s
} }
if str != nil { if str != nil {
@ -1392,7 +1390,7 @@ setValue:
case float64: case float64:
value = v value = v
default: default:
s := StrTo(ToStr(v)) s := utils.StrTo(utils.ToStr(v))
str = &s str = &s
} }
} }
@ -1599,7 +1597,7 @@ setValue:
} }
if !isNative { if !isNative {
fd := field.Addr().Interface().(Fielder) fd := field.Addr().Interface().(models.Fielder)
err := fd.SetRaw(value) err := fd.SetRaw(value)
if err != nil { if err != nil {
err = fmt.Errorf("converted value `%v` set to Fielder `%s` failed, err: %s", value, fi.FullName, err) err = fmt.Errorf("converted value `%v` set to Fielder `%s` failed, err: %s", value, fi.FullName, err)
@ -1918,7 +1916,7 @@ func (d *dbBase) GenerateSpecifyIndex(tableName string, useIndex int, indexes []
case hints.KeyIgnoreIndex: case hints.KeyIgnoreIndex:
useWay = `IGNORE` useWay = `IGNORE`
default: default:
DebugLog.Println("[WARN] Not a valid specifying action, so that action is ignored") logs.DebugLog.Println("[WARN] Not a valid specifying action, so that action is ignored")
return `` return ``
} }

View File

@ -21,6 +21,8 @@ import (
"sync" "sync"
"time" "time"
"github.com/beego/beego/v2/client/orm/internal/logs"
lru "github.com/hashicorp/golang-lru" lru "github.com/hashicorp/golang-lru"
) )
@ -320,7 +322,7 @@ func detectTZ(al *alias) {
al.TZ = t.Location() al.TZ = t.Location()
} }
} else { } else {
DebugLog.Printf("Detect DB timezone: %s %s\n", tz, err.Error()) logs.DebugLog.Printf("Detect DB timezone: %s %s\n", tz, err.Error())
} }
} }
@ -347,7 +349,7 @@ func detectTZ(al *alias) {
if err == nil { if err == nil {
al.TZ = loc al.TZ = loc
} else { } else {
DebugLog.Printf("Detect DB timezone: %s %s\n", tz, err.Error()) logs.DebugLog.Printf("Detect DB timezone: %s %s\n", tz, err.Error())
} }
} }
} }
@ -479,7 +481,7 @@ end:
if db != nil { if db != nil {
db.Close() db.Close()
} }
DebugLog.Println(err.Error()) logs.DebugLog.Println(err.Error())
} }
return err return err

View File

@ -20,6 +20,8 @@ import (
"reflect" "reflect"
"strings" "strings"
"github.com/beego/beego/v2/client/orm/internal/logs"
"github.com/beego/beego/v2/client/orm/internal/models" "github.com/beego/beego/v2/client/orm/internal/models"
) )
@ -161,7 +163,7 @@ func (d *dbBaseMysql) InsertOrUpdate(ctx context.Context, q dbQuerier, mi *model
if err == nil { if err == nil {
lastInsertId, err := res.LastInsertId() lastInsertId, err := res.LastInsertId()
if err != nil { if err != nil {
DebugLog.Println(ErrLastInsertIdUnavailable, ':', err) logs.DebugLog.Println(ErrLastInsertIdUnavailable, ':', err)
return lastInsertId, ErrLastInsertIdUnavailable return lastInsertId, ErrLastInsertIdUnavailable
} else { } else {
return lastInsertId, nil return lastInsertId, nil

View File

@ -19,6 +19,8 @@ import (
"fmt" "fmt"
"strings" "strings"
"github.com/beego/beego/v2/client/orm/internal/logs"
"github.com/beego/beego/v2/client/orm/internal/models" "github.com/beego/beego/v2/client/orm/internal/models"
"github.com/beego/beego/v2/client/orm/hints" "github.com/beego/beego/v2/client/orm/hints"
@ -118,7 +120,7 @@ func (d *dbBaseOracle) GenerateSpecifyIndex(tableName string, useIndex int, inde
case hints.KeyIgnoreIndex: case hints.KeyIgnoreIndex:
hint = `NO_INDEX` hint = `NO_INDEX`
default: default:
DebugLog.Println("[WARN] Not a valid specifying action, so that action is ignored") logs.DebugLog.Println("[WARN] Not a valid specifying action, so that action is ignored")
return `` return ``
} }
@ -158,7 +160,7 @@ func (d *dbBaseOracle) InsertValue(ctx context.Context, q dbQuerier, mi *models.
lastInsertId, err := res.LastInsertId() lastInsertId, err := res.LastInsertId()
if err != nil { if err != nil {
DebugLog.Println(ErrLastInsertIdUnavailable, ':', err) logs.DebugLog.Println(ErrLastInsertIdUnavailable, ':', err)
return lastInsertId, ErrLastInsertIdUnavailable return lastInsertId, ErrLastInsertIdUnavailable
} else { } else {
return lastInsertId, nil return lastInsertId, nil

View File

@ -19,6 +19,8 @@ import (
"fmt" "fmt"
"strconv" "strconv"
"github.com/beego/beego/v2/client/orm/internal/logs"
"github.com/beego/beego/v2/client/orm/internal/models" "github.com/beego/beego/v2/client/orm/internal/models"
) )
@ -187,7 +189,7 @@ func (d *dbBasePostgres) IndexExists(ctx context.Context, db dbQuerier, table st
// GenerateSpecifyIndex return a specifying index clause // GenerateSpecifyIndex return a specifying index clause
func (d *dbBasePostgres) GenerateSpecifyIndex(tableName string, useIndex int, indexes []string) string { func (d *dbBasePostgres) GenerateSpecifyIndex(tableName string, useIndex int, indexes []string) string {
DebugLog.Println("[WARN] Not support any specifying index action, so that action is ignored") logs.DebugLog.Println("[WARN] Not support any specifying index action, so that action is ignored")
return `` return ``
} }

View File

@ -22,6 +22,8 @@ import (
"strings" "strings"
"time" "time"
"github.com/beego/beego/v2/client/orm/internal/logs"
"github.com/beego/beego/v2/client/orm/internal/models" "github.com/beego/beego/v2/client/orm/internal/models"
"github.com/beego/beego/v2/client/orm/hints" "github.com/beego/beego/v2/client/orm/hints"
@ -78,7 +80,7 @@ var _ dbBaser = new(dbBaseSqlite)
// override base db read for update behavior as SQlite does not support syntax // override base db read for update behavior as SQlite does not support syntax
func (d *dbBaseSqlite) Read(ctx context.Context, q dbQuerier, mi *models.ModelInfo, ind reflect.Value, tz *time.Location, cols []string, isForUpdate bool) error { func (d *dbBaseSqlite) Read(ctx context.Context, q dbQuerier, mi *models.ModelInfo, ind reflect.Value, tz *time.Location, cols []string, isForUpdate bool) error {
if isForUpdate { if isForUpdate {
DebugLog.Println("[WARN] SQLite does not support SELECT FOR UPDATE query, isForUpdate param is ignored and always as false to do the work") logs.DebugLog.Println("[WARN] SQLite does not support SELECT FOR UPDATE query, isForUpdate param is ignored and always as false to do the work")
} }
return d.dbBase.Read(ctx, q, mi, ind, tz, cols, false) return d.dbBase.Read(ctx, q, mi, ind, tz, cols, false)
} }
@ -173,7 +175,7 @@ func (d *dbBaseSqlite) GenerateSpecifyIndex(tableName string, useIndex int, inde
case hints.KeyUseIndex, hints.KeyForceIndex: case hints.KeyUseIndex, hints.KeyForceIndex:
return fmt.Sprintf(` INDEXED BY %s `, strings.Join(s, `,`)) return fmt.Sprintf(` INDEXED BY %s `, strings.Join(s, `,`))
default: default:
DebugLog.Println("[WARN] Not a valid specifying action, so that action is ignored") logs.DebugLog.Println("[WARN] Not a valid specifying action, so that action is ignored")
return `` return ``
} }
} }

View File

@ -19,6 +19,8 @@ import (
"reflect" "reflect"
"time" "time"
"github.com/beego/beego/v2/client/orm/internal/utils"
"github.com/beego/beego/v2/client/orm/internal/models" "github.com/beego/beego/v2/client/orm/internal/models"
) )
@ -81,27 +83,27 @@ outFor:
var err error var err error
if len(v) >= 19 { if len(v) >= 19 {
s := v[:19] s := v[:19]
t, err = time.ParseInLocation(formatDateTime, s, DefaultTimeLoc) t, err = time.ParseInLocation(utils.FormatDateTime, s, DefaultTimeLoc)
} else if len(v) >= 10 { } else if len(v) >= 10 {
s := v s := v
if len(v) > 10 { if len(v) > 10 {
s = v[:10] s = v[:10]
} }
t, err = time.ParseInLocation(formatDate, s, tz) t, err = time.ParseInLocation(utils.FormatDate, s, tz)
} else { } else {
s := v s := v
if len(s) > 8 { if len(s) > 8 {
s = v[:8] s = v[:8]
} }
t, err = time.ParseInLocation(formatTime, s, tz) t, err = time.ParseInLocation(utils.FormatTime, s, tz)
} }
if err == nil { if err == nil {
if fi.FieldType == TypeDateField { if fi.FieldType == TypeDateField {
v = t.In(tz).Format(formatDate) v = t.In(tz).Format(utils.FormatDate)
} else if fi.FieldType == TypeDateTimeField { } else if fi.FieldType == TypeDateTimeField {
v = t.In(tz).Format(formatDateTime) v = t.In(tz).Format(utils.FormatDateTime)
} else { } else {
v = t.In(tz).Format(formatTime) v = t.In(tz).Format(utils.FormatTime)
} }
} }
} }
@ -112,7 +114,7 @@ outFor:
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
arg = val.Uint() arg = val.Uint()
case reflect.Float32: case reflect.Float32:
arg, _ = StrTo(ToStr(arg)).Float64() arg, _ = utils.StrTo(utils.ToStr(arg)).Float64()
case reflect.Float64: case reflect.Float64:
arg = val.Float() arg = val.Float()
case reflect.Bool: case reflect.Bool:
@ -146,13 +148,13 @@ outFor:
case reflect.Struct: case reflect.Struct:
if v, ok := arg.(time.Time); ok { if v, ok := arg.(time.Time); ok {
if fi != nil && fi.FieldType == TypeDateField { if fi != nil && fi.FieldType == TypeDateField {
arg = v.In(tz).Format(formatDate) arg = v.In(tz).Format(utils.FormatDate)
} else if fi != nil && fi.FieldType == TypeDateTimeField { } else if fi != nil && fi.FieldType == TypeDateTimeField {
arg = v.In(tz).Format(formatDateTime) arg = v.In(tz).Format(utils.FormatDateTime)
} else if fi != nil && fi.FieldType == TypeTimeField { } else if fi != nil && fi.FieldType == TypeTimeField {
arg = v.In(tz).Format(formatTime) arg = v.In(tz).Format(utils.FormatTime)
} else { } else {
arg = v.In(tz).Format(formatDateTime) arg = v.In(tz).Format(utils.FormatDateTime)
} }
} else { } else {
typ := val.Type() typ := val.Type()

View File

@ -20,6 +20,8 @@ import (
"reflect" "reflect"
"time" "time"
utils2 "github.com/beego/beego/v2/client/orm/internal/utils"
"github.com/beego/beego/v2/client/orm/internal/models" "github.com/beego/beego/v2/client/orm/internal/models"
"github.com/beego/beego/v2/core/logs" "github.com/beego/beego/v2/core/logs"
@ -200,7 +202,7 @@ func (f *filterOrmDecorator) QueryTable(ptrStructOrTableName interface{}) QueryS
if table, ok := ptrStructOrTableName.(string); ok { if table, ok := ptrStructOrTableName.(string); ok {
name = table name = table
} else { } else {
name = models.GetFullName(indirectType(reflect.TypeOf(ptrStructOrTableName))) name = models.GetFullName(utils2.IndirectType(reflect.TypeOf(ptrStructOrTableName)))
md = ptrStructOrTableName md = ptrStructOrTableName
} }

View File

@ -0,0 +1,20 @@
package logs
import (
"io"
"log"
"os"
)
var DebugLog = NewLog(os.Stdout)
// Log implement the log.Logger
type Log struct {
*log.Logger
}
func NewLog(out io.Writer) *Log {
d := new(Log)
d.Logger = log.New(out, "[ORM]", log.LstdFlags)
return d
}

View File

@ -0,0 +1,785 @@
// Copyright 2014 beego Author. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package models
import (
"fmt"
"strconv"
"time"
"github.com/beego/beego/v2/client/orm/internal/utils"
)
// Define the Type enum
const (
TypeBooleanField = 1 << iota
TypeVarCharField
TypeCharField
TypeTextField
TypeTimeField
TypeDateField
TypeDateTimeField
TypeBitField
TypeSmallIntegerField
TypeIntegerField
TypeBigIntegerField
TypePositiveBitField
TypePositiveSmallIntegerField
TypePositiveIntegerField
TypePositiveBigIntegerField
TypeFloatField
TypeDecimalField
TypeJSONField
TypeJsonbField
RelForeignKey
RelOneToOne
RelManyToMany
RelReverseOne
RelReverseMany
)
// Define some logic enum
const (
IsIntegerField = ^-TypePositiveBigIntegerField >> 6 << 7
IsPositiveIntegerField = ^-TypePositiveBigIntegerField >> 10 << 11
IsRelField = ^-RelReverseMany >> 18 << 19
IsFieldType = ^-RelReverseMany<<1 + 1
)
// BooleanField A true/false field.
type BooleanField bool
// Value return the BooleanField
func (e BooleanField) Value() bool {
return bool(e)
}
// Set will set the BooleanField
func (e *BooleanField) Set(d bool) {
*e = BooleanField(d)
}
// String format the Bool to string
func (e *BooleanField) String() string {
return strconv.FormatBool(e.Value())
}
// FieldType return BooleanField the type
func (e *BooleanField) FieldType() int {
return TypeBooleanField
}
// SetRaw set the interface to bool
func (e *BooleanField) SetRaw(value interface{}) error {
switch d := value.(type) {
case bool:
e.Set(d)
case string:
v, err := utils.StrTo(d).Bool()
if err == nil {
e.Set(v)
}
return err
default:
return fmt.Errorf("<BooleanField.SetRaw> unknown value `%s`", value)
}
return nil
}
// RawValue return the current value
func (e *BooleanField) RawValue() interface{} {
return e.Value()
}
// verify the BooleanField implement the Fielder interface
var _ Fielder = new(BooleanField)
// CharField A string field
// required values tag: size
// The size is enforced at the database level and in modelss validation.
// eg: `orm:"size(120)"`
type CharField string
// Value return the CharField's Value
func (e CharField) Value() string {
return string(e)
}
// Set CharField value
func (e *CharField) Set(d string) {
*e = CharField(d)
}
// String return the CharField
func (e *CharField) String() string {
return e.Value()
}
// FieldType return the enum type
func (e *CharField) FieldType() int {
return TypeVarCharField
}
// SetRaw set the interface to string
func (e *CharField) SetRaw(value interface{}) error {
switch d := value.(type) {
case string:
e.Set(d)
default:
return fmt.Errorf("<CharField.SetRaw> unknown value `%s`", value)
}
return nil
}
// RawValue return the CharField value
func (e *CharField) RawValue() interface{} {
return e.Value()
}
// verify CharField implement Fielder
var _ Fielder = new(CharField)
// TimeField A time, represented in go by a time.Time instance.
// only time values like 10:00:00
// Has a few extra, optional attr tag:
//
// auto_now:
// Automatically set the field to now every time the object is saved. Useful for “last-modified” timestamps.
// Note that the current date is always used; its not just a default value that you can override.
//
// auto_now_add:
// Automatically set the field to now when the object is first created. Useful for creation of timestamps.
// Note that the current date is always used; its not just a default value that you can override.
//
// eg: `orm:"auto_now"` or `orm:"auto_now_add"`
type TimeField time.Time
// Value return the time.Time
func (e TimeField) Value() time.Time {
return time.Time(e)
}
// Set set the TimeField's value
func (e *TimeField) Set(d time.Time) {
*e = TimeField(d)
}
// String convert time to string
func (e *TimeField) String() string {
return e.Value().String()
}
// FieldType return enum type Date
func (e *TimeField) FieldType() int {
return TypeDateField
}
// SetRaw convert the interface to time.Time. Allow string and time.Time
func (e *TimeField) SetRaw(value interface{}) error {
switch d := value.(type) {
case time.Time:
e.Set(d)
case string:
v, err := utils.TimeParse(d, utils.FormatTime)
if err == nil {
e.Set(v)
}
return err
default:
return fmt.Errorf("<TimeField.SetRaw> unknown value `%s`", value)
}
return nil
}
// RawValue return time value
func (e *TimeField) RawValue() interface{} {
return e.Value()
}
var _ Fielder = new(TimeField)
// DateField A date, represented in go by a time.Time instance.
// only date values like 2006-01-02
// Has a few extra, optional attr tag:
//
// auto_now:
// Automatically set the field to now every time the object is saved. Useful for “last-modified” timestamps.
// Note that the current date is always used; its not just a default value that you can override.
//
// auto_now_add:
// Automatically set the field to now when the object is first created. Useful for creation of timestamps.
// Note that the current date is always used; its not just a default value that you can override.
//
// eg: `orm:"auto_now"` or `orm:"auto_now_add"`
type DateField time.Time
// Value return the time.Time
func (e DateField) Value() time.Time {
return time.Time(e)
}
// Set set the DateField's value
func (e *DateField) Set(d time.Time) {
*e = DateField(d)
}
// String convert datetime to string
func (e *DateField) String() string {
return e.Value().String()
}
// FieldType return enum type Date
func (e *DateField) FieldType() int {
return TypeDateField
}
// SetRaw convert the interface to time.Time. Allow string and time.Time
func (e *DateField) SetRaw(value interface{}) error {
switch d := value.(type) {
case time.Time:
e.Set(d)
case string:
v, err := utils.TimeParse(d, utils.FormatDate)
if err == nil {
e.Set(v)
}
return err
default:
return fmt.Errorf("<DateField.SetRaw> unknown value `%s`", value)
}
return nil
}
// RawValue return Date value
func (e *DateField) RawValue() interface{} {
return e.Value()
}
// verify DateField implement fielder interface
var _ Fielder = new(DateField)
// DateTimeField A date, represented in go by a time.Time instance.
// datetime values like 2006-01-02 15:04:05
// Takes the same extra arguments as DateField.
type DateTimeField time.Time
// Value return the datetime value
func (e DateTimeField) Value() time.Time {
return time.Time(e)
}
// Set set the time.Time to datetime
func (e *DateTimeField) Set(d time.Time) {
*e = DateTimeField(d)
}
// String return the time's String
func (e *DateTimeField) String() string {
return e.Value().String()
}
// FieldType return the enum TypeDateTimeField
func (e *DateTimeField) FieldType() int {
return TypeDateTimeField
}
// SetRaw convert the string or time.Time to DateTimeField
func (e *DateTimeField) SetRaw(value interface{}) error {
switch d := value.(type) {
case time.Time:
e.Set(d)
case string:
v, err := utils.TimeParse(d, utils.FormatDateTime)
if err == nil {
e.Set(v)
}
return err
default:
return fmt.Errorf("<DateTimeField.SetRaw> unknown value `%s`", value)
}
return nil
}
// RawValue return the datetime value
func (e *DateTimeField) RawValue() interface{} {
return e.Value()
}
// verify datetime implement fielder
var _ Fielder = new(DateTimeField)
// FloatField A floating-point number represented in go by a float32 value.
type FloatField float64
// Value return the FloatField value
func (e FloatField) Value() float64 {
return float64(e)
}
// Set the Float64
func (e *FloatField) Set(d float64) {
*e = FloatField(d)
}
// String return the string
func (e *FloatField) String() string {
return utils.ToStr(e.Value(), -1, 32)
}
// FieldType return the enum type
func (e *FloatField) FieldType() int {
return TypeFloatField
}
// SetRaw converter interface Float64 float32 or string to FloatField
func (e *FloatField) SetRaw(value interface{}) error {
switch d := value.(type) {
case float32:
e.Set(float64(d))
case float64:
e.Set(d)
case string:
v, err := utils.StrTo(d).Float64()
if err == nil {
e.Set(v)
}
return err
default:
return fmt.Errorf("<FloatField.SetRaw> unknown value `%s`", value)
}
return nil
}
// RawValue return the FloatField value
func (e *FloatField) RawValue() interface{} {
return e.Value()
}
// verify FloatField implement Fielder
var _ Fielder = new(FloatField)
// SmallIntegerField -32768 to 32767
type SmallIntegerField int16
// Value return int16 value
func (e SmallIntegerField) Value() int16 {
return int16(e)
}
// Set the SmallIntegerField value
func (e *SmallIntegerField) Set(d int16) {
*e = SmallIntegerField(d)
}
// String convert smallint to string
func (e *SmallIntegerField) String() string {
return utils.ToStr(e.Value())
}
// FieldType return enum type SmallIntegerField
func (e *SmallIntegerField) FieldType() int {
return TypeSmallIntegerField
}
// SetRaw convert interface int16/string to int16
func (e *SmallIntegerField) SetRaw(value interface{}) error {
switch d := value.(type) {
case int16:
e.Set(d)
case string:
v, err := utils.StrTo(d).Int16()
if err == nil {
e.Set(v)
}
return err
default:
return fmt.Errorf("<SmallIntegerField.SetRaw> unknown value `%s`", value)
}
return nil
}
// RawValue return smallint value
func (e *SmallIntegerField) RawValue() interface{} {
return e.Value()
}
// verify SmallIntegerField implement Fielder
var _ Fielder = new(SmallIntegerField)
// IntegerField -2147483648 to 2147483647
type IntegerField int32
// Value return the int32
func (e IntegerField) Value() int32 {
return int32(e)
}
// Set IntegerField value
func (e *IntegerField) Set(d int32) {
*e = IntegerField(d)
}
// String convert Int32 to string
func (e *IntegerField) String() string {
return utils.ToStr(e.Value())
}
// FieldType return the enum type
func (e *IntegerField) FieldType() int {
return TypeIntegerField
}
// SetRaw convert interface int32/string to int32
func (e *IntegerField) SetRaw(value interface{}) error {
switch d := value.(type) {
case int32:
e.Set(d)
case string:
v, err := utils.StrTo(d).Int32()
if err == nil {
e.Set(v)
}
return err
default:
return fmt.Errorf("<IntegerField.SetRaw> unknown value `%s`", value)
}
return nil
}
// RawValue return IntegerField value
func (e *IntegerField) RawValue() interface{} {
return e.Value()
}
// verify IntegerField implement Fielder
var _ Fielder = new(IntegerField)
// BigIntegerField -9223372036854775808 to 9223372036854775807.
type BigIntegerField int64
// Value return int64
func (e BigIntegerField) Value() int64 {
return int64(e)
}
// Set the BigIntegerField value
func (e *BigIntegerField) Set(d int64) {
*e = BigIntegerField(d)
}
// String convert BigIntegerField to string
func (e *BigIntegerField) String() string {
return utils.ToStr(e.Value())
}
// FieldType return enum type
func (e *BigIntegerField) FieldType() int {
return TypeBigIntegerField
}
// SetRaw convert interface int64/string to int64
func (e *BigIntegerField) SetRaw(value interface{}) error {
switch d := value.(type) {
case int64:
e.Set(d)
case string:
v, err := utils.StrTo(d).Int64()
if err == nil {
e.Set(v)
}
return err
default:
return fmt.Errorf("<BigIntegerField.SetRaw> unknown value `%s`", value)
}
return nil
}
// RawValue return BigIntegerField value
func (e *BigIntegerField) RawValue() interface{} {
return e.Value()
}
// verify BigIntegerField implement Fielder
var _ Fielder = new(BigIntegerField)
// PositiveSmallIntegerField 0 to 65535
type PositiveSmallIntegerField uint16
// Value return uint16
func (e PositiveSmallIntegerField) Value() uint16 {
return uint16(e)
}
// Set PositiveSmallIntegerField value
func (e *PositiveSmallIntegerField) Set(d uint16) {
*e = PositiveSmallIntegerField(d)
}
// String convert uint16 to string
func (e *PositiveSmallIntegerField) String() string {
return utils.ToStr(e.Value())
}
// FieldType return enum type
func (e *PositiveSmallIntegerField) FieldType() int {
return TypePositiveSmallIntegerField
}
// SetRaw convert Interface uint16/string to uint16
func (e *PositiveSmallIntegerField) SetRaw(value interface{}) error {
switch d := value.(type) {
case uint16:
e.Set(d)
case string:
v, err := utils.StrTo(d).Uint16()
if err == nil {
e.Set(v)
}
return err
default:
return fmt.Errorf("<PositiveSmallIntegerField.SetRaw> unknown value `%s`", value)
}
return nil
}
// RawValue returns PositiveSmallIntegerField value
func (e *PositiveSmallIntegerField) RawValue() interface{} {
return e.Value()
}
// verify PositiveSmallIntegerField implement Fielder
var _ Fielder = new(PositiveSmallIntegerField)
// PositiveIntegerField 0 to 4294967295
type PositiveIntegerField uint32
// Value return PositiveIntegerField value. Uint32
func (e PositiveIntegerField) Value() uint32 {
return uint32(e)
}
// Set the PositiveIntegerField value
func (e *PositiveIntegerField) Set(d uint32) {
*e = PositiveIntegerField(d)
}
// String convert PositiveIntegerField to string
func (e *PositiveIntegerField) String() string {
return utils.ToStr(e.Value())
}
// FieldType return enum type
func (e *PositiveIntegerField) FieldType() int {
return TypePositiveIntegerField
}
// SetRaw convert interface uint32/string to Uint32
func (e *PositiveIntegerField) SetRaw(value interface{}) error {
switch d := value.(type) {
case uint32:
e.Set(d)
case string:
v, err := utils.StrTo(d).Uint32()
if err == nil {
e.Set(v)
}
return err
default:
return fmt.Errorf("<PositiveIntegerField.SetRaw> unknown value `%s`", value)
}
return nil
}
// RawValue return the PositiveIntegerField Value
func (e *PositiveIntegerField) RawValue() interface{} {
return e.Value()
}
// verify PositiveIntegerField implement Fielder
var _ Fielder = new(PositiveIntegerField)
// PositiveBigIntegerField 0 to 18446744073709551615
type PositiveBigIntegerField uint64
// Value return uint64
func (e PositiveBigIntegerField) Value() uint64 {
return uint64(e)
}
// Set PositiveBigIntegerField value
func (e *PositiveBigIntegerField) Set(d uint64) {
*e = PositiveBigIntegerField(d)
}
// String convert PositiveBigIntegerField to string
func (e *PositiveBigIntegerField) String() string {
return utils.ToStr(e.Value())
}
// FieldType return enum type
func (e *PositiveBigIntegerField) FieldType() int {
return TypePositiveIntegerField
}
// SetRaw convert interface uint64/string to Uint64
func (e *PositiveBigIntegerField) SetRaw(value interface{}) error {
switch d := value.(type) {
case uint64:
e.Set(d)
case string:
v, err := utils.StrTo(d).Uint64()
if err == nil {
e.Set(v)
}
return err
default:
return fmt.Errorf("<PositiveBigIntegerField.SetRaw> unknown value `%s`", value)
}
return nil
}
// RawValue return PositiveBigIntegerField value
func (e *PositiveBigIntegerField) RawValue() interface{} {
return e.Value()
}
// verify PositiveBigIntegerField implement Fielder
var _ Fielder = new(PositiveBigIntegerField)
// TextField A large text field.
type TextField string
// Value return TextField value
func (e TextField) Value() string {
return string(e)
}
// Set the TextField value
func (e *TextField) Set(d string) {
*e = TextField(d)
}
// String convert TextField to string
func (e *TextField) String() string {
return e.Value()
}
// FieldType return enum type
func (e *TextField) FieldType() int {
return TypeTextField
}
// SetRaw convert interface string to string
func (e *TextField) SetRaw(value interface{}) error {
switch d := value.(type) {
case string:
e.Set(d)
default:
return fmt.Errorf("<TextField.SetRaw> unknown value `%s`", value)
}
return nil
}
// RawValue return TextField value
func (e *TextField) RawValue() interface{} {
return e.Value()
}
// verify TextField implement Fielder
var _ Fielder = new(TextField)
// JSONField postgres json field.
type JSONField string
// Value return JSONField value
func (j JSONField) Value() string {
return string(j)
}
// Set the JSONField value
func (j *JSONField) Set(d string) {
*j = JSONField(d)
}
// String convert JSONField to string
func (j *JSONField) String() string {
return j.Value()
}
// FieldType return enum type
func (j *JSONField) FieldType() int {
return TypeJSONField
}
// SetRaw convert interface string to string
func (j *JSONField) SetRaw(value interface{}) error {
switch d := value.(type) {
case string:
j.Set(d)
default:
return fmt.Errorf("<JSONField.SetRaw> unknown value `%s`", value)
}
return nil
}
// RawValue return JSONField value
func (j *JSONField) RawValue() interface{} {
return j.Value()
}
// verify JSONField implement Fielder
var _ Fielder = new(JSONField)
// JsonbField postgres json field.
type JsonbField string
// Value return JsonbField value
func (j JsonbField) Value() string {
return string(j)
}
// Set the JsonbField value
func (j *JsonbField) Set(d string) {
*j = JsonbField(d)
}
// String convert JsonbField to string
func (j *JsonbField) String() string {
return j.Value()
}
// FieldType return enum type
func (j *JsonbField) FieldType() int {
return TypeJsonbField
}
// SetRaw convert interface string to string
func (j *JsonbField) SetRaw(value interface{}) error {
switch d := value.(type) {
case string:
j.Set(d)
default:
return fmt.Errorf("<JsonbField.SetRaw> unknown value `%s`", value)
}
return nil
}
// RawValue return JsonbField value
func (j *JsonbField) RawValue() interface{} {
return j.Value()
}
// verify JsonbField implement Fielder
var _ Fielder = new(JsonbField)

View File

@ -20,7 +20,7 @@ import (
"reflect" "reflect"
"strings" "strings"
"github.com/beego/beego/v2/client/orm" "github.com/beego/beego/v2/client/orm/internal/utils"
) )
var errSkipField = errors.New("skip field") var errSkipField = errors.New("skip field")
@ -125,7 +125,7 @@ type FieldInfo struct {
Column string Column string
AddrValue reflect.Value AddrValue reflect.Value
Sf reflect.StructField Sf reflect.StructField
Initial orm.StrTo // store the default value Initial utils.StrTo // store the default value
Size int Size int
ReverseField string ReverseField string
ReverseFieldInfo *FieldInfo ReverseFieldInfo *FieldInfo
@ -147,7 +147,7 @@ func NewFieldInfo(mi *ModelInfo, field reflect.Value, sf reflect.StructField, mN
var ( var (
tag string tag string
tagValue string tagValue string
initial orm.StrTo // store the default value initial utils.StrTo // store the default value
fieldType int fieldType int
attrs map[string]bool attrs map[string]bool
tags map[string]string tags map[string]string
@ -163,7 +163,7 @@ func NewFieldInfo(mi *ModelInfo, field reflect.Value, sf reflect.StructField, mN
addrField = field addrField = field
if field.CanAddr() && field.Kind() != reflect.Ptr { if field.CanAddr() && field.Kind() != reflect.Ptr {
addrField = field.Addr() addrField = field.Addr()
if _, ok := addrField.Interface().(orm.Fielder); !ok { if _, ok := addrField.Interface().(Fielder); !ok {
if field.Kind() == reflect.Slice { if field.Kind() == reflect.Slice {
addrField = field addrField = field
} }
@ -188,14 +188,14 @@ func NewFieldInfo(mi *ModelInfo, field reflect.Value, sf reflect.StructField, mN
checkType: checkType:
switch f := addrField.Interface().(type) { switch f := addrField.Interface().(type) {
case orm.Fielder: case Fielder:
fi.IsFielder = true fi.IsFielder = true
if field.Kind() == reflect.Ptr { if field.Kind() == reflect.Ptr {
err = fmt.Errorf("the model Fielder can not be use ptr") err = fmt.Errorf("the model Fielder can not be use ptr")
goto end goto end
} }
fieldType = f.FieldType() fieldType = f.FieldType()
if fieldType&orm.IsRelField > 0 { if fieldType&IsRelField > 0 {
err = fmt.Errorf("unsupport type custom field, please refer to https://github.com/beego/beego/v2/blob/master/orm/models_fields.go#L24-L42") err = fmt.Errorf("unsupport type custom field, please refer to https://github.com/beego/beego/v2/blob/master/orm/models_fields.go#L24-L42")
goto end goto end
} }
@ -205,13 +205,13 @@ checkType:
if tagValue != "" { if tagValue != "" {
switch tagValue { switch tagValue {
case "fk": case "fk":
fieldType = orm.RelForeignKey fieldType = RelForeignKey
break checkType break checkType
case "one": case "one":
fieldType = orm.RelOneToOne fieldType = RelOneToOne
break checkType break checkType
case "m2m": case "m2m":
fieldType = orm.RelManyToMany fieldType = RelManyToMany
if tv := tags["rel_table"]; tv != "" { if tv := tags["rel_table"]; tv != "" {
fi.RelTable = tv fi.RelTable = tv
} else if tv := tags["rel_through"]; tv != "" { } else if tv := tags["rel_through"]; tv != "" {
@ -228,10 +228,10 @@ checkType:
if tagValue != "" { if tagValue != "" {
switch tagValue { switch tagValue {
case "one": case "one":
fieldType = orm.RelReverseOne fieldType = RelReverseOne
break checkType break checkType
case "many": case "many":
fieldType = orm.RelReverseMany fieldType = RelReverseMany
if tv := tags["rel_table"]; tv != "" { if tv := tags["rel_table"]; tv != "" {
fi.RelTable = tv fi.RelTable = tv
} else if tv := tags["rel_through"]; tv != "" { } else if tv := tags["rel_through"]; tv != "" {
@ -248,26 +248,26 @@ checkType:
if err != nil { if err != nil {
goto end goto end
} }
if fieldType == orm.TypeVarCharField { if fieldType == TypeVarCharField {
switch tags["type"] { switch tags["type"] {
case "char": case "char":
fieldType = orm.TypeCharField fieldType = TypeCharField
case "text": case "text":
fieldType = orm.TypeTextField fieldType = TypeTextField
case "json": case "json":
fieldType = orm.TypeJSONField fieldType = TypeJSONField
case "jsonb": case "jsonb":
fieldType = orm.TypeJsonbField fieldType = TypeJsonbField
} }
} }
if fieldType == orm.TypeFloatField && (digits != "" || decimals != "") { if fieldType == TypeFloatField && (digits != "" || decimals != "") {
fieldType = orm.TypeDecimalField fieldType = TypeDecimalField
} }
if fieldType == orm.TypeDateTimeField && tags["type"] == "date" { if fieldType == TypeDateTimeField && tags["type"] == "date" {
fieldType = orm.TypeDateField fieldType = TypeDateField
} }
if fieldType == orm.TypeTimeField && tags["type"] == "time" { if fieldType == TypeTimeField && tags["type"] == "time" {
fieldType = orm.TypeTimeField fieldType = TypeTimeField
} }
} }
@ -275,12 +275,12 @@ checkType:
// rel should Ptr // rel should Ptr
// reverse should slice []*struct // reverse should slice []*struct
switch fieldType { switch fieldType {
case orm.RelForeignKey, orm.RelOneToOne, orm.RelReverseOne: case RelForeignKey, RelOneToOne, RelReverseOne:
if field.Kind() != reflect.Ptr { if field.Kind() != reflect.Ptr {
err = fmt.Errorf("rel/reverse:one field must be *%s", field.Type().Name()) err = fmt.Errorf("rel/reverse:one field must be *%s", field.Type().Name())
goto end goto end
} }
case orm.RelManyToMany, orm.RelReverseMany: case RelManyToMany, RelReverseMany:
if field.Kind() != reflect.Slice { if field.Kind() != reflect.Slice {
err = fmt.Errorf("rel/reverse:many field must be slice") err = fmt.Errorf("rel/reverse:many field must be slice")
goto end goto end
@ -292,7 +292,7 @@ checkType:
} }
} }
if fieldType&orm.IsFieldType == 0 { if fieldType&IsFieldType == 0 {
err = fmt.Errorf("wrong field type") err = fmt.Errorf("wrong field type")
goto end goto end
} }
@ -317,7 +317,7 @@ checkType:
} }
switch fieldType { switch fieldType {
case orm.RelManyToMany, orm.RelReverseMany, orm.RelReverseOne: case RelManyToMany, RelReverseMany, RelReverseOne:
fi.Null = false fi.Null = false
fi.Index = false fi.Index = false
fi.Auto = false fi.Auto = false
@ -328,12 +328,12 @@ checkType:
} }
switch fieldType { switch fieldType {
case orm.RelForeignKey, orm.RelOneToOne, orm.RelManyToMany: case RelForeignKey, RelOneToOne, RelManyToMany:
fi.Rel = true fi.Rel = true
if fieldType == orm.RelOneToOne { if fieldType == RelOneToOne {
fi.Unique = true fi.Unique = true
} }
case orm.RelReverseMany, orm.RelReverseOne: case RelReverseMany, RelReverseOne:
fi.Reverse = true fi.Reverse = true
} }
@ -363,10 +363,10 @@ checkType:
} }
switch fieldType { switch fieldType {
case orm.TypeBooleanField: case TypeBooleanField:
case orm.TypeVarCharField, orm.TypeCharField, orm.TypeJSONField, orm.TypeJsonbField: case TypeVarCharField, TypeCharField, TypeJSONField, TypeJsonbField:
if size != "" { if size != "" {
v, e := orm.StrTo(size).Int32() v, e := utils.StrTo(size).Int32()
if e != nil { if e != nil {
err = fmt.Errorf("wrong size value `%s`", size) err = fmt.Errorf("wrong size value `%s`", size)
} else { } else {
@ -376,13 +376,13 @@ checkType:
fi.Size = 255 fi.Size = 255
fi.ToText = true fi.ToText = true
} }
case orm.TypeTextField: case TypeTextField:
fi.Index = false fi.Index = false
fi.Unique = false fi.Unique = false
case orm.TypeTimeField, orm.TypeDateField, orm.TypeDateTimeField: case TypeTimeField, TypeDateField, TypeDateTimeField:
if fieldType == orm.TypeDateTimeField { if fieldType == TypeDateTimeField {
if precision != "" { if precision != "" {
v, e := orm.StrTo(precision).Int() v, e := utils.StrTo(precision).Int()
if e != nil { if e != nil {
err = fmt.Errorf("convert %s to int error:%v", precision, e) err = fmt.Errorf("convert %s to int error:%v", precision, e)
} else { } else {
@ -396,12 +396,12 @@ checkType:
} else if attrs["auto_now_add"] { } else if attrs["auto_now_add"] {
fi.AutoNowAdd = true fi.AutoNowAdd = true
} }
case orm.TypeFloatField: case TypeFloatField:
case orm.TypeDecimalField: case TypeDecimalField:
d1 := digits d1 := digits
d2 := decimals d2 := decimals
v1, er1 := orm.StrTo(d1).Int8() v1, er1 := utils.StrTo(d1).Int8()
v2, er2 := orm.StrTo(d2).Int8() v2, er2 := utils.StrTo(d2).Int8()
if er1 != nil || er2 != nil { if er1 != nil || er2 != nil {
err = fmt.Errorf("wrong digits/decimals value %s/%s", d2, d1) err = fmt.Errorf("wrong digits/decimals value %s/%s", d2, d1)
goto end goto end
@ -410,12 +410,12 @@ checkType:
fi.Decimals = int(v2) fi.Decimals = int(v2)
default: default:
switch { switch {
case fieldType&orm.IsIntegerField > 0: case fieldType&IsIntegerField > 0:
case fieldType&orm.IsRelField > 0: case fieldType&IsRelField > 0:
} }
} }
if fieldType&orm.IsIntegerField == 0 { if fieldType&IsIntegerField == 0 {
if fi.Auto { if fi.Auto {
err = fmt.Errorf("non-integer type cannot set auto") err = fmt.Errorf("non-integer type cannot set auto")
goto end goto end
@ -442,32 +442,32 @@ checkType:
} }
// can not set default for these type // can not set default for these type
if fi.Auto || fi.Pk || fi.Unique || fieldType == orm.TypeTimeField || fieldType == orm.TypeDateField || fieldType == orm.TypeDateTimeField { if fi.Auto || fi.Pk || fi.Unique || fieldType == TypeTimeField || fieldType == TypeDateField || fieldType == TypeDateTimeField {
initial.Clear() initial.Clear()
} }
if initial.Exist() { if initial.Exist() {
v := initial v := initial
switch fieldType { switch fieldType {
case orm.TypeBooleanField: case TypeBooleanField:
_, err = v.Bool() _, err = v.Bool()
case orm.TypeFloatField, orm.TypeDecimalField: case TypeFloatField, TypeDecimalField:
_, err = v.Float64() _, err = v.Float64()
case orm.TypeBitField: case TypeBitField:
_, err = v.Int8() _, err = v.Int8()
case orm.TypeSmallIntegerField: case TypeSmallIntegerField:
_, err = v.Int16() _, err = v.Int16()
case orm.TypeIntegerField: case TypeIntegerField:
_, err = v.Int32() _, err = v.Int32()
case orm.TypeBigIntegerField: case TypeBigIntegerField:
_, err = v.Int64() _, err = v.Int64()
case orm.TypePositiveBitField: case TypePositiveBitField:
_, err = v.Uint8() _, err = v.Uint8()
case orm.TypePositiveSmallIntegerField: case TypePositiveSmallIntegerField:
_, err = v.Uint16() _, err = v.Uint16()
case orm.TypePositiveIntegerField: case TypePositiveIntegerField:
_, err = v.Uint32() _, err = v.Uint32()
case orm.TypePositiveBigIntegerField: case TypePositiveBigIntegerField:
_, err = v.Uint64() _, err = v.Uint64()
} }
if err != nil { if err != nil {

View File

@ -18,8 +18,6 @@ import (
"fmt" "fmt"
"os" "os"
"reflect" "reflect"
"github.com/beego/beego/v2/client/orm"
) )
// ModelInfo single model info // ModelInfo single model info
@ -113,7 +111,7 @@ func NewM2MModelInfo(m1, m2 *ModelInfo) (mi *ModelInfo) {
fa := new(FieldInfo) // pk fa := new(FieldInfo) // pk
f1 := new(FieldInfo) // m1 table RelForeignKey f1 := new(FieldInfo) // m1 table RelForeignKey
f2 := new(FieldInfo) // m2 table RelForeignKey f2 := new(FieldInfo) // m2 table RelForeignKey
fa.FieldType = orm.TypeBigIntegerField fa.FieldType = TypeBigIntegerField
fa.Auto = true fa.Auto = true
fa.Pk = true fa.Pk = true
fa.DBcol = true fa.DBcol = true
@ -123,8 +121,8 @@ func NewM2MModelInfo(m1, m2 *ModelInfo) (mi *ModelInfo) {
f1.DBcol = true f1.DBcol = true
f2.DBcol = true f2.DBcol = true
f1.FieldType = orm.RelForeignKey f1.FieldType = RelForeignKey
f2.FieldType = orm.RelForeignKey f2.FieldType = RelForeignKey
f1.Name = CamelString(m1.Table) f1.Name = CamelString(m1.Table)
f2.Name = CamelString(m2.Table) f2.Name = CamelString(m2.Table)
f1.FullName = mi.FullName + "." + f1.Name f1.FullName = mi.FullName + "." + f1.Name

View File

@ -21,7 +21,7 @@ import (
"strings" "strings"
"time" "time"
"github.com/beego/beego/v2/client/orm" "github.com/beego/beego/v2/client/orm/internal/logs"
) )
// 1 is attr // 1 is attr
@ -145,11 +145,11 @@ func getColumnName(ft int, addrField reflect.Value, sf reflect.StructField, col
column = NameStrategyMap[NameStrategy](sf.Name) column = NameStrategyMap[NameStrategy](sf.Name)
} }
switch ft { switch ft {
case orm.RelForeignKey, orm.RelOneToOne: case RelForeignKey, RelOneToOne:
if len(col) == 0 { if len(col) == 0 {
column = column + "_id" column = column + "_id"
} }
case orm.RelManyToMany, orm.RelReverseMany, orm.RelReverseOne: case RelManyToMany, RelReverseMany, RelReverseOne:
column = sf.Name column = sf.Name
} }
return column return column
@ -159,76 +159,76 @@ func getColumnName(ft int, addrField reflect.Value, sf reflect.StructField, col
func getFieldType(val reflect.Value) (ft int, err error) { func getFieldType(val reflect.Value) (ft int, err error) {
switch val.Type() { switch val.Type() {
case reflect.TypeOf(new(int8)): case reflect.TypeOf(new(int8)):
ft = orm.TypeBitField ft = TypeBitField
case reflect.TypeOf(new(int16)): case reflect.TypeOf(new(int16)):
ft = orm.TypeSmallIntegerField ft = TypeSmallIntegerField
case reflect.TypeOf(new(int32)), case reflect.TypeOf(new(int32)),
reflect.TypeOf(new(int)): reflect.TypeOf(new(int)):
ft = orm.TypeIntegerField ft = TypeIntegerField
case reflect.TypeOf(new(int64)): case reflect.TypeOf(new(int64)):
ft = orm.TypeBigIntegerField ft = TypeBigIntegerField
case reflect.TypeOf(new(uint8)): case reflect.TypeOf(new(uint8)):
ft = orm.TypePositiveBitField ft = TypePositiveBitField
case reflect.TypeOf(new(uint16)): case reflect.TypeOf(new(uint16)):
ft = orm.TypePositiveSmallIntegerField ft = TypePositiveSmallIntegerField
case reflect.TypeOf(new(uint32)), case reflect.TypeOf(new(uint32)),
reflect.TypeOf(new(uint)): reflect.TypeOf(new(uint)):
ft = orm.TypePositiveIntegerField ft = TypePositiveIntegerField
case reflect.TypeOf(new(uint64)): case reflect.TypeOf(new(uint64)):
ft = orm.TypePositiveBigIntegerField ft = TypePositiveBigIntegerField
case reflect.TypeOf(new(float32)), case reflect.TypeOf(new(float32)),
reflect.TypeOf(new(float64)): reflect.TypeOf(new(float64)):
ft = orm.TypeFloatField ft = TypeFloatField
case reflect.TypeOf(new(bool)): case reflect.TypeOf(new(bool)):
ft = orm.TypeBooleanField ft = TypeBooleanField
case reflect.TypeOf(new(string)): case reflect.TypeOf(new(string)):
ft = orm.TypeVarCharField ft = TypeVarCharField
case reflect.TypeOf(new(time.Time)): case reflect.TypeOf(new(time.Time)):
ft = orm.TypeDateTimeField ft = TypeDateTimeField
default: default:
elm := reflect.Indirect(val) elm := reflect.Indirect(val)
switch elm.Kind() { switch elm.Kind() {
case reflect.Int8: case reflect.Int8:
ft = orm.TypeBitField ft = TypeBitField
case reflect.Int16: case reflect.Int16:
ft = orm.TypeSmallIntegerField ft = TypeSmallIntegerField
case reflect.Int32, reflect.Int: case reflect.Int32, reflect.Int:
ft = orm.TypeIntegerField ft = TypeIntegerField
case reflect.Int64: case reflect.Int64:
ft = orm.TypeBigIntegerField ft = TypeBigIntegerField
case reflect.Uint8: case reflect.Uint8:
ft = orm.TypePositiveBitField ft = TypePositiveBitField
case reflect.Uint16: case reflect.Uint16:
ft = orm.TypePositiveSmallIntegerField ft = TypePositiveSmallIntegerField
case reflect.Uint32, reflect.Uint: case reflect.Uint32, reflect.Uint:
ft = orm.TypePositiveIntegerField ft = TypePositiveIntegerField
case reflect.Uint64: case reflect.Uint64:
ft = orm.TypePositiveBigIntegerField ft = TypePositiveBigIntegerField
case reflect.Float32, reflect.Float64: case reflect.Float32, reflect.Float64:
ft = orm.TypeFloatField ft = TypeFloatField
case reflect.Bool: case reflect.Bool:
ft = orm.TypeBooleanField ft = TypeBooleanField
case reflect.String: case reflect.String:
ft = orm.TypeVarCharField ft = TypeVarCharField
default: default:
if elm.Interface() == nil { if elm.Interface() == nil {
panic(fmt.Errorf("%s is nil pointer, may be miss setting tag", val)) panic(fmt.Errorf("%s is nil pointer, may be miss setting tag", val))
} }
switch elm.Interface().(type) { switch elm.Interface().(type) {
case sql.NullInt64: case sql.NullInt64:
ft = orm.TypeBigIntegerField ft = TypeBigIntegerField
case sql.NullFloat64: case sql.NullFloat64:
ft = orm.TypeFloatField ft = TypeFloatField
case sql.NullBool: case sql.NullBool:
ft = orm.TypeBooleanField ft = TypeBooleanField
case sql.NullString: case sql.NullString:
ft = orm.TypeVarCharField ft = TypeVarCharField
case time.Time: case time.Time:
ft = orm.TypeDateTimeField ft = TypeDateTimeField
} }
} }
} }
if ft&orm.IsFieldType == 0 { if ft&IsFieldType == 0 {
err = fmt.Errorf("unsupport field type %s, may be miss setting tag", val) err = fmt.Errorf("unsupport field type %s, may be miss setting tag", val)
} }
return return
@ -252,7 +252,7 @@ func ParseStructTag(data string) (attrs map[string]bool, tags map[string]string)
tags[name] = v tags[name] = v
} }
} else { } else {
orm.DebugLog.Println("unsupport orm tag", v) logs.DebugLog.Println("unsupport orm tag", v)
} }
} }
return return

View File

@ -0,0 +1,23 @@
// Copyright 2023 beego-dev. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package models
// Fielder define field info
type Fielder interface {
String() string
FieldType() int
SetRaw(interface{}) error
RawValue() interface{}
}

View File

@ -0,0 +1,249 @@
// Copyright 2014 beego Author. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package utils
import (
"fmt"
"math/big"
"reflect"
"strconv"
"time"
)
// StrTo is the target string
type StrTo string
// Set string
func (f *StrTo) Set(v string) {
if v != "" {
*f = StrTo(v)
} else {
f.Clear()
}
}
// Clear string
func (f *StrTo) Clear() {
*f = StrTo(rune(0x1E))
}
// Exist check string exist
func (f StrTo) Exist() bool {
return string(f) != string(rune(0x1E))
}
// Bool string to bool
func (f StrTo) Bool() (bool, error) {
return strconv.ParseBool(f.String())
}
// Float32 string to float32
func (f StrTo) Float32() (float32, error) {
v, err := strconv.ParseFloat(f.String(), 32)
return float32(v), err
}
// Float64 string to float64
func (f StrTo) Float64() (float64, error) {
return strconv.ParseFloat(f.String(), 64)
}
// Int string to int
func (f StrTo) Int() (int, error) {
v, err := strconv.ParseInt(f.String(), 10, 32)
return int(v), err
}
// Int8 string to int8
func (f StrTo) Int8() (int8, error) {
v, err := strconv.ParseInt(f.String(), 10, 8)
return int8(v), err
}
// Int16 string to int16
func (f StrTo) Int16() (int16, error) {
v, err := strconv.ParseInt(f.String(), 10, 16)
return int16(v), err
}
// Int32 string to int32
func (f StrTo) Int32() (int32, error) {
v, err := strconv.ParseInt(f.String(), 10, 32)
return int32(v), err
}
// Int64 string to int64
func (f StrTo) Int64() (int64, error) {
v, err := strconv.ParseInt(f.String(), 10, 64)
if err != nil {
i := new(big.Int)
ni, ok := i.SetString(f.String(), 10) // octal
if !ok {
return v, err
}
return ni.Int64(), nil
}
return v, err
}
// Uint string to uint
func (f StrTo) Uint() (uint, error) {
v, err := strconv.ParseUint(f.String(), 10, 32)
return uint(v), err
}
// Uint8 string to uint8
func (f StrTo) Uint8() (uint8, error) {
v, err := strconv.ParseUint(f.String(), 10, 8)
return uint8(v), err
}
// Uint16 string to uint16
func (f StrTo) Uint16() (uint16, error) {
v, err := strconv.ParseUint(f.String(), 10, 16)
return uint16(v), err
}
// Uint32 string to uint32
func (f StrTo) Uint32() (uint32, error) {
v, err := strconv.ParseUint(f.String(), 10, 32)
return uint32(v), err
}
// Uint64 string to uint64
func (f StrTo) Uint64() (uint64, error) {
v, err := strconv.ParseUint(f.String(), 10, 64)
if err != nil {
i := new(big.Int)
ni, ok := i.SetString(f.String(), 10)
if !ok {
return v, err
}
return ni.Uint64(), nil
}
return v, err
}
// String string to string
func (f StrTo) String() string {
if f.Exist() {
return string(f)
}
return ""
}
// ToStr interface to string
func ToStr(value interface{}, args ...int) (s string) {
switch v := value.(type) {
case bool:
s = strconv.FormatBool(v)
case float32:
s = strconv.FormatFloat(float64(v), 'f', ArgInt(args).Get(0, -1), ArgInt(args).Get(1, 32))
case float64:
s = strconv.FormatFloat(v, 'f', ArgInt(args).Get(0, -1), ArgInt(args).Get(1, 64))
case int:
s = strconv.FormatInt(int64(v), ArgInt(args).Get(0, 10))
case int8:
s = strconv.FormatInt(int64(v), ArgInt(args).Get(0, 10))
case int16:
s = strconv.FormatInt(int64(v), ArgInt(args).Get(0, 10))
case int32:
s = strconv.FormatInt(int64(v), ArgInt(args).Get(0, 10))
case int64:
s = strconv.FormatInt(v, ArgInt(args).Get(0, 10))
case uint:
s = strconv.FormatUint(uint64(v), ArgInt(args).Get(0, 10))
case uint8:
s = strconv.FormatUint(uint64(v), ArgInt(args).Get(0, 10))
case uint16:
s = strconv.FormatUint(uint64(v), ArgInt(args).Get(0, 10))
case uint32:
s = strconv.FormatUint(uint64(v), ArgInt(args).Get(0, 10))
case uint64:
s = strconv.FormatUint(v, ArgInt(args).Get(0, 10))
case string:
s = v
case []byte:
s = string(v)
default:
s = fmt.Sprintf("%v", v)
}
return s
}
// ToInt64 interface to int64
func ToInt64(value interface{}) (d int64) {
val := reflect.ValueOf(value)
switch value.(type) {
case int, int8, int16, int32, int64:
d = val.Int()
case uint, uint8, uint16, uint32, uint64:
d = int64(val.Uint())
default:
panic(fmt.Errorf("ToInt64 need numeric not `%T`", value))
}
return
}
type ArgString []string
// Get get string by index from string slice
func (a ArgString) Get(i int, args ...string) (r string) {
if i >= 0 && i < len(a) {
r = a[i]
} else if len(args) > 0 {
r = args[0]
}
return
}
type ArgInt []int
// Get get int by index from int slice
func (a ArgInt) Get(i int, args ...int) (r int) {
if i >= 0 && i < len(a) {
r = a[i]
}
if len(args) > 0 {
r = args[0]
}
return
}
// TimeParse parse time to string with location
func TimeParse(dateString, format string) (time.Time, error) {
tp, err := time.ParseInLocation(format, dateString, DefaultTimeLoc)
return tp, err
}
// IndirectType get pointer indirect type
func IndirectType(v reflect.Type) reflect.Type {
switch v.Kind() {
case reflect.Ptr:
return IndirectType(v.Elem())
default:
return v
}
}
const (
FormatTime = "15:04:05"
FormatDate = "2006-01-02"
FormatDateTime = "2006-01-02 15:04:05"
)
var (
DefaultTimeLoc = time.Local
)

View File

@ -15,91 +15,47 @@
package orm package orm
import ( import (
"fmt" "github.com/beego/beego/v2/client/orm/internal/models"
"strconv"
"time"
) )
// Define the Type enum // Define the Type enum
const ( const (
TypeBooleanField = 1 << iota TypeBooleanField = models.TypeBooleanField
TypeVarCharField TypeVarCharField = models.TypeVarCharField
TypeCharField TypeCharField = models.TypeCharField
TypeTextField TypeTextField = models.TypeTextField
TypeTimeField TypeTimeField = models.TypeTimeField
TypeDateField TypeDateField = models.TypeDateField
TypeDateTimeField TypeDateTimeField = models.TypeDateTimeField
TypeBitField TypeBitField = models.TypeBitField
TypeSmallIntegerField TypeSmallIntegerField = models.TypeSmallIntegerField
TypeIntegerField TypeIntegerField = models.TypeIntegerField
TypeBigIntegerField TypeBigIntegerField = models.TypeBigIntegerField
TypePositiveBitField TypePositiveBitField = models.TypePositiveBitField
TypePositiveSmallIntegerField TypePositiveSmallIntegerField = models.TypePositiveSmallIntegerField
TypePositiveIntegerField TypePositiveIntegerField = models.TypePositiveIntegerField
TypePositiveBigIntegerField TypePositiveBigIntegerField = models.TypePositiveBigIntegerField
TypeFloatField TypeFloatField = models.TypeFloatField
TypeDecimalField TypeDecimalField = models.TypeDecimalField
TypeJSONField TypeJSONField = models.TypeJSONField
TypeJsonbField TypeJsonbField = models.TypeJsonbField
RelForeignKey RelForeignKey = models.RelForeignKey
RelOneToOne RelOneToOne = models.RelOneToOne
RelManyToMany RelManyToMany = models.RelManyToMany
RelReverseOne RelReverseOne = models.RelReverseOne
RelReverseMany RelReverseMany = models.RelReverseMany
) )
// Define some logic enum // Define some logic enum
const ( const (
IsIntegerField = ^-TypePositiveBigIntegerField >> 6 << 7 IsIntegerField = models.IsIntegerField
IsPositiveIntegerField = ^-TypePositiveBigIntegerField >> 10 << 11 IsPositiveIntegerField = models.IsPositiveIntegerField
IsRelField = ^-RelReverseMany >> 18 << 19 IsRelField = models.IsRelField
IsFieldType = ^-RelReverseMany<<1 + 1 IsFieldType = models.IsFieldType
) )
// BooleanField A true/false field. // BooleanField A true/false field.
type BooleanField bool type BooleanField = models.BooleanField
// Value return the BooleanField
func (e BooleanField) Value() bool {
return bool(e)
}
// Set will set the BooleanField
func (e *BooleanField) Set(d bool) {
*e = BooleanField(d)
}
// String format the Bool to string
func (e *BooleanField) String() string {
return strconv.FormatBool(e.Value())
}
// FieldType return BooleanField the type
func (e *BooleanField) FieldType() int {
return TypeBooleanField
}
// SetRaw set the interface to bool
func (e *BooleanField) SetRaw(value interface{}) error {
switch d := value.(type) {
case bool:
e.Set(d)
case string:
v, err := StrTo(d).Bool()
if err == nil {
e.Set(v)
}
return err
default:
return fmt.Errorf("<BooleanField.SetRaw> unknown value `%s`", value)
}
return nil
}
// RawValue return the current value
func (e *BooleanField) RawValue() interface{} {
return e.Value()
}
// verify the BooleanField implement the Fielder interface // verify the BooleanField implement the Fielder interface
var _ Fielder = new(BooleanField) var _ Fielder = new(BooleanField)
@ -108,43 +64,7 @@ var _ Fielder = new(BooleanField)
// required values tag: size // required values tag: size
// The size is enforced at the database level and in modelss validation. // The size is enforced at the database level and in modelss validation.
// eg: `orm:"size(120)"` // eg: `orm:"size(120)"`
type CharField string type CharField = models.CharField
// Value return the CharField's Value
func (e CharField) Value() string {
return string(e)
}
// Set CharField value
func (e *CharField) Set(d string) {
*e = CharField(d)
}
// String return the CharField
func (e *CharField) String() string {
return e.Value()
}
// FieldType return the enum type
func (e *CharField) FieldType() int {
return TypeVarCharField
}
// SetRaw set the interface to string
func (e *CharField) SetRaw(value interface{}) error {
switch d := value.(type) {
case string:
e.Set(d)
default:
return fmt.Errorf("<CharField.SetRaw> unknown value `%s`", value)
}
return nil
}
// RawValue return the CharField value
func (e *CharField) RawValue() interface{} {
return e.Value()
}
// verify CharField implement Fielder // verify CharField implement Fielder
var _ Fielder = new(CharField) var _ Fielder = new(CharField)
@ -162,49 +82,7 @@ var _ Fielder = new(CharField)
// Note that the current date is always used; its not just a default value that you can override. // Note that the current date is always used; its not just a default value that you can override.
// //
// eg: `orm:"auto_now"` or `orm:"auto_now_add"` // eg: `orm:"auto_now"` or `orm:"auto_now_add"`
type TimeField time.Time type TimeField = models.TimeField
// Value return the time.Time
func (e TimeField) Value() time.Time {
return time.Time(e)
}
// Set set the TimeField's value
func (e *TimeField) Set(d time.Time) {
*e = TimeField(d)
}
// String convert time to string
func (e *TimeField) String() string {
return e.Value().String()
}
// FieldType return enum type Date
func (e *TimeField) FieldType() int {
return TypeDateField
}
// SetRaw convert the interface to time.Time. Allow string and time.Time
func (e *TimeField) SetRaw(value interface{}) error {
switch d := value.(type) {
case time.Time:
e.Set(d)
case string:
v, err := timeParse(d, formatTime)
if err == nil {
e.Set(v)
}
return err
default:
return fmt.Errorf("<TimeField.SetRaw> unknown value `%s`", value)
}
return nil
}
// RawValue return time value
func (e *TimeField) RawValue() interface{} {
return e.Value()
}
var _ Fielder = new(TimeField) var _ Fielder = new(TimeField)
@ -221,49 +99,7 @@ var _ Fielder = new(TimeField)
// Note that the current date is always used; its not just a default value that you can override. // Note that the current date is always used; its not just a default value that you can override.
// //
// eg: `orm:"auto_now"` or `orm:"auto_now_add"` // eg: `orm:"auto_now"` or `orm:"auto_now_add"`
type DateField time.Time type DateField = models.DateField
// Value return the time.Time
func (e DateField) Value() time.Time {
return time.Time(e)
}
// Set set the DateField's value
func (e *DateField) Set(d time.Time) {
*e = DateField(d)
}
// String convert datetime to string
func (e *DateField) String() string {
return e.Value().String()
}
// FieldType return enum type Date
func (e *DateField) FieldType() int {
return TypeDateField
}
// SetRaw convert the interface to time.Time. Allow string and time.Time
func (e *DateField) SetRaw(value interface{}) error {
switch d := value.(type) {
case time.Time:
e.Set(d)
case string:
v, err := timeParse(d, formatDate)
if err == nil {
e.Set(v)
}
return err
default:
return fmt.Errorf("<DateField.SetRaw> unknown value `%s`", value)
}
return nil
}
// RawValue return Date value
func (e *DateField) RawValue() interface{} {
return e.Value()
}
// verify DateField implement fielder interface // verify DateField implement fielder interface
var _ Fielder = new(DateField) var _ Fielder = new(DateField)
@ -271,513 +107,67 @@ var _ Fielder = new(DateField)
// DateTimeField A date, represented in go by a time.Time instance. // DateTimeField A date, represented in go by a time.Time instance.
// datetime values like 2006-01-02 15:04:05 // datetime values like 2006-01-02 15:04:05
// Takes the same extra arguments as DateField. // Takes the same extra arguments as DateField.
type DateTimeField time.Time type DateTimeField = models.DateTimeField
// Value return the datetime value
func (e DateTimeField) Value() time.Time {
return time.Time(e)
}
// Set set the time.Time to datetime
func (e *DateTimeField) Set(d time.Time) {
*e = DateTimeField(d)
}
// String return the time's String
func (e *DateTimeField) String() string {
return e.Value().String()
}
// FieldType return the enum TypeDateTimeField
func (e *DateTimeField) FieldType() int {
return TypeDateTimeField
}
// SetRaw convert the string or time.Time to DateTimeField
func (e *DateTimeField) SetRaw(value interface{}) error {
switch d := value.(type) {
case time.Time:
e.Set(d)
case string:
v, err := timeParse(d, formatDateTime)
if err == nil {
e.Set(v)
}
return err
default:
return fmt.Errorf("<DateTimeField.SetRaw> unknown value `%s`", value)
}
return nil
}
// RawValue return the datetime value
func (e *DateTimeField) RawValue() interface{} {
return e.Value()
}
// verify datetime implement fielder // verify datetime implement fielder
var _ Fielder = new(DateTimeField) var _ models.Fielder = new(DateTimeField)
// FloatField A floating-point number represented in go by a float32 value. // FloatField A floating-point number represented in go by a float32 value.
type FloatField float64 type FloatField = models.FloatField
// Value return the FloatField value
func (e FloatField) Value() float64 {
return float64(e)
}
// Set the Float64
func (e *FloatField) Set(d float64) {
*e = FloatField(d)
}
// String return the string
func (e *FloatField) String() string {
return ToStr(e.Value(), -1, 32)
}
// FieldType return the enum type
func (e *FloatField) FieldType() int {
return TypeFloatField
}
// SetRaw converter interface Float64 float32 or string to FloatField
func (e *FloatField) SetRaw(value interface{}) error {
switch d := value.(type) {
case float32:
e.Set(float64(d))
case float64:
e.Set(d)
case string:
v, err := StrTo(d).Float64()
if err == nil {
e.Set(v)
}
return err
default:
return fmt.Errorf("<FloatField.SetRaw> unknown value `%s`", value)
}
return nil
}
// RawValue return the FloatField value
func (e *FloatField) RawValue() interface{} {
return e.Value()
}
// verify FloatField implement Fielder // verify FloatField implement Fielder
var _ Fielder = new(FloatField) var _ Fielder = new(FloatField)
// SmallIntegerField -32768 to 32767 // SmallIntegerField -32768 to 32767
type SmallIntegerField int16 type SmallIntegerField = models.SmallIntegerField
// Value return int16 value
func (e SmallIntegerField) Value() int16 {
return int16(e)
}
// Set the SmallIntegerField value
func (e *SmallIntegerField) Set(d int16) {
*e = SmallIntegerField(d)
}
// String convert smallint to string
func (e *SmallIntegerField) String() string {
return ToStr(e.Value())
}
// FieldType return enum type SmallIntegerField
func (e *SmallIntegerField) FieldType() int {
return TypeSmallIntegerField
}
// SetRaw convert interface int16/string to int16
func (e *SmallIntegerField) SetRaw(value interface{}) error {
switch d := value.(type) {
case int16:
e.Set(d)
case string:
v, err := StrTo(d).Int16()
if err == nil {
e.Set(v)
}
return err
default:
return fmt.Errorf("<SmallIntegerField.SetRaw> unknown value `%s`", value)
}
return nil
}
// RawValue return smallint value
func (e *SmallIntegerField) RawValue() interface{} {
return e.Value()
}
// verify SmallIntegerField implement Fielder // verify SmallIntegerField implement Fielder
var _ Fielder = new(SmallIntegerField) var _ Fielder = new(SmallIntegerField)
// IntegerField -2147483648 to 2147483647 // IntegerField -2147483648 to 2147483647
type IntegerField int32 type IntegerField = models.IntegerField
// Value return the int32
func (e IntegerField) Value() int32 {
return int32(e)
}
// Set IntegerField value
func (e *IntegerField) Set(d int32) {
*e = IntegerField(d)
}
// String convert Int32 to string
func (e *IntegerField) String() string {
return ToStr(e.Value())
}
// FieldType return the enum type
func (e *IntegerField) FieldType() int {
return TypeIntegerField
}
// SetRaw convert interface int32/string to int32
func (e *IntegerField) SetRaw(value interface{}) error {
switch d := value.(type) {
case int32:
e.Set(d)
case string:
v, err := StrTo(d).Int32()
if err == nil {
e.Set(v)
}
return err
default:
return fmt.Errorf("<IntegerField.SetRaw> unknown value `%s`", value)
}
return nil
}
// RawValue return IntegerField value
func (e *IntegerField) RawValue() interface{} {
return e.Value()
}
// verify IntegerField implement Fielder // verify IntegerField implement Fielder
var _ Fielder = new(IntegerField) var _ Fielder = new(IntegerField)
// BigIntegerField -9223372036854775808 to 9223372036854775807. // BigIntegerField -9223372036854775808 to 9223372036854775807.
type BigIntegerField int64 type BigIntegerField = models.BigIntegerField
// Value return int64
func (e BigIntegerField) Value() int64 {
return int64(e)
}
// Set the BigIntegerField value
func (e *BigIntegerField) Set(d int64) {
*e = BigIntegerField(d)
}
// String convert BigIntegerField to string
func (e *BigIntegerField) String() string {
return ToStr(e.Value())
}
// FieldType return enum type
func (e *BigIntegerField) FieldType() int {
return TypeBigIntegerField
}
// SetRaw convert interface int64/string to int64
func (e *BigIntegerField) SetRaw(value interface{}) error {
switch d := value.(type) {
case int64:
e.Set(d)
case string:
v, err := StrTo(d).Int64()
if err == nil {
e.Set(v)
}
return err
default:
return fmt.Errorf("<BigIntegerField.SetRaw> unknown value `%s`", value)
}
return nil
}
// RawValue return BigIntegerField value
func (e *BigIntegerField) RawValue() interface{} {
return e.Value()
}
// verify BigIntegerField implement Fielder // verify BigIntegerField implement Fielder
var _ Fielder = new(BigIntegerField) var _ Fielder = new(BigIntegerField)
// PositiveSmallIntegerField 0 to 65535 // PositiveSmallIntegerField 0 to 65535
type PositiveSmallIntegerField uint16 type PositiveSmallIntegerField = models.PositiveSmallIntegerField
// Value return uint16
func (e PositiveSmallIntegerField) Value() uint16 {
return uint16(e)
}
// Set PositiveSmallIntegerField value
func (e *PositiveSmallIntegerField) Set(d uint16) {
*e = PositiveSmallIntegerField(d)
}
// String convert uint16 to string
func (e *PositiveSmallIntegerField) String() string {
return ToStr(e.Value())
}
// FieldType return enum type
func (e *PositiveSmallIntegerField) FieldType() int {
return TypePositiveSmallIntegerField
}
// SetRaw convert Interface uint16/string to uint16
func (e *PositiveSmallIntegerField) SetRaw(value interface{}) error {
switch d := value.(type) {
case uint16:
e.Set(d)
case string:
v, err := StrTo(d).Uint16()
if err == nil {
e.Set(v)
}
return err
default:
return fmt.Errorf("<PositiveSmallIntegerField.SetRaw> unknown value `%s`", value)
}
return nil
}
// RawValue returns PositiveSmallIntegerField value
func (e *PositiveSmallIntegerField) RawValue() interface{} {
return e.Value()
}
// verify PositiveSmallIntegerField implement Fielder // verify PositiveSmallIntegerField implement Fielder
var _ Fielder = new(PositiveSmallIntegerField) var _ Fielder = new(PositiveSmallIntegerField)
// PositiveIntegerField 0 to 4294967295 // PositiveIntegerField 0 to 4294967295
type PositiveIntegerField uint32 type PositiveIntegerField = models.PositiveIntegerField
// Value return PositiveIntegerField value. Uint32
func (e PositiveIntegerField) Value() uint32 {
return uint32(e)
}
// Set the PositiveIntegerField value
func (e *PositiveIntegerField) Set(d uint32) {
*e = PositiveIntegerField(d)
}
// String convert PositiveIntegerField to string
func (e *PositiveIntegerField) String() string {
return ToStr(e.Value())
}
// FieldType return enum type
func (e *PositiveIntegerField) FieldType() int {
return TypePositiveIntegerField
}
// SetRaw convert interface uint32/string to Uint32
func (e *PositiveIntegerField) SetRaw(value interface{}) error {
switch d := value.(type) {
case uint32:
e.Set(d)
case string:
v, err := StrTo(d).Uint32()
if err == nil {
e.Set(v)
}
return err
default:
return fmt.Errorf("<PositiveIntegerField.SetRaw> unknown value `%s`", value)
}
return nil
}
// RawValue return the PositiveIntegerField Value
func (e *PositiveIntegerField) RawValue() interface{} {
return e.Value()
}
// verify PositiveIntegerField implement Fielder // verify PositiveIntegerField implement Fielder
var _ Fielder = new(PositiveIntegerField) var _ Fielder = new(PositiveIntegerField)
// PositiveBigIntegerField 0 to 18446744073709551615 // PositiveBigIntegerField 0 to 18446744073709551615
type PositiveBigIntegerField uint64 type PositiveBigIntegerField = models.PositiveBigIntegerField
// Value return uint64
func (e PositiveBigIntegerField) Value() uint64 {
return uint64(e)
}
// Set PositiveBigIntegerField value
func (e *PositiveBigIntegerField) Set(d uint64) {
*e = PositiveBigIntegerField(d)
}
// String convert PositiveBigIntegerField to string
func (e *PositiveBigIntegerField) String() string {
return ToStr(e.Value())
}
// FieldType return enum type
func (e *PositiveBigIntegerField) FieldType() int {
return TypePositiveIntegerField
}
// SetRaw convert interface uint64/string to Uint64
func (e *PositiveBigIntegerField) SetRaw(value interface{}) error {
switch d := value.(type) {
case uint64:
e.Set(d)
case string:
v, err := StrTo(d).Uint64()
if err == nil {
e.Set(v)
}
return err
default:
return fmt.Errorf("<PositiveBigIntegerField.SetRaw> unknown value `%s`", value)
}
return nil
}
// RawValue return PositiveBigIntegerField value
func (e *PositiveBigIntegerField) RawValue() interface{} {
return e.Value()
}
// verify PositiveBigIntegerField implement Fielder // verify PositiveBigIntegerField implement Fielder
var _ Fielder = new(PositiveBigIntegerField) var _ Fielder = new(PositiveBigIntegerField)
// TextField A large text field. // TextField A large text field.
type TextField string type TextField = models.TextField
// Value return TextField value
func (e TextField) Value() string {
return string(e)
}
// Set the TextField value
func (e *TextField) Set(d string) {
*e = TextField(d)
}
// String convert TextField to string
func (e *TextField) String() string {
return e.Value()
}
// FieldType return enum type
func (e *TextField) FieldType() int {
return TypeTextField
}
// SetRaw convert interface string to string
func (e *TextField) SetRaw(value interface{}) error {
switch d := value.(type) {
case string:
e.Set(d)
default:
return fmt.Errorf("<TextField.SetRaw> unknown value `%s`", value)
}
return nil
}
// RawValue return TextField value
func (e *TextField) RawValue() interface{} {
return e.Value()
}
// verify TextField implement Fielder // verify TextField implement Fielder
var _ Fielder = new(TextField) var _ Fielder = new(TextField)
// JSONField postgres json field. // JSONField postgres json field.
type JSONField string type JSONField = models.JSONField
// Value return JSONField value
func (j JSONField) Value() string {
return string(j)
}
// Set the JSONField value
func (j *JSONField) Set(d string) {
*j = JSONField(d)
}
// String convert JSONField to string
func (j *JSONField) String() string {
return j.Value()
}
// FieldType return enum type
func (j *JSONField) FieldType() int {
return TypeJSONField
}
// SetRaw convert interface string to string
func (j *JSONField) SetRaw(value interface{}) error {
switch d := value.(type) {
case string:
j.Set(d)
default:
return fmt.Errorf("<JSONField.SetRaw> unknown value `%s`", value)
}
return nil
}
// RawValue return JSONField value
func (j *JSONField) RawValue() interface{} {
return j.Value()
}
// verify JSONField implement Fielder // verify JSONField implement Fielder
var _ Fielder = new(JSONField) var _ models.Fielder = new(JSONField)
// JsonbField postgres json field. // JsonbField postgres json field.
type JsonbField string type JsonbField = models.JsonbField
// Value return JsonbField value
func (j JsonbField) Value() string {
return string(j)
}
// Set the JsonbField value
func (j *JsonbField) Set(d string) {
*j = JsonbField(d)
}
// String convert JsonbField to string
func (j *JsonbField) String() string {
return j.Value()
}
// FieldType return enum type
func (j *JsonbField) FieldType() int {
return TypeJsonbField
}
// SetRaw convert interface string to string
func (j *JsonbField) SetRaw(value interface{}) error {
switch d := value.(type) {
case string:
j.Set(d)
default:
return fmt.Errorf("<JsonbField.SetRaw> unknown value `%s`", value)
}
return nil
}
// RawValue return JsonbField value
func (j *JsonbField) RawValue() interface{} {
return j.Value()
}
// verify JsonbField implement Fielder // verify JsonbField implement Fielder
var _ Fielder = new(JsonbField) var _ models.Fielder = new(JsonbField)

View File

@ -22,6 +22,8 @@ import (
"strings" "strings"
"time" "time"
"github.com/beego/beego/v2/client/orm/internal/models"
_ "github.com/go-sql-driver/mysql" _ "github.com/go-sql-driver/mysql"
_ "github.com/lib/pq" _ "github.com/lib/pq"
_ "github.com/mattn/go-sqlite3" _ "github.com/mattn/go-sqlite3"
@ -79,7 +81,7 @@ func (e *SliceStringField) RawValue() interface{} {
return e.String() return e.String()
} }
var _ Fielder = new(SliceStringField) var _ models.Fielder = new(SliceStringField)
// A json field. // A json field.
type JSONFieldTest struct { type JSONFieldTest struct {
@ -111,7 +113,7 @@ func (e *JSONFieldTest) RawValue() interface{} {
return e.String() return e.String()
} }
var _ Fielder = new(JSONFieldTest) var _ models.Fielder = new(JSONFieldTest)
type Data struct { type Data struct {
ID int `orm:"column(id)"` ID int `orm:"column(id)"`

View File

@ -54,9 +54,10 @@ import (
"database/sql" "database/sql"
"errors" "errors"
"fmt" "fmt"
"os"
"reflect" "reflect"
"time"
ilogs "github.com/beego/beego/v2/client/orm/internal/logs"
iutils "github.com/beego/beego/v2/client/orm/internal/utils"
"github.com/beego/beego/v2/client/orm/internal/models" "github.com/beego/beego/v2/client/orm/internal/models"
@ -74,10 +75,10 @@ const (
// Define common vars // Define common vars
var ( var (
Debug = false Debug = false
DebugLog = NewLog(os.Stdout) DebugLog = ilogs.DebugLog
DefaultRowsLimit = -1 DefaultRowsLimit = -1
DefaultRelsDepth = 2 DefaultRelsDepth = 2
DefaultTimeLoc = time.Local DefaultTimeLoc = iutils.DefaultTimeLoc
ErrTxDone = errors.New("<TxOrmer.Commit/Rollback> transaction already done") ErrTxDone = errors.New("<TxOrmer.Commit/Rollback> transaction already done")
ErrMultiRows = errors.New("<QuerySeter> return multi rows") ErrMultiRows = errors.New("<QuerySeter> return multi rows")
ErrNoRows = errors.New("<QuerySeter> no row found") ErrNoRows = errors.New("<QuerySeter> no row found")
@ -479,7 +480,7 @@ func (o *ormBase) QueryTable(ptrStructOrTableName interface{}) (qs QuerySeter) {
qs = newQuerySet(o, mi) qs = newQuerySet(o, mi)
} }
} else { } else {
name = models.GetFullName(indirectType(reflect.TypeOf(ptrStructOrTableName))) name = models.GetFullName(iutils.IndirectType(reflect.TypeOf(ptrStructOrTableName)))
if mi, ok := defaultModelCache.getByFullName(name); ok { if mi, ok := defaultModelCache.getByFullName(name); ok {
qs = newQuerySet(o, mi) qs = newQuerySet(o, mi)
} }

View File

@ -22,23 +22,22 @@ import (
"log" "log"
"strings" "strings"
"time" "time"
"github.com/beego/beego/v2/client/orm/internal/logs"
) )
// Log implement the log.Logger type Log = logs.Log
type Log struct {
*log.Logger
}
// costomer log func
var LogFunc func(query map[string]interface{})
// NewLog set io.Writer to create a Logger. // NewLog set io.Writer to create a Logger.
func NewLog(out io.Writer) *Log { func NewLog(out io.Writer) *logs.Log {
d := new(Log) d := new(logs.Log)
d.Logger = log.New(out, "[ORM]", log.LstdFlags) d.Logger = log.New(out, "[ORM]", log.LstdFlags)
return d return d
} }
// LogFunc costomer log func
var LogFunc func(query map[string]interface{})
func debugLogQueies(alias *alias, operaton, query string, t time.Time, err error, args ...interface{}) { func debugLogQueies(alias *alias, operaton, query string, t time.Time, err error, args ...interface{}) {
logMap := make(map[string]interface{}) logMap := make(map[string]interface{})
sub := time.Since(t) / 1e5 sub := time.Since(t) / 1e5
@ -64,7 +63,7 @@ func debugLogQueies(alias *alias, operaton, query string, t time.Time, err error
if LogFunc != nil { if LogFunc != nil {
LogFunc(logMap) LogFunc(logMap)
} }
DebugLog.Println(con) logs.DebugLog.Println(con)
} }
// statement query logger struct. // statement query logger struct.

View File

@ -18,6 +18,8 @@ import (
"context" "context"
"fmt" "fmt"
"github.com/beego/beego/v2/client/orm/internal/utils"
"github.com/beego/beego/v2/client/orm/internal/models" "github.com/beego/beego/v2/client/orm/internal/models"
"github.com/beego/beego/v2/client/orm/clauses/order_clause" "github.com/beego/beego/v2/client/orm/clauses/order_clause"
@ -56,7 +58,7 @@ func ColValue(opt operator, value interface{}) interface{} {
default: default:
panic(fmt.Errorf("orm.ColValue wrong operator")) panic(fmt.Errorf("orm.ColValue wrong operator"))
} }
v, err := StrTo(ToStr(value)).Int64() v, err := utils.StrTo(utils.ToStr(value)).Int64()
if err != nil { if err != nil {
panic(fmt.Errorf("orm.ColValue doesn't support non string/numeric type, %s", err)) panic(fmt.Errorf("orm.ColValue doesn't support non string/numeric type, %s", err))
} }
@ -115,13 +117,13 @@ func (o querySet) Exclude(expr string, args ...interface{}) QuerySeter {
// set offset number // set offset number
func (o *querySet) setOffset(num interface{}) { func (o *querySet) setOffset(num interface{}) {
o.offset = ToInt64(num) o.offset = utils.ToInt64(num)
} }
// add LIMIT value. // add LIMIT value.
// args[0] means offset, e.g. LIMIT num,offset. // args[0] means offset, e.g. LIMIT num,offset.
func (o querySet) Limit(limit interface{}, args ...interface{}) QuerySeter { func (o querySet) Limit(limit interface{}, args ...interface{}) QuerySeter {
o.limit = ToInt64(limit) o.limit = utils.ToInt64(limit)
if len(args) > 0 { if len(args) > 0 {
o.setOffset(args[0]) o.setOffset(args[0])
} }

View File

@ -20,6 +20,8 @@ import (
"reflect" "reflect"
"time" "time"
"github.com/beego/beego/v2/client/orm/internal/utils"
"github.com/beego/beego/v2/client/orm/internal/models" "github.com/beego/beego/v2/client/orm/internal/models"
"github.com/pkg/errors" "github.com/pkg/errors"
@ -97,7 +99,7 @@ func (o *rawSet) setFieldValue(ind reflect.Value, value interface{}) {
} else if v, ok := value.(bool); ok { } else if v, ok := value.(bool); ok {
ind.SetBool(v) ind.SetBool(v)
} else { } else {
v, _ := StrTo(ToStr(value)).Bool() v, _ := utils.StrTo(utils.ToStr(value)).Bool()
ind.SetBool(v) ind.SetBool(v)
} }
@ -105,7 +107,7 @@ func (o *rawSet) setFieldValue(ind reflect.Value, value interface{}) {
if value == nil { if value == nil {
ind.SetString("") ind.SetString("")
} else { } else {
ind.SetString(ToStr(value)) ind.SetString(utils.ToStr(value))
} }
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
@ -119,7 +121,7 @@ func (o *rawSet) setFieldValue(ind reflect.Value, value interface{}) {
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
ind.SetInt(int64(val.Uint())) ind.SetInt(int64(val.Uint()))
default: default:
v, _ := StrTo(ToStr(value)).Int64() v, _ := utils.StrTo(utils.ToStr(value)).Int64()
ind.SetInt(v) ind.SetInt(v)
} }
} }
@ -134,7 +136,7 @@ func (o *rawSet) setFieldValue(ind reflect.Value, value interface{}) {
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
ind.SetUint(val.Uint()) ind.SetUint(val.Uint())
default: default:
v, _ := StrTo(ToStr(value)).Uint64() v, _ := utils.StrTo(utils.ToStr(value)).Uint64()
ind.SetUint(v) ind.SetUint(v)
} }
} }
@ -147,7 +149,7 @@ func (o *rawSet) setFieldValue(ind reflect.Value, value interface{}) {
case reflect.Float64: case reflect.Float64:
ind.SetFloat(val.Float()) ind.SetFloat(val.Float())
default: default:
v, _ := StrTo(ToStr(value)).Float64() v, _ := utils.StrTo(utils.ToStr(value)).Float64()
ind.SetFloat(v) ind.SetFloat(v)
} }
} }
@ -172,20 +174,20 @@ func (o *rawSet) setFieldValue(ind reflect.Value, value interface{}) {
if str != "" { if str != "" {
if len(str) >= 19 { if len(str) >= 19 {
str = str[:19] str = str[:19]
t, err := time.ParseInLocation(formatDateTime, str, o.orm.alias.TZ) t, err := time.ParseInLocation(utils.FormatDateTime, str, o.orm.alias.TZ)
if err == nil { if err == nil {
t = t.In(DefaultTimeLoc) t = t.In(DefaultTimeLoc)
ind.Set(reflect.ValueOf(t)) ind.Set(reflect.ValueOf(t))
} }
} else if len(str) >= 10 { } else if len(str) >= 10 {
str = str[:10] str = str[:10]
t, err := time.ParseInLocation(formatDate, str, DefaultTimeLoc) t, err := time.ParseInLocation(utils.FormatDate, str, DefaultTimeLoc)
if err == nil { if err == nil {
ind.Set(reflect.ValueOf(t)) ind.Set(reflect.ValueOf(t))
} }
} else if len(str) >= 8 { } else if len(str) >= 8 {
str = str[:8] str = str[:8]
t, err := time.ParseInLocation(formatTime, str, DefaultTimeLoc) t, err := time.ParseInLocation(utils.FormatTime, str, DefaultTimeLoc)
if err == nil { if err == nil {
ind.Set(reflect.ValueOf(t)) ind.Set(reflect.ValueOf(t))
} }
@ -381,7 +383,7 @@ func (o *rawSet) QueryRow(containers ...interface{}) error {
field = mf.Elem().FieldByIndex(fi.RelModelInfo.Fields.Pk.FieldIndex) field = mf.Elem().FieldByIndex(fi.RelModelInfo.Fields.Pk.FieldIndex)
} }
if fi.IsFielder { if fi.IsFielder {
fd := field.Addr().Interface().(Fielder) fd := field.Addr().Interface().(models.Fielder)
err := fd.SetRaw(value) err := fd.SetRaw(value)
if err != nil { if err != nil {
return errors.Errorf("set raw error:%s", err) return errors.Errorf("set raw error:%s", err)
@ -548,7 +550,7 @@ func (o *rawSet) QueryRows(containers ...interface{}) (int64, error) {
field = mf.Elem().FieldByIndex(fi.RelModelInfo.Fields.Pk.FieldIndex) field = mf.Elem().FieldByIndex(fi.RelModelInfo.Fields.Pk.FieldIndex)
} }
if fi.IsFielder { if fi.IsFielder {
fd := field.Addr().Interface().(Fielder) fd := field.Addr().Interface().(models.Fielder)
err := fd.SetRaw(value) err := fd.SetRaw(value)
if err != nil { if err != nil {
return 0, errors.Errorf("set raw error:%s", err) return 0, errors.Errorf("set raw error:%s", err)

View File

@ -29,6 +29,10 @@ import (
"testing" "testing"
"time" "time"
"github.com/beego/beego/v2/client/orm/internal/logs"
"github.com/beego/beego/v2/client/orm/internal/utils"
"github.com/beego/beego/v2/client/orm/internal/models" "github.com/beego/beego/v2/client/orm/internal/models"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -40,9 +44,9 @@ import (
var _ = os.PathSeparator var _ = os.PathSeparator
var ( var (
testDate = formatDate + " -0700" testDate = utils.FormatDate + " -0700"
testDateTime = formatDateTime + " -0700" testDateTime = utils.FormatDateTime + " -0700"
testTime = formatTime + " -0700" testTime = utils.FormatTime + " -0700"
) )
type argAny []interface{} type argAny []interface{}
@ -71,7 +75,7 @@ func ValuesCompare(is bool, a interface{}, args ...interface{}) (ok bool, err er
case time.Time: case time.Time:
if v2, vo := b.(time.Time); vo { if v2, vo := b.(time.Time); vo {
if arg.Get(1) != nil { if arg.Get(1) != nil {
format := ToStr(arg.Get(1)) format := utils.ToStr(arg.Get(1))
a = v.Format(format) a = v.Format(format)
b = v2.Format(format) b = v2.Format(format)
ok = a == b ok = a == b
@ -81,7 +85,7 @@ func ValuesCompare(is bool, a interface{}, args ...interface{}) (ok bool, err er
} }
} }
default: default:
ok = ToStr(a) == ToStr(b) ok = utils.ToStr(a) == utils.ToStr(b)
} }
ok = is && ok || !is && !ok ok = is && ok || !is && !ok
if !ok { if !ok {
@ -2933,9 +2937,9 @@ func TestDebugLog(t *testing.T) {
func captureDebugLogOutput(f func()) string { func captureDebugLogOutput(f func()) string {
var buf bytes.Buffer var buf bytes.Buffer
DebugLog.SetOutput(&buf) logs.DebugLog.SetOutput(&buf)
defer func() { defer func() {
DebugLog.SetOutput(os.Stderr) logs.DebugLog.SetOutput(os.Stderr)
}() }()
f() f()
return buf.String() return buf.String()

View File

@ -97,13 +97,7 @@ type Driver interface {
Type() DriverType Type() DriverType
} }
// Fielder define field info type Fielder = models.Fielder
type Fielder interface {
String() string
FieldType() int
SetRaw(interface{}) error
RawValue() interface{}
}
type TxBeginner interface { type TxBeginner interface {
// Begin self control transaction // Begin self control transaction

View File

@ -15,235 +15,15 @@
package orm package orm
import ( import (
"fmt"
"math/big"
"reflect"
"strconv"
"time"
"github.com/beego/beego/v2/client/orm/internal/models" "github.com/beego/beego/v2/client/orm/internal/models"
"github.com/beego/beego/v2/client/orm/internal/utils"
) )
// StrTo is the target string type StrTo = utils.StrTo
type StrTo string
// Set string
func (f *StrTo) Set(v string) {
if v != "" {
*f = StrTo(v)
} else {
f.Clear()
}
}
// Clear string
func (f *StrTo) Clear() {
*f = StrTo(rune(0x1E))
}
// Exist check string exist
func (f StrTo) Exist() bool {
return string(f) != string(rune(0x1E))
}
// Bool string to bool
func (f StrTo) Bool() (bool, error) {
return strconv.ParseBool(f.String())
}
// Float32 string to float32
func (f StrTo) Float32() (float32, error) {
v, err := strconv.ParseFloat(f.String(), 32)
return float32(v), err
}
// Float64 string to float64
func (f StrTo) Float64() (float64, error) {
return strconv.ParseFloat(f.String(), 64)
}
// Int string to int
func (f StrTo) Int() (int, error) {
v, err := strconv.ParseInt(f.String(), 10, 32)
return int(v), err
}
// Int8 string to int8
func (f StrTo) Int8() (int8, error) {
v, err := strconv.ParseInt(f.String(), 10, 8)
return int8(v), err
}
// Int16 string to int16
func (f StrTo) Int16() (int16, error) {
v, err := strconv.ParseInt(f.String(), 10, 16)
return int16(v), err
}
// Int32 string to int32
func (f StrTo) Int32() (int32, error) {
v, err := strconv.ParseInt(f.String(), 10, 32)
return int32(v), err
}
// Int64 string to int64
func (f StrTo) Int64() (int64, error) {
v, err := strconv.ParseInt(f.String(), 10, 64)
if err != nil {
i := new(big.Int)
ni, ok := i.SetString(f.String(), 10) // octal
if !ok {
return v, err
}
return ni.Int64(), nil
}
return v, err
}
// Uint string to uint
func (f StrTo) Uint() (uint, error) {
v, err := strconv.ParseUint(f.String(), 10, 32)
return uint(v), err
}
// Uint8 string to uint8
func (f StrTo) Uint8() (uint8, error) {
v, err := strconv.ParseUint(f.String(), 10, 8)
return uint8(v), err
}
// Uint16 string to uint16
func (f StrTo) Uint16() (uint16, error) {
v, err := strconv.ParseUint(f.String(), 10, 16)
return uint16(v), err
}
// Uint32 string to uint32
func (f StrTo) Uint32() (uint32, error) {
v, err := strconv.ParseUint(f.String(), 10, 32)
return uint32(v), err
}
// Uint64 string to uint64
func (f StrTo) Uint64() (uint64, error) {
v, err := strconv.ParseUint(f.String(), 10, 64)
if err != nil {
i := new(big.Int)
ni, ok := i.SetString(f.String(), 10)
if !ok {
return v, err
}
return ni.Uint64(), nil
}
return v, err
}
// String string to string
func (f StrTo) String() string {
if f.Exist() {
return string(f)
}
return ""
}
// ToStr interface to string
func ToStr(value interface{}, args ...int) (s string) {
switch v := value.(type) {
case bool:
s = strconv.FormatBool(v)
case float32:
s = strconv.FormatFloat(float64(v), 'f', argInt(args).Get(0, -1), argInt(args).Get(1, 32))
case float64:
s = strconv.FormatFloat(v, 'f', argInt(args).Get(0, -1), argInt(args).Get(1, 64))
case int:
s = strconv.FormatInt(int64(v), argInt(args).Get(0, 10))
case int8:
s = strconv.FormatInt(int64(v), argInt(args).Get(0, 10))
case int16:
s = strconv.FormatInt(int64(v), argInt(args).Get(0, 10))
case int32:
s = strconv.FormatInt(int64(v), argInt(args).Get(0, 10))
case int64:
s = strconv.FormatInt(v, argInt(args).Get(0, 10))
case uint:
s = strconv.FormatUint(uint64(v), argInt(args).Get(0, 10))
case uint8:
s = strconv.FormatUint(uint64(v), argInt(args).Get(0, 10))
case uint16:
s = strconv.FormatUint(uint64(v), argInt(args).Get(0, 10))
case uint32:
s = strconv.FormatUint(uint64(v), argInt(args).Get(0, 10))
case uint64:
s = strconv.FormatUint(v, argInt(args).Get(0, 10))
case string:
s = v
case []byte:
s = string(v)
default:
s = fmt.Sprintf("%v", v)
}
return s
}
// ToInt64 interface to int64
func ToInt64(value interface{}) (d int64) {
val := reflect.ValueOf(value)
switch value.(type) {
case int, int8, int16, int32, int64:
d = val.Int()
case uint, uint8, uint16, uint32, uint64:
d = int64(val.Uint())
default:
panic(fmt.Errorf("ToInt64 need numeric not `%T`", value))
}
return
}
// SetNameStrategy set different name strategy
func SetNameStrategy(s string) { func SetNameStrategy(s string) {
if models.SnakeAcronymNameStrategy != s { if models.SnakeAcronymNameStrategy != s {
models.NameStrategy = models.DefaultNameStrategy models.NameStrategy = models.DefaultNameStrategy
} }
models.NameStrategy = s models.NameStrategy = s
} }
type argString []string
// Get get string by index from string slice
func (a argString) Get(i int, args ...string) (r string) {
if i >= 0 && i < len(a) {
r = a[i]
} else if len(args) > 0 {
r = args[0]
}
return
}
type argInt []int
// get int by index from int slice
func (a argInt) Get(i int, args ...int) (r int) {
if i >= 0 && i < len(a) {
r = a[i]
}
if len(args) > 0 {
r = args[0]
}
return
}
// parse time to string with location
func timeParse(dateString, format string) (time.Time, error) {
tp, err := time.ParseInLocation(format, dateString, DefaultTimeLoc)
return tp, err
}
// get pointer indirect type
func indirectType(v reflect.Type) reflect.Type {
switch v.Kind() {
case reflect.Ptr:
return indirectType(v.Elem())
default:
return v
}
}