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
9e3ebc88
Commit
9e3ebc88
authored
Feb 28, 2014
by
slene
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #513 from hobeone/develop
add support for sql.Null* types, thx hobeone
parents
d05270d2
6e00cfb4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
165 additions
and
58 deletions
+165
-58
db.go
orm/db.go
+88
-19
models_test.go
orm/models_test.go
+27
-23
models_utils.go
orm/models_utils.go
+13
-13
orm_test.go
orm/orm_test.go
+37
-3
No files found.
orm/db.go
View file @
9e3ebc88
...
@@ -103,15 +103,36 @@ func (d *dbBase) collectFieldValue(mi *modelInfo, fi *fieldInfo, ind reflect.Val
...
@@ -103,15 +103,36 @@ func (d *dbBase) collectFieldValue(mi *modelInfo, fi *fieldInfo, ind reflect.Val
}
else
{
}
else
{
switch
fi
.
fieldType
{
switch
fi
.
fieldType
{
case
TypeBooleanField
:
case
TypeBooleanField
:
value
=
field
.
Bool
()
if
nb
,
ok
:=
field
.
Interface
()
.
(
sql
.
NullBool
);
ok
{
value
=
nil
if
nb
.
Valid
{
value
=
nb
.
Bool
}
}
else
{
value
=
field
.
Bool
()
}
case
TypeCharField
,
TypeTextField
:
case
TypeCharField
,
TypeTextField
:
value
=
field
.
String
()
if
ns
,
ok
:=
field
.
Interface
()
.
(
sql
.
NullString
);
ok
{
value
=
nil
if
ns
.
Valid
{
value
=
ns
.
String
}
}
else
{
value
=
field
.
String
()
}
case
TypeFloatField
,
TypeDecimalField
:
case
TypeFloatField
,
TypeDecimalField
:
vu
:=
field
.
Interface
()
if
nf
,
ok
:=
field
.
Interface
()
.
(
sql
.
NullFloat64
);
ok
{
if
_
,
ok
:=
vu
.
(
float32
);
ok
{
value
=
nil
value
,
_
=
StrTo
(
ToStr
(
vu
))
.
Float64
()
if
nf
.
Valid
{
value
=
nf
.
Float64
}
}
else
{
}
else
{
value
=
field
.
Float
()
vu
:=
field
.
Interface
()
if
_
,
ok
:=
vu
.
(
float32
);
ok
{
value
,
_
=
StrTo
(
ToStr
(
vu
))
.
Float64
()
}
else
{
value
=
field
.
Float
()
}
}
}
case
TypeDateField
,
TypeDateTimeField
:
case
TypeDateField
,
TypeDateTimeField
:
value
=
field
.
Interface
()
value
=
field
.
Interface
()
...
@@ -124,7 +145,14 @@ func (d *dbBase) collectFieldValue(mi *modelInfo, fi *fieldInfo, ind reflect.Val
...
@@ -124,7 +145,14 @@ func (d *dbBase) collectFieldValue(mi *modelInfo, fi *fieldInfo, ind reflect.Val
case
fi
.
fieldType
&
IsPostiveIntegerField
>
0
:
case
fi
.
fieldType
&
IsPostiveIntegerField
>
0
:
value
=
field
.
Uint
()
value
=
field
.
Uint
()
case
fi
.
fieldType
&
IsIntegerField
>
0
:
case
fi
.
fieldType
&
IsIntegerField
>
0
:
value
=
field
.
Int
()
if
ni
,
ok
:=
field
.
Interface
()
.
(
sql
.
NullInt64
);
ok
{
value
=
nil
if
ni
.
Valid
{
value
=
ni
.
Int64
}
}
else
{
value
=
field
.
Int
()
}
case
fi
.
fieldType
&
IsRelField
>
0
:
case
fi
.
fieldType
&
IsRelField
>
0
:
if
field
.
IsNil
()
{
if
field
.
IsNil
()
{
value
=
nil
value
=
nil
...
@@ -1122,17 +1150,37 @@ setValue:
...
@@ -1122,17 +1150,37 @@ setValue:
switch
{
switch
{
case
fieldType
==
TypeBooleanField
:
case
fieldType
==
TypeBooleanField
:
if
isNative
{
if
isNative
{
if
value
==
nil
{
if
nb
,
ok
:=
field
.
Interface
()
.
(
sql
.
NullBool
);
ok
{
value
=
false
if
value
==
nil
{
nb
.
Valid
=
false
}
else
{
nb
.
Bool
=
value
.
(
bool
)
nb
.
Valid
=
true
}
field
.
Set
(
reflect
.
ValueOf
(
nb
))
}
else
{
if
value
==
nil
{
value
=
false
}
field
.
SetBool
(
value
.
(
bool
))
}
}
field
.
SetBool
(
value
.
(
bool
))
}
}
case
fieldType
==
TypeCharField
||
fieldType
==
TypeTextField
:
case
fieldType
==
TypeCharField
||
fieldType
==
TypeTextField
:
if
isNative
{
if
isNative
{
if
value
==
nil
{
if
ns
,
ok
:=
field
.
Interface
()
.
(
sql
.
NullString
);
ok
{
value
=
""
if
value
==
nil
{
ns
.
Valid
=
false
}
else
{
ns
.
String
=
value
.
(
string
)
ns
.
Valid
=
true
}
field
.
Set
(
reflect
.
ValueOf
(
ns
))
}
else
{
if
value
==
nil
{
value
=
""
}
field
.
SetString
(
value
.
(
string
))
}
}
field
.
SetString
(
value
.
(
string
))
}
}
case
fieldType
==
TypeDateField
||
fieldType
==
TypeDateTimeField
:
case
fieldType
==
TypeDateField
||
fieldType
==
TypeDateTimeField
:
if
isNative
{
if
isNative
{
...
@@ -1151,18 +1199,39 @@ setValue:
...
@@ -1151,18 +1199,39 @@ setValue:
}
}
}
else
{
}
else
{
if
isNative
{
if
isNative
{
if
value
==
nil
{
if
ni
,
ok
:=
field
.
Interface
()
.
(
sql
.
NullInt64
);
ok
{
value
=
int64
(
0
)
if
value
==
nil
{
ni
.
Valid
=
false
}
else
{
ni
.
Int64
=
value
.
(
int64
)
ni
.
Valid
=
true
}
field
.
Set
(
reflect
.
ValueOf
(
ni
))
}
else
{
if
value
==
nil
{
value
=
int64
(
0
)
}
field
.
SetInt
(
value
.
(
int64
))
}
}
field
.
SetInt
(
value
.
(
int64
))
}
}
}
}
case
fieldType
==
TypeFloatField
||
fieldType
==
TypeDecimalField
:
case
fieldType
==
TypeFloatField
||
fieldType
==
TypeDecimalField
:
if
isNative
{
if
isNative
{
if
value
==
nil
{
if
nf
,
ok
:=
field
.
Interface
()
.
(
sql
.
NullFloat64
);
ok
{
value
=
float64
(
0
)
if
value
==
nil
{
nf
.
Valid
=
false
}
else
{
nf
.
Float64
=
value
.
(
float64
)
nf
.
Valid
=
true
}
field
.
Set
(
reflect
.
ValueOf
(
nf
))
}
else
{
if
value
==
nil
{
value
=
float64
(
0
)
}
field
.
SetFloat
(
value
.
(
float64
))
}
}
field
.
SetFloat
(
value
.
(
float64
))
}
}
case
fieldType
&
IsRelField
>
0
:
case
fieldType
&
IsRelField
>
0
:
if
value
!=
nil
{
if
value
!=
nil
{
...
...
orm/models_test.go
View file @
9e3ebc88
package
orm
package
orm
import
(
import
(
"database/sql"
"encoding/json"
"encoding/json"
"fmt"
"fmt"
"os"
"os"
...
@@ -116,27 +117,31 @@ type Data struct {
...
@@ -116,27 +117,31 @@ type Data struct {
}
}
type
DataNull
struct
{
type
DataNull
struct
{
Id
int
Id
int
Boolean
bool
`orm:"null"`
Boolean
bool
`orm:"null"`
Char
string
`orm:"null;size(50)"`
Char
string
`orm:"null;size(50)"`
Text
string
`orm:"null;type(text)"`
Text
string
`orm:"null;type(text)"`
Date
time
.
Time
`orm:"null;type(date)"`
Date
time
.
Time
`orm:"null;type(date)"`
DateTime
time
.
Time
`orm:"null;column(datetime)""`
DateTime
time
.
Time
`orm:"null;column(datetime)""`
Byte
byte
`orm:"null"`
Byte
byte
`orm:"null"`
Rune
rune
`orm:"null"`
Rune
rune
`orm:"null"`
Int
int
`orm:"null"`
Int
int
`orm:"null"`
Int8
int8
`orm:"null"`
Int8
int8
`orm:"null"`
Int16
int16
`orm:"null"`
Int16
int16
`orm:"null"`
Int32
int32
`orm:"null"`
Int32
int32
`orm:"null"`
Int64
int64
`orm:"null"`
Int64
int64
`orm:"null"`
Uint
uint
`orm:"null"`
Uint
uint
`orm:"null"`
Uint8
uint8
`orm:"null"`
Uint8
uint8
`orm:"null"`
Uint16
uint16
`orm:"null"`
Uint16
uint16
`orm:"null"`
Uint32
uint32
`orm:"null"`
Uint32
uint32
`orm:"null"`
Uint64
uint64
`orm:"null"`
Uint64
uint64
`orm:"null"`
Float32
float32
`orm:"null"`
Float32
float32
`orm:"null"`
Float64
float64
`orm:"null"`
Float64
float64
`orm:"null"`
Decimal
float64
`orm:"digits(8);decimals(4);null"`
Decimal
float64
`orm:"digits(8);decimals(4);null"`
NullString
sql
.
NullString
`orm:"null"`
NullBool
sql
.
NullBool
`orm:"null"`
NullFloat64
sql
.
NullFloat64
`orm:"null"`
NullInt64
sql
.
NullInt64
`orm:"null"`
}
}
// only for mysql
// only for mysql
...
@@ -303,9 +308,8 @@ go test -v github.com/astaxie/beego/orm
...
@@ -303,9 +308,8 @@ go test -v github.com/astaxie/beego/orm
#### Sqlite3
#### Sqlite3
touch /path/to/orm_test.db
export ORM_DRIVER=sqlite3
export ORM_DRIVER=sqlite3
export ORM_SOURCE=
/path/to/orm_test.db
export ORM_SOURCE=
'file:memory_test?mode=memory'
go test -v github.com/astaxie/beego/orm
go test -v github.com/astaxie/beego/orm
...
...
orm/models_utils.go
View file @
9e3ebc88
package
orm
package
orm
import
(
import
(
"database/sql"
"fmt"
"fmt"
"reflect"
"reflect"
"strings"
"strings"
...
@@ -98,30 +99,29 @@ func getColumnName(ft int, addrField reflect.Value, sf reflect.StructField, col
...
@@ -98,30 +99,29 @@ func getColumnName(ft int, addrField reflect.Value, sf reflect.StructField, col
// return field type as type constant from reflect.Value
// return field type as type constant from reflect.Value
func
getFieldType
(
val
reflect
.
Value
)
(
ft
int
,
err
error
)
{
func
getFieldType
(
val
reflect
.
Value
)
(
ft
int
,
err
error
)
{
elm
:=
reflect
.
Indirect
(
val
)
elm
:=
reflect
.
Indirect
(
val
)
switch
elm
.
Kind
(
)
{
switch
elm
.
Interface
()
.
(
type
)
{
case
reflect
.
I
nt8
:
case
i
nt8
:
ft
=
TypeBitField
ft
=
TypeBitField
case
reflect
.
I
nt16
:
case
i
nt16
:
ft
=
TypeSmallIntegerField
ft
=
TypeSmallIntegerField
case
reflect
.
Int32
,
reflect
.
I
nt
:
case
int32
,
i
nt
:
ft
=
TypeIntegerField
ft
=
TypeIntegerField
case
reflect
.
Int64
:
case
int64
,
sql
.
Null
Int64
:
ft
=
TypeBigIntegerField
ft
=
TypeBigIntegerField
case
reflect
.
U
int8
:
case
u
int8
:
ft
=
TypePositiveBitField
ft
=
TypePositiveBitField
case
reflect
.
U
int16
:
case
u
int16
:
ft
=
TypePositiveSmallIntegerField
ft
=
TypePositiveSmallIntegerField
case
reflect
.
Uint32
,
reflect
.
U
int
:
case
uint32
,
u
int
:
ft
=
TypePositiveIntegerField
ft
=
TypePositiveIntegerField
case
reflect
.
U
int64
:
case
u
int64
:
ft
=
TypePositiveBigIntegerField
ft
=
TypePositiveBigIntegerField
case
reflect
.
Float32
,
reflect
.
Float64
:
case
float32
,
float64
,
sql
.
Null
Float64
:
ft
=
TypeFloatField
ft
=
TypeFloatField
case
reflect
.
Bool
:
case
bool
,
sql
.
Null
Bool
:
ft
=
TypeBooleanField
ft
=
TypeBooleanField
case
reflect
.
String
:
case
string
,
sql
.
Null
String
:
ft
=
TypeCharField
ft
=
TypeCharField
case
reflect
.
Invalid
:
default
:
default
:
if
elm
.
CanInterface
()
{
if
elm
.
CanInterface
()
{
if
_
,
ok
:=
elm
.
Interface
()
.
(
time
.
Time
);
ok
{
if
_
,
ok
:=
elm
.
Interface
()
.
(
time
.
Time
);
ok
{
...
...
orm/orm_test.go
View file @
9e3ebc88
...
@@ -2,6 +2,7 @@ package orm
...
@@ -2,6 +2,7 @@ package orm
import
(
import
(
"bytes"
"bytes"
"database/sql"
"fmt"
"fmt"
"io/ioutil"
"io/ioutil"
"os"
"os"
...
@@ -258,12 +259,45 @@ func TestNullDataTypes(t *testing.T) {
...
@@ -258,12 +259,45 @@ func TestNullDataTypes(t *testing.T) {
err
=
dORM
.
Read
(
&
d
)
err
=
dORM
.
Read
(
&
d
)
throwFail
(
t
,
err
)
throwFail
(
t
,
err
)
throwFail
(
t
,
AssertIs
(
d
.
NullBool
.
Valid
,
false
))
throwFail
(
t
,
AssertIs
(
d
.
NullString
.
Valid
,
false
))
throwFail
(
t
,
AssertIs
(
d
.
NullInt64
.
Valid
,
false
))
throwFail
(
t
,
AssertIs
(
d
.
NullFloat64
.
Valid
,
false
))
_
,
err
=
dORM
.
Raw
(
`INSERT INTO data_null (boolean) VALUES (?)`
,
nil
)
.
Exec
()
_
,
err
=
dORM
.
Raw
(
`INSERT INTO data_null (boolean) VALUES (?)`
,
nil
)
.
Exec
()
throwFail
(
t
,
err
)
throwFail
(
t
,
err
)
d
=
DataNull
{
Id
:
2
}
d
=
DataNull
{
Id
:
2
}
err
=
dORM
.
Read
(
&
d
)
err
=
dORM
.
Read
(
&
d
)
throwFail
(
t
,
err
)
throwFail
(
t
,
err
)
d
=
DataNull
{
DateTime
:
time
.
Now
(),
NullString
:
sql
.
NullString
{
"test"
,
true
},
NullBool
:
sql
.
NullBool
{
true
,
true
},
NullInt64
:
sql
.
NullInt64
{
42
,
true
},
NullFloat64
:
sql
.
NullFloat64
{
42.42
,
true
},
}
id
,
err
=
dORM
.
Insert
(
&
d
)
throwFail
(
t
,
err
)
throwFail
(
t
,
AssertIs
(
id
,
3
))
d
=
DataNull
{
Id
:
3
}
err
=
dORM
.
Read
(
&
d
)
throwFail
(
t
,
err
)
throwFail
(
t
,
AssertIs
(
d
.
NullBool
.
Valid
,
true
))
throwFail
(
t
,
AssertIs
(
d
.
NullBool
.
Bool
,
true
))
throwFail
(
t
,
AssertIs
(
d
.
NullString
.
Valid
,
true
))
throwFail
(
t
,
AssertIs
(
d
.
NullString
.
String
,
"test"
))
throwFail
(
t
,
AssertIs
(
d
.
NullInt64
.
Valid
,
true
))
throwFail
(
t
,
AssertIs
(
d
.
NullInt64
.
Int64
,
42
))
throwFail
(
t
,
AssertIs
(
d
.
NullFloat64
.
Valid
,
true
))
throwFail
(
t
,
AssertIs
(
d
.
NullFloat64
.
Float64
,
42.42
))
}
}
func
TestCRUD
(
t
*
testing
.
T
)
{
func
TestCRUD
(
t
*
testing
.
T
)
{
...
@@ -1646,10 +1680,10 @@ func TestTransaction(t *testing.T) {
...
@@ -1646,10 +1680,10 @@ func TestTransaction(t *testing.T) {
func
TestReadOrCreate
(
t
*
testing
.
T
)
{
func
TestReadOrCreate
(
t
*
testing
.
T
)
{
u
:=
&
User
{
u
:=
&
User
{
UserName
:
"Kyle"
,
UserName
:
"Kyle"
,
Email
:
"kylemcc@gmail.com"
,
Email
:
"kylemcc@gmail.com"
,
Password
:
"other_pass"
,
Password
:
"other_pass"
,
Status
:
7
,
Status
:
7
,
IsStaff
:
false
,
IsStaff
:
false
,
IsActive
:
true
,
IsActive
:
true
,
}
}
...
...
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