mirror of
https://github.com/astaxie/beego.git
synced 2024-12-23 15:30:50 +00:00
Merge pull request #1875 from miraclesu/feature/orm_json
orm: add json & jsonb type support
This commit is contained in:
commit
f6ad2cf848
@ -90,6 +90,18 @@ checkColumn:
|
|||||||
} else {
|
} else {
|
||||||
col = fmt.Sprintf(s, fi.digits, fi.decimals)
|
col = fmt.Sprintf(s, fi.digits, fi.decimals)
|
||||||
}
|
}
|
||||||
|
case TypeJSONField:
|
||||||
|
if al.Driver != DRPostgres {
|
||||||
|
fieldType = TypeCharField
|
||||||
|
goto checkColumn
|
||||||
|
}
|
||||||
|
col = T["json"]
|
||||||
|
case TypeJsonbField:
|
||||||
|
if al.Driver != DRPostgres {
|
||||||
|
fieldType = TypeCharField
|
||||||
|
goto checkColumn
|
||||||
|
}
|
||||||
|
col = T["jsonb"]
|
||||||
case RelForeignKey, RelOneToOne:
|
case RelForeignKey, RelOneToOne:
|
||||||
fieldType = fi.relModelInfo.fields.pk.fieldType
|
fieldType = fi.relModelInfo.fields.pk.fieldType
|
||||||
fieldSize = fi.relModelInfo.fields.pk.size
|
fieldSize = fi.relModelInfo.fields.pk.size
|
||||||
@ -278,6 +290,8 @@ func getColumnDefault(fi *fieldInfo) string {
|
|||||||
case TypeBooleanField:
|
case TypeBooleanField:
|
||||||
t = " DEFAULT %s "
|
t = " DEFAULT %s "
|
||||||
d = "FALSE"
|
d = "FALSE"
|
||||||
|
case TypeJSONField, TypeJsonbField:
|
||||||
|
d = "{}"
|
||||||
}
|
}
|
||||||
|
|
||||||
if fi.colDefault {
|
if fi.colDefault {
|
||||||
|
14
orm/db.go
14
orm/db.go
@ -141,7 +141,7 @@ func (d *dbBase) collectFieldValue(mi *modelInfo, fi *fieldInfo, ind reflect.Val
|
|||||||
} else {
|
} else {
|
||||||
value = field.Bool()
|
value = field.Bool()
|
||||||
}
|
}
|
||||||
case TypeCharField, TypeTextField:
|
case TypeCharField, TypeTextField, TypeJSONField, TypeJsonbField:
|
||||||
if ns, ok := field.Interface().(sql.NullString); ok {
|
if ns, ok := field.Interface().(sql.NullString); ok {
|
||||||
value = nil
|
value = nil
|
||||||
if ns.Valid {
|
if ns.Valid {
|
||||||
@ -247,6 +247,14 @@ func (d *dbBase) collectFieldValue(mi *modelInfo, fi *fieldInfo, ind reflect.Val
|
|||||||
field.Set(reflect.ValueOf(tnow.In(DefaultTimeLoc)))
|
field.Set(reflect.ValueOf(tnow.In(DefaultTimeLoc)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case TypeJSONField, TypeJsonbField:
|
||||||
|
if s, ok := value.(string); (ok && len(s) == 0) || value == nil {
|
||||||
|
if fi.colDefault && fi.initial.Exist() {
|
||||||
|
value = fi.initial.String()
|
||||||
|
} else {
|
||||||
|
value = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return value, nil
|
return value, nil
|
||||||
@ -1093,7 +1101,7 @@ setValue:
|
|||||||
}
|
}
|
||||||
value = b
|
value = b
|
||||||
}
|
}
|
||||||
case fieldType == TypeCharField || fieldType == TypeTextField:
|
case fieldType == TypeCharField || fieldType == TypeTextField || fieldType == TypeJSONField || fieldType == TypeJsonbField:
|
||||||
if str == nil {
|
if str == nil {
|
||||||
value = ToStr(val)
|
value = ToStr(val)
|
||||||
} else {
|
} else {
|
||||||
@ -1239,7 +1247,7 @@ setValue:
|
|||||||
field.SetBool(value.(bool))
|
field.SetBool(value.(bool))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case fieldType == TypeCharField || fieldType == TypeTextField:
|
case fieldType == TypeCharField || fieldType == TypeTextField || fieldType == TypeJSONField || fieldType == TypeJsonbField:
|
||||||
if isNative {
|
if isNative {
|
||||||
if ns, ok := field.Interface().(sql.NullString); ok {
|
if ns, ok := field.Interface().(sql.NullString); ok {
|
||||||
if value == nil {
|
if value == nil {
|
||||||
|
@ -56,6 +56,8 @@ var postgresTypes = map[string]string{
|
|||||||
"uint64": `bigint CHECK("%COL%" >= 0)`,
|
"uint64": `bigint CHECK("%COL%" >= 0)`,
|
||||||
"float64": "double precision",
|
"float64": "double precision",
|
||||||
"float64-decimal": "numeric(%d, %d)",
|
"float64-decimal": "numeric(%d, %d)",
|
||||||
|
"json": "json",
|
||||||
|
"jsonb": "jsonb",
|
||||||
}
|
}
|
||||||
|
|
||||||
// postgresql dbBaser.
|
// postgresql dbBaser.
|
||||||
|
@ -38,6 +38,8 @@ const (
|
|||||||
TypePositiveBigIntegerField
|
TypePositiveBigIntegerField
|
||||||
TypeFloatField
|
TypeFloatField
|
||||||
TypeDecimalField
|
TypeDecimalField
|
||||||
|
TypeJSONField
|
||||||
|
TypeJsonbField
|
||||||
RelForeignKey
|
RelForeignKey
|
||||||
RelOneToOne
|
RelOneToOne
|
||||||
RelManyToMany
|
RelManyToMany
|
||||||
@ -49,7 +51,7 @@ const (
|
|||||||
const (
|
const (
|
||||||
IsIntegerField = ^-TypePositiveBigIntegerField >> 5 << 6
|
IsIntegerField = ^-TypePositiveBigIntegerField >> 5 << 6
|
||||||
IsPositiveIntegerField = ^-TypePositiveBigIntegerField >> 9 << 10
|
IsPositiveIntegerField = ^-TypePositiveBigIntegerField >> 9 << 10
|
||||||
IsRelField = ^-RelReverseMany >> 15 << 16
|
IsRelField = ^-RelReverseMany >> 17 << 18
|
||||||
IsFieldType = ^-RelReverseMany<<1 + 1
|
IsFieldType = ^-RelReverseMany<<1 + 1
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -146,7 +148,7 @@ func (e *CharField) RawValue() interface{} {
|
|||||||
// verify CharField implement Fielder
|
// verify CharField implement Fielder
|
||||||
var _ Fielder = new(CharField)
|
var _ Fielder = new(CharField)
|
||||||
|
|
||||||
// A time, represented in go by a time.Time instance.
|
// TimeField A time, represented in go by a time.Time instance.
|
||||||
// only time values like 10:00:00
|
// only time values like 10:00:00
|
||||||
// Has a few extra, optional attr tag:
|
// Has a few extra, optional attr tag:
|
||||||
//
|
//
|
||||||
@ -161,22 +163,27 @@ var _ Fielder = new(CharField)
|
|||||||
// eg: `orm:"auto_now"` or `orm:"auto_now_add"`
|
// eg: `orm:"auto_now"` or `orm:"auto_now_add"`
|
||||||
type TimeField time.Time
|
type TimeField time.Time
|
||||||
|
|
||||||
|
// Value return the time.Time
|
||||||
func (e TimeField) Value() time.Time {
|
func (e TimeField) Value() time.Time {
|
||||||
return time.Time(e)
|
return time.Time(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set set the TimeField's value
|
||||||
func (e *TimeField) Set(d time.Time) {
|
func (e *TimeField) Set(d time.Time) {
|
||||||
*e = TimeField(d)
|
*e = TimeField(d)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// String convert time to string
|
||||||
func (e *TimeField) String() string {
|
func (e *TimeField) String() string {
|
||||||
return e.Value().String()
|
return e.Value().String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FieldType return enum type Date
|
||||||
func (e *TimeField) FieldType() int {
|
func (e *TimeField) FieldType() int {
|
||||||
return TypeDateField
|
return TypeDateField
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetRaw convert the interface to time.Time. Allow string and time.Time
|
||||||
func (e *TimeField) SetRaw(value interface{}) error {
|
func (e *TimeField) SetRaw(value interface{}) error {
|
||||||
switch d := value.(type) {
|
switch d := value.(type) {
|
||||||
case time.Time:
|
case time.Time:
|
||||||
@ -193,6 +200,7 @@ func (e *TimeField) SetRaw(value interface{}) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RawValue return time value
|
||||||
func (e *TimeField) RawValue() interface{} {
|
func (e *TimeField) RawValue() interface{} {
|
||||||
return e.Value()
|
return e.Value()
|
||||||
}
|
}
|
||||||
@ -681,3 +689,87 @@ func (e *TextField) RawValue() interface{} {
|
|||||||
|
|
||||||
// verify TextField implement Fielder
|
// verify TextField implement Fielder
|
||||||
var _ Fielder = new(TextField)
|
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)
|
||||||
|
@ -239,8 +239,15 @@ checkType:
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
goto end
|
goto end
|
||||||
}
|
}
|
||||||
if fieldType == TypeCharField && tags["type"] == "text" {
|
if fieldType == TypeCharField {
|
||||||
fieldType = TypeTextField
|
switch tags["type"] {
|
||||||
|
case "text":
|
||||||
|
fieldType = TypeTextField
|
||||||
|
case "json":
|
||||||
|
fieldType = TypeJSONField
|
||||||
|
case "jsonb":
|
||||||
|
fieldType = TypeJsonbField
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if fieldType == TypeFloatField && (digits != "" || decimals != "") {
|
if fieldType == TypeFloatField && (digits != "" || decimals != "") {
|
||||||
fieldType = TypeDecimalField
|
fieldType = TypeDecimalField
|
||||||
@ -342,7 +349,7 @@ checkType:
|
|||||||
|
|
||||||
switch fieldType {
|
switch fieldType {
|
||||||
case TypeBooleanField:
|
case TypeBooleanField:
|
||||||
case TypeCharField:
|
case TypeCharField, TypeJSONField, TypeJsonbField:
|
||||||
if size != "" {
|
if size != "" {
|
||||||
v, e := StrTo(size).Int32()
|
v, e := StrTo(size).Int32()
|
||||||
if e != nil {
|
if e != nil {
|
||||||
|
@ -78,40 +78,42 @@ func (e *SliceStringField) RawValue() interface{} {
|
|||||||
var _ Fielder = new(SliceStringField)
|
var _ Fielder = new(SliceStringField)
|
||||||
|
|
||||||
// A json field.
|
// A json field.
|
||||||
type JSONField struct {
|
type JSONFieldTest struct {
|
||||||
Name string
|
Name string
|
||||||
Data string
|
Data string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *JSONField) String() string {
|
func (e *JSONFieldTest) String() string {
|
||||||
data, _ := json.Marshal(e)
|
data, _ := json.Marshal(e)
|
||||||
return string(data)
|
return string(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *JSONField) FieldType() int {
|
func (e *JSONFieldTest) FieldType() int {
|
||||||
return TypeTextField
|
return TypeTextField
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *JSONField) SetRaw(value interface{}) error {
|
func (e *JSONFieldTest) SetRaw(value interface{}) error {
|
||||||
switch d := value.(type) {
|
switch d := value.(type) {
|
||||||
case string:
|
case string:
|
||||||
return json.Unmarshal([]byte(d), e)
|
return json.Unmarshal([]byte(d), e)
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("<JsonField.SetRaw> unknown value `%v`", value)
|
return fmt.Errorf("<JSONField.SetRaw> unknown value `%v`", value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *JSONField) RawValue() interface{} {
|
func (e *JSONFieldTest) RawValue() interface{} {
|
||||||
return e.String()
|
return e.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ Fielder = new(JSONField)
|
var _ Fielder = new(JSONFieldTest)
|
||||||
|
|
||||||
type Data struct {
|
type Data struct {
|
||||||
ID int `orm:"column(id)"`
|
ID int `orm:"column(id)"`
|
||||||
Boolean bool
|
Boolean bool
|
||||||
Char string `orm:"size(50)"`
|
Char string `orm:"size(50)"`
|
||||||
Text string `orm:"type(text)"`
|
Text string `orm:"type(text)"`
|
||||||
|
JSON string `orm:"type(json);default({\"name\":\"json\"})"`
|
||||||
|
Jsonb string `orm:"type(jsonb)"`
|
||||||
Time time.Time `orm:"type(time)"`
|
Time time.Time `orm:"type(time)"`
|
||||||
Date time.Time `orm:"type(date)"`
|
Date time.Time `orm:"type(date)"`
|
||||||
DateTime time.Time `orm:"column(datetime)"`
|
DateTime time.Time `orm:"column(datetime)"`
|
||||||
@ -137,6 +139,8 @@ type DataNull struct {
|
|||||||
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)"`
|
||||||
|
JSON string `orm:"type(json);null"`
|
||||||
|
Jsonb string `orm:"type(jsonb);null"`
|
||||||
Time time.Time `orm:"null;type(time)"`
|
Time time.Time `orm:"null;type(time)"`
|
||||||
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)"`
|
||||||
@ -239,7 +243,7 @@ type User struct {
|
|||||||
ShouldSkip string `orm:"-"`
|
ShouldSkip string `orm:"-"`
|
||||||
Nums int
|
Nums int
|
||||||
Langs SliceStringField `orm:"size(100)"`
|
Langs SliceStringField `orm:"size(100)"`
|
||||||
Extra JSONField `orm:"type(text)"`
|
Extra JSONFieldTest `orm:"type(text)"`
|
||||||
unexport bool `orm:"-"`
|
unexport bool `orm:"-"`
|
||||||
unexportBool bool
|
unexportBool bool
|
||||||
}
|
}
|
||||||
@ -390,12 +394,12 @@ func NewInLineOneToOne() *InLineOneToOne {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type IntegerPk struct {
|
type IntegerPk struct {
|
||||||
Id int64 `orm:"pk"`
|
ID int64 `orm:"pk"`
|
||||||
Value string
|
Value string
|
||||||
}
|
}
|
||||||
|
|
||||||
type UintPk struct {
|
type UintPk struct {
|
||||||
Id uint32 `orm:"pk"`
|
ID uint32 `orm:"pk"`
|
||||||
Name string
|
Name string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,6 +241,8 @@ var DataValues = map[string]interface{}{
|
|||||||
"Boolean": true,
|
"Boolean": true,
|
||||||
"Char": "char",
|
"Char": "char",
|
||||||
"Text": "text",
|
"Text": "text",
|
||||||
|
"JSON": `{"name":"json"}`,
|
||||||
|
"Jsonb": `{"name": "jsonb"}`,
|
||||||
"Time": time.Now(),
|
"Time": time.Now(),
|
||||||
"Date": time.Now(),
|
"Date": time.Now(),
|
||||||
"DateTime": time.Now(),
|
"DateTime": time.Now(),
|
||||||
@ -266,6 +268,9 @@ func TestDataTypes(t *testing.T) {
|
|||||||
ind := reflect.Indirect(reflect.ValueOf(&d))
|
ind := reflect.Indirect(reflect.ValueOf(&d))
|
||||||
|
|
||||||
for name, value := range DataValues {
|
for name, value := range DataValues {
|
||||||
|
if name == "JSON" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
e := ind.FieldByName(name)
|
e := ind.FieldByName(name)
|
||||||
e.Set(reflect.ValueOf(value))
|
e.Set(reflect.ValueOf(value))
|
||||||
}
|
}
|
||||||
@ -310,10 +315,18 @@ func TestNullDataTypes(t *testing.T) {
|
|||||||
throwFail(t, err)
|
throwFail(t, err)
|
||||||
throwFail(t, AssertIs(id, 1))
|
throwFail(t, AssertIs(id, 1))
|
||||||
|
|
||||||
|
data := `{"ok":1,"data":{"arr":[1,2],"msg":"gopher"}}`
|
||||||
|
d = DataNull{ID: 1, JSON: data}
|
||||||
|
num, err := dORM.Update(&d)
|
||||||
|
throwFail(t, err)
|
||||||
|
throwFail(t, AssertIs(num, 1))
|
||||||
|
|
||||||
d = DataNull{ID: 1}
|
d = DataNull{ID: 1}
|
||||||
err = dORM.Read(&d)
|
err = dORM.Read(&d)
|
||||||
throwFail(t, err)
|
throwFail(t, err)
|
||||||
|
|
||||||
|
throwFail(t, AssertIs(d.JSON, data))
|
||||||
|
|
||||||
throwFail(t, AssertIs(d.NullBool.Valid, false))
|
throwFail(t, AssertIs(d.NullBool.Valid, false))
|
||||||
throwFail(t, AssertIs(d.NullString.Valid, false))
|
throwFail(t, AssertIs(d.NullString.Valid, false))
|
||||||
throwFail(t, AssertIs(d.NullInt64.Valid, false))
|
throwFail(t, AssertIs(d.NullInt64.Valid, false))
|
||||||
@ -2014,9 +2027,9 @@ func TestInLineOneToOne(t *testing.T) {
|
|||||||
|
|
||||||
func TestIntegerPk(t *testing.T) {
|
func TestIntegerPk(t *testing.T) {
|
||||||
its := []IntegerPk{
|
its := []IntegerPk{
|
||||||
{Id: math.MinInt64, Value: "-"},
|
{ID: math.MinInt64, Value: "-"},
|
||||||
{Id: 0, Value: "0"},
|
{ID: 0, Value: "0"},
|
||||||
{Id: math.MaxInt64, Value: "+"},
|
{ID: math.MaxInt64, Value: "+"},
|
||||||
}
|
}
|
||||||
|
|
||||||
num, err := dORM.InsertMulti(len(its), its)
|
num, err := dORM.InsertMulti(len(its), its)
|
||||||
@ -2024,7 +2037,7 @@ func TestIntegerPk(t *testing.T) {
|
|||||||
throwFail(t, AssertIs(num, len(its)))
|
throwFail(t, AssertIs(num, len(its)))
|
||||||
|
|
||||||
for _, intPk := range its {
|
for _, intPk := range its {
|
||||||
out := IntegerPk{Id: intPk.Id}
|
out := IntegerPk{ID: intPk.ID}
|
||||||
err = dORM.Read(&out)
|
err = dORM.Read(&out)
|
||||||
throwFail(t, err)
|
throwFail(t, err)
|
||||||
throwFail(t, AssertIs(out.Value, intPk.Value))
|
throwFail(t, AssertIs(out.Value, intPk.Value))
|
||||||
@ -2072,21 +2085,21 @@ func TestInsertAuto(t *testing.T) {
|
|||||||
func TestUintPk(t *testing.T) {
|
func TestUintPk(t *testing.T) {
|
||||||
name := "go"
|
name := "go"
|
||||||
u := &UintPk{
|
u := &UintPk{
|
||||||
Id: 8,
|
ID: 8,
|
||||||
Name: name,
|
Name: name,
|
||||||
}
|
}
|
||||||
|
|
||||||
created, pk, err := dORM.ReadOrCreate(u, "Id")
|
created, pk, err := dORM.ReadOrCreate(u, "ID")
|
||||||
throwFail(t, err)
|
throwFail(t, err)
|
||||||
throwFail(t, AssertIs(created, true))
|
throwFail(t, AssertIs(created, true))
|
||||||
throwFail(t, AssertIs(u.Name, name))
|
throwFail(t, AssertIs(u.Name, name))
|
||||||
|
|
||||||
nu := &UintPk{Id: 8}
|
nu := &UintPk{ID: 8}
|
||||||
created, pk, err = dORM.ReadOrCreate(nu, "Id")
|
created, pk, err = dORM.ReadOrCreate(nu, "ID")
|
||||||
throwFail(t, err)
|
throwFail(t, err)
|
||||||
throwFail(t, AssertIs(created, false))
|
throwFail(t, AssertIs(created, false))
|
||||||
throwFail(t, AssertIs(nu.Id, u.Id))
|
throwFail(t, AssertIs(nu.ID, u.ID))
|
||||||
throwFail(t, AssertIs(pk, u.Id))
|
throwFail(t, AssertIs(pk, u.ID))
|
||||||
throwFail(t, AssertIs(nu.Name, name))
|
throwFail(t, AssertIs(nu.Name, name))
|
||||||
|
|
||||||
dORM.Delete(u)
|
dORM.Delete(u)
|
||||||
|
Loading…
Reference in New Issue
Block a user