Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
B
beego
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
beego
Commits
95e67ba2
Commit
95e67ba2
authored
Mar 13, 2014
by
slene
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
orm now support custom builtin types as model struct field or query args fix #489
parent
769f7c75
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
160 additions
and
65 deletions
+160
-65
db_utils.go
orm/db_utils.go
+57
-45
models_test.go
orm/models_test.go
+39
-0
models_utils.go
orm/models_utils.go
+23
-16
orm_test.go
orm/orm_test.go
+41
-4
No files found.
orm/db_utils.go
View file @
95e67ba2
...
...
@@ -51,9 +51,16 @@ outFor:
continue
}
switch
v
:=
arg
.
(
type
)
{
case
[]
byte
:
case
string
:
kind
:=
val
.
Kind
()
if
kind
==
reflect
.
Ptr
{
val
=
val
.
Elem
()
kind
=
val
.
Kind
()
arg
=
val
.
Interface
()
}
switch
kind
{
case
reflect
.
String
:
v
:=
val
.
String
()
if
fi
!=
nil
{
if
fi
.
fieldType
==
TypeDateField
||
fi
.
fieldType
==
TypeDateTimeField
{
var
t
time
.
Time
...
...
@@ -78,61 +85,66 @@ outFor:
}
}
arg
=
v
case
time
.
Time
:
if
fi
!=
nil
&&
fi
.
fieldType
==
TypeDateField
{
arg
=
v
.
In
(
tz
)
.
Format
(
format_Date
)
}
else
{
arg
=
v
.
In
(
tz
)
.
Format
(
format_DateTime
)
case
reflect
.
Int
,
reflect
.
Int8
,
reflect
.
Int16
,
reflect
.
Int32
,
reflect
.
Int64
:
arg
=
val
.
Int
()
case
reflect
.
Uint
,
reflect
.
Uint8
,
reflect
.
Uint16
,
reflect
.
Uint32
,
reflect
.
Uint64
:
arg
=
val
.
Uint
()
case
reflect
.
Float32
:
arg
,
_
=
StrTo
(
ToStr
(
arg
))
.
Float64
()
case
reflect
.
Float64
:
arg
=
val
.
Float
()
case
reflect
.
Bool
:
arg
=
val
.
Bool
()
case
reflect
.
Slice
,
reflect
.
Array
:
if
_
,
ok
:=
arg
.
([]
byte
);
ok
{
continue
outFor
}
default
:
kind
:=
val
.
Kind
()
switch
kind
{
case
reflect
.
Slice
,
reflect
.
Array
:
var
args
[]
interface
{}
for
i
:=
0
;
i
<
val
.
Len
();
i
++
{
v
:=
val
.
Index
(
i
)
var
vu
interface
{}
if
v
.
CanInterface
()
{
vu
=
v
.
Interface
()
}
if
vu
==
nil
{
continue
}
var
args
[]
interface
{}
for
i
:=
0
;
i
<
val
.
Len
();
i
++
{
v
:=
val
.
Index
(
i
)
args
=
append
(
args
,
vu
)
var
vu
interface
{}
if
v
.
CanInterface
()
{
vu
=
v
.
Interface
()
}
if
len
(
args
)
>
0
{
p
:=
getFlatParams
(
fi
,
args
,
tz
)
params
=
append
(
params
,
p
...
)
if
vu
==
nil
{
continue
}
continue
outFor
case
reflect
.
Ptr
,
reflect
.
Struct
:
ind
:=
reflect
.
Indirect
(
val
)
args
=
append
(
args
,
vu
)
}
if
ind
.
Kind
()
==
reflect
.
Struct
{
typ
:=
ind
.
Type
()
name
:=
getFullName
(
typ
)
var
value
interface
{}
if
mmi
,
ok
:=
modelCache
.
getByFN
(
name
);
ok
{
if
_
,
vu
,
exist
:=
getExistPk
(
mmi
,
ind
);
exist
{
value
=
vu
}
if
len
(
args
)
>
0
{
p
:=
getFlatParams
(
fi
,
args
,
tz
)
params
=
append
(
params
,
p
...
)
}
continue
outFor
case
reflect
.
Struct
:
if
v
,
ok
:=
arg
.
(
time
.
Time
);
ok
{
if
fi
!=
nil
&&
fi
.
fieldType
==
TypeDateField
{
arg
=
v
.
In
(
tz
)
.
Format
(
format_Date
)
}
else
{
arg
=
v
.
In
(
tz
)
.
Format
(
format_DateTime
)
}
}
else
{
typ
:=
val
.
Type
()
name
:=
getFullName
(
typ
)
var
value
interface
{}
if
mmi
,
ok
:=
modelCache
.
getByFN
(
name
);
ok
{
if
_
,
vu
,
exist
:=
getExistPk
(
mmi
,
val
);
exist
{
value
=
vu
}
arg
=
value
}
arg
=
value
if
arg
==
nil
{
panic
(
fmt
.
Errorf
(
"need a valid args value, unknown table or value `%s`"
,
name
))
}
}
else
{
arg
=
ind
.
Interface
()
if
arg
==
nil
{
panic
(
fmt
.
Errorf
(
"need a valid args value, unknown table or value `%s`"
,
name
))
}
}
}
params
=
append
(
params
,
arg
)
}
return
...
...
orm/models_test.go
View file @
95e67ba2
...
...
@@ -144,6 +144,45 @@ type DataNull struct {
NullInt64
sql
.
NullInt64
`orm:"null"`
}
type
String
string
type
Boolean
bool
type
Byte
byte
type
Rune
rune
type
Int
int
type
Int8
int8
type
Int16
int16
type
Int32
int32
type
Int64
int64
type
Uint
uint
type
Uint8
uint8
type
Uint16
uint16
type
Uint32
uint32
type
Uint64
uint64
type
Float32
float64
type
Float64
float64
type
DataCustom
struct
{
Id
int
Boolean
Boolean
Char
string
`orm:"size(50)"`
Text
string
`orm:"type(text)"`
Byte
Byte
Rune
Rune
Int
Int
Int8
Int8
Int16
Int16
Int32
Int32
Int64
Int64
Uint
Uint
Uint8
Uint8
Uint16
Uint16
Uint32
Uint32
Uint64
Uint64
Float32
Float32
Float64
Float64
Decimal
Float64
`orm:"digits(8);decimals(4)"`
}
// only for mysql
type
UserBig
struct
{
Id
uint64
...
...
orm/models_utils.go
View file @
95e67ba2
...
...
@@ -99,34 +99,41 @@ func getColumnName(ft int, addrField reflect.Value, sf reflect.StructField, col
// return field type as type constant from reflect.Value
func
getFieldType
(
val
reflect
.
Value
)
(
ft
int
,
err
error
)
{
elm
:=
reflect
.
Indirect
(
val
)
switch
elm
.
Interface
()
.
(
type
)
{
case
i
nt8
:
switch
elm
.
Kind
(
)
{
case
reflect
.
I
nt8
:
ft
=
TypeBitField
case
i
nt16
:
case
reflect
.
I
nt16
:
ft
=
TypeSmallIntegerField
case
int32
,
i
nt
:
case
reflect
.
Int32
,
reflect
.
I
nt
:
ft
=
TypeIntegerField
case
int64
,
sql
.
Null
Int64
:
case
reflect
.
Int64
:
ft
=
TypeBigIntegerField
case
u
int8
:
case
reflect
.
U
int8
:
ft
=
TypePositiveBitField
case
u
int16
:
case
reflect
.
U
int16
:
ft
=
TypePositiveSmallIntegerField
case
uint32
,
u
int
:
case
reflect
.
Uint32
,
reflect
.
U
int
:
ft
=
TypePositiveIntegerField
case
u
int64
:
case
reflect
.
U
int64
:
ft
=
TypePositiveBigIntegerField
case
float32
,
float64
,
sql
.
Null
Float64
:
case
reflect
.
Float32
,
reflect
.
Float64
:
ft
=
TypeFloatField
case
bool
,
sql
.
Null
Bool
:
case
reflect
.
Bool
:
ft
=
TypeBooleanField
case
string
,
sql
.
Null
String
:
case
reflect
.
String
:
ft
=
TypeCharField
default
:
if
elm
.
CanInterface
()
{
if
_
,
ok
:=
elm
.
Interface
()
.
(
time
.
Time
);
ok
{
ft
=
TypeDateTimeField
}
switch
elm
.
Interface
()
.
(
type
)
{
case
sql
.
NullInt64
:
ft
=
TypeBigIntegerField
case
sql
.
NullFloat64
:
ft
=
TypeFloatField
case
sql
.
NullBool
:
ft
=
TypeBooleanField
case
sql
.
NullString
:
ft
=
TypeCharField
case
time
.
Time
:
ft
=
TypeDateTimeField
}
}
if
ft
&
IsFieldType
==
0
{
...
...
orm/orm_test.go
View file @
95e67ba2
...
...
@@ -149,7 +149,7 @@ func TestGetDB(t *testing.T) {
}
func
TestSyncDb
(
t
*
testing
.
T
)
{
RegisterModel
(
new
(
Data
),
new
(
DataNull
))
RegisterModel
(
new
(
Data
),
new
(
DataNull
)
,
new
(
DataCustom
)
)
RegisterModel
(
new
(
User
))
RegisterModel
(
new
(
Profile
))
RegisterModel
(
new
(
Post
))
...
...
@@ -165,7 +165,7 @@ func TestSyncDb(t *testing.T) {
}
func
TestRegisterModels
(
t
*
testing
.
T
)
{
RegisterModel
(
new
(
Data
),
new
(
DataNull
))
RegisterModel
(
new
(
Data
),
new
(
DataNull
)
,
new
(
DataCustom
)
)
RegisterModel
(
new
(
User
))
RegisterModel
(
new
(
Profile
))
RegisterModel
(
new
(
Post
))
...
...
@@ -309,6 +309,39 @@ func TestNullDataTypes(t *testing.T) {
throwFail
(
t
,
AssertIs
(
d
.
NullFloat64
.
Float64
,
42.42
))
}
func
TestDataCustomTypes
(
t
*
testing
.
T
)
{
d
:=
DataCustom
{}
ind
:=
reflect
.
Indirect
(
reflect
.
ValueOf
(
&
d
))
for
name
,
value
:=
range
Data_Values
{
e
:=
ind
.
FieldByName
(
name
)
if
!
e
.
IsValid
()
{
continue
}
e
.
Set
(
reflect
.
ValueOf
(
value
)
.
Convert
(
e
.
Type
()))
}
id
,
err
:=
dORM
.
Insert
(
&
d
)
throwFail
(
t
,
err
)
throwFail
(
t
,
AssertIs
(
id
,
1
))
d
=
DataCustom
{
Id
:
1
}
err
=
dORM
.
Read
(
&
d
)
throwFail
(
t
,
err
)
ind
=
reflect
.
Indirect
(
reflect
.
ValueOf
(
&
d
))
for
name
,
value
:=
range
Data_Values
{
e
:=
ind
.
FieldByName
(
name
)
if
!
e
.
IsValid
()
{
continue
}
vu
:=
e
.
Interface
()
value
=
reflect
.
ValueOf
(
value
)
.
Convert
(
e
.
Type
())
.
Interface
()
throwFail
(
t
,
AssertIs
(
vu
==
value
,
true
),
value
,
vu
)
}
}
func
TestCRUD
(
t
*
testing
.
T
)
{
profile
:=
NewProfile
()
profile
.
Age
=
30
...
...
@@ -562,6 +595,10 @@ func TestOperators(t *testing.T) {
throwFail
(
t
,
err
)
throwFail
(
t
,
AssertIs
(
num
,
1
))
num
,
err
=
qs
.
Filter
(
"user_name__exact"
,
String
(
"slene"
))
.
Count
()
throwFail
(
t
,
err
)
throwFail
(
t
,
AssertIs
(
num
,
1
))
num
,
err
=
qs
.
Filter
(
"user_name__exact"
,
"slene"
)
.
Count
()
throwFail
(
t
,
err
)
throwFail
(
t
,
AssertIs
(
num
,
1
))
...
...
@@ -602,11 +639,11 @@ func TestOperators(t *testing.T) {
throwFail
(
t
,
err
)
throwFail
(
t
,
AssertIs
(
num
,
3
))
num
,
err
=
qs
.
Filter
(
"status__lt"
,
3
)
.
Count
()
num
,
err
=
qs
.
Filter
(
"status__lt"
,
Uint
(
3
)
)
.
Count
()
throwFail
(
t
,
err
)
throwFail
(
t
,
AssertIs
(
num
,
2
))
num
,
err
=
qs
.
Filter
(
"status__lte"
,
3
)
.
Count
()
num
,
err
=
qs
.
Filter
(
"status__lte"
,
Int
(
3
)
)
.
Count
()
throwFail
(
t
,
err
)
throwFail
(
t
,
AssertIs
(
num
,
3
))
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment