1
0
mirror of https://github.com/astaxie/beego.git synced 2024-11-25 21:11:29 +00:00

orm: add json & jsonb type support

This commit is contained in:
miraclesu 2016-04-08 21:53:27 +08:00
parent 6da765c465
commit 657744efb1
5 changed files with 124 additions and 7 deletions

View File

@ -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 {

View File

@ -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 {

View File

@ -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.

View File

@ -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
) )
@ -681,3 +683,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)

View File

@ -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 {