Commit c697b980 authored by astaxie's avatar astaxie

enhancement

parent 56aa224a
...@@ -80,7 +80,7 @@ type _dbCache struct { ...@@ -80,7 +80,7 @@ type _dbCache struct {
func (ac *_dbCache) add(name string, al *alias) (added bool) { func (ac *_dbCache) add(name string, al *alias) (added bool) {
ac.mux.Lock() ac.mux.Lock()
defer ac.mux.Unlock() defer ac.mux.Unlock()
if _, ok := ac.cache[name]; ok == false { if _, ok := ac.cache[name]; !ok {
ac.cache[name] = al ac.cache[name] = al
added = true added = true
} }
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
package orm package orm
import ( import (
"errors"
"fmt" "fmt"
"os" "os"
"reflect" "reflect"
...@@ -55,34 +54,34 @@ func registerModel(prefix string, model interface{}) { ...@@ -55,34 +54,34 @@ func registerModel(prefix string, model interface{}) {
os.Exit(2) os.Exit(2)
} }
info := newModelInfo(val) mi := newModelInfo(val)
if info.fields.pk == nil { if mi.fields.pk == nil {
outFor: outFor:
for _, fi := range info.fields.fieldsDB { for _, fi := range mi.fields.fieldsDB {
if strings.ToLower(fi.name) == "id" { if strings.ToLower(fi.name) == "id" {
switch fi.addrValue.Elem().Kind() { switch fi.addrValue.Elem().Kind() {
case reflect.Int, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint32, reflect.Uint64: case reflect.Int, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint32, reflect.Uint64:
fi.auto = true fi.auto = true
fi.pk = true fi.pk = true
info.fields.pk = fi mi.fields.pk = fi
break outFor break outFor
} }
} }
} }
if info.fields.pk == nil { if mi.fields.pk == nil {
fmt.Printf("<orm.RegisterModel> `%s` need a primary key field, default use 'id' if not set\n", name) fmt.Printf("<orm.RegisterModel> `%s` need a primary key field, default use 'id' if not set\n", name)
os.Exit(2) os.Exit(2)
} }
} }
info.table = table mi.table = table
info.pkg = typ.PkgPath() mi.pkg = typ.PkgPath()
info.model = model mi.model = model
info.manual = true mi.manual = true
modelCache.set(table, info) modelCache.set(table, mi)
} }
// boostrap models // boostrap models
...@@ -90,12 +89,10 @@ func bootStrap() { ...@@ -90,12 +89,10 @@ func bootStrap() {
if modelCache.done { if modelCache.done {
return return
} }
var ( var (
err error err error
models map[string]*modelInfo models map[string]*modelInfo
) )
if dataBaseCache.getDefault() == nil { if dataBaseCache.getDefault() == nil {
err = fmt.Errorf("must have one register DataBase alias named `default`") err = fmt.Errorf("must have one register DataBase alias named `default`")
goto end goto end
...@@ -106,14 +103,13 @@ func bootStrap() { ...@@ -106,14 +103,13 @@ func bootStrap() {
for _, fi := range mi.fields.columns { for _, fi := range mi.fields.columns {
if fi.rel || fi.reverse { if fi.rel || fi.reverse {
elm := fi.addrValue.Type().Elem() elm := fi.addrValue.Type().Elem()
switch fi.fieldType { if fi.fieldType == RelReverseMany || fi.fieldType == RelManyToMany {
case RelReverseMany, RelManyToMany:
elm = elm.Elem() elm = elm.Elem()
} }
// check the rel or reverse model already register
name := getFullName(elm) name := getFullName(elm)
mii, ok := modelCache.getByFullName(name) mii, ok := modelCache.getByFullName(name)
if ok == false || mii.pkg != elm.PkgPath() { if !ok || mii.pkg != elm.PkgPath() {
err = fmt.Errorf("can not found rel in field `%s`, `%s` may be miss register", fi.fullName, elm.String()) err = fmt.Errorf("can not found rel in field `%s`, `%s` may be miss register", fi.fullName, elm.String())
goto end goto end
} }
...@@ -122,20 +118,17 @@ func bootStrap() { ...@@ -122,20 +118,17 @@ func bootStrap() {
switch fi.fieldType { switch fi.fieldType {
case RelManyToMany: case RelManyToMany:
if fi.relThrough != "" { if fi.relThrough != "" {
msg := fmt.Sprintf("field `%s` wrong rel_through value `%s`", fi.fullName, fi.relThrough)
if i := strings.LastIndex(fi.relThrough, "."); i != -1 && len(fi.relThrough) > (i+1) { if i := strings.LastIndex(fi.relThrough, "."); i != -1 && len(fi.relThrough) > (i+1) {
pn := fi.relThrough[:i] pn := fi.relThrough[:i]
rmi, ok := modelCache.getByFullName(fi.relThrough) rmi, ok := modelCache.getByFullName(fi.relThrough)
if ok == false || pn != rmi.pkg { if ok == false || pn != rmi.pkg {
err = errors.New(msg + " cannot find table") err = fmt.Errorf("field `%s` wrong rel_through value `%s` cannot find table", fi.fullName, fi.relThrough)
goto end goto end
} }
fi.relThroughModelInfo = rmi fi.relThroughModelInfo = rmi
fi.relTable = rmi.table fi.relTable = rmi.table
} else { } else {
err = errors.New(msg) err = fmt.Errorf("field `%s` wrong rel_through value `%s`", fi.fullName, fi.relThrough)
goto end goto end
} }
} else { } else {
...@@ -143,7 +136,6 @@ func bootStrap() { ...@@ -143,7 +136,6 @@ func bootStrap() {
if fi.relTable != "" { if fi.relTable != "" {
i.table = fi.relTable i.table = fi.relTable
} }
if v := modelCache.set(i.table, i); v != nil { if v := modelCache.set(i.table, i); v != nil {
err = fmt.Errorf("the rel table name `%s` already registered, cannot be use, please change one", fi.relTable) err = fmt.Errorf("the rel table name `%s` already registered, cannot be use, please change one", fi.relTable)
goto end goto end
......
...@@ -104,7 +104,7 @@ type fieldInfo struct { ...@@ -104,7 +104,7 @@ type fieldInfo struct {
mi *modelInfo mi *modelInfo
fieldIndex []int fieldIndex []int
fieldType int fieldType int
dbcol bool dbcol bool // table column fk and onetoone
inModel bool inModel bool
name string name string
fullName string fullName string
...@@ -116,13 +116,13 @@ type fieldInfo struct { ...@@ -116,13 +116,13 @@ type fieldInfo struct {
null bool null bool
index bool index bool
unique bool unique bool
colDefault bool colDefault bool // whether has default tag
initial StrTo initial StrTo // store the default value
size int size int
toText bool toText bool
autoNow bool autoNow bool
autoNowAdd bool autoNowAdd bool
rel bool rel bool // if type equal to RelForeignKey, RelOneToOne, RelManyToMany then true
reverse bool reverse bool
reverseField string reverseField string
reverseFieldInfo *fieldInfo reverseFieldInfo *fieldInfo
...@@ -134,7 +134,7 @@ type fieldInfo struct { ...@@ -134,7 +134,7 @@ type fieldInfo struct {
relModelInfo *modelInfo relModelInfo *modelInfo
digits int digits int
decimals int decimals int
isFielder bool isFielder bool // implement Fielder interface
onDelete string onDelete string
} }
...@@ -265,6 +265,9 @@ checkType: ...@@ -265,6 +265,9 @@ checkType:
} }
} }
// check the rel and reverse type
// rel should Ptr
// reverse should slice []*struct
switch fieldType { switch fieldType {
case RelForeignKey, RelOneToOne, RelReverseOne: case RelForeignKey, RelOneToOne, RelReverseOne:
if field.Kind() != reflect.Ptr { if field.Kind() != reflect.Ptr {
...@@ -403,14 +406,12 @@ checkType: ...@@ -403,14 +406,12 @@ checkType:
if fi.auto || fi.pk { if fi.auto || fi.pk {
if fi.auto { if fi.auto {
switch addrField.Elem().Kind() { switch addrField.Elem().Kind() {
case reflect.Int, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint32, reflect.Uint64: case reflect.Int, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint32, reflect.Uint64:
default: default:
err = fmt.Errorf("auto primary key only support int, int32, int64, uint, uint32, uint64 but found `%s`", addrField.Elem().Kind()) err = fmt.Errorf("auto primary key only support int, int32, int64, uint, uint32, uint64 but found `%s`", addrField.Elem().Kind())
goto end goto end
} }
fi.pk = true fi.pk = true
} }
fi.null = false fi.null = false
...@@ -422,8 +423,8 @@ checkType: ...@@ -422,8 +423,8 @@ checkType:
fi.index = false fi.index = false
} }
// can not set default for these type
if fi.auto || fi.pk || fi.unique || fieldType == TypeTimeField || fieldType == TypeDateField || fieldType == TypeDateTimeField { if fi.auto || fi.pk || fi.unique || fieldType == TypeTimeField || fieldType == TypeDateField || fieldType == TypeDateTimeField {
// can not set default
initial.Clear() initial.Clear()
} }
......
...@@ -107,9 +107,9 @@ func newM2MModelInfo(m1, m2 *modelInfo) (mi *modelInfo) { ...@@ -107,9 +107,9 @@ func newM2MModelInfo(m1, m2 *modelInfo) (mi *modelInfo) {
mi.name = camelString(mi.table) mi.name = camelString(mi.table)
mi.fullName = m1.pkg + "." + mi.name mi.fullName = m1.pkg + "." + mi.name
fa := new(fieldInfo) fa := new(fieldInfo) // pk
f1 := new(fieldInfo) f1 := new(fieldInfo) // m1 table RelForeignKey
f2 := new(fieldInfo) f2 := new(fieldInfo) // m2 table RelForeignKey
fa.fieldType = TypeBigIntegerField fa.fieldType = TypeBigIntegerField
fa.auto = true fa.auto = true
fa.pk = true fa.pk = true
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment