add comments for orm package, done
Showing
14 changed files
with
192 additions
and
0 deletions
| ... | @@ -41,6 +41,7 @@ var ( | ... | @@ -41,6 +41,7 @@ var ( |
| 41 | } | 41 | } |
| 42 | ) | 42 | ) |
| 43 | 43 | ||
| 44 | // model info collection | ||
| 44 | type _modelCache struct { | 45 | type _modelCache struct { |
| 45 | sync.RWMutex | 46 | sync.RWMutex |
| 46 | orders []string | 47 | orders []string |
| ... | @@ -49,6 +50,7 @@ type _modelCache struct { | ... | @@ -49,6 +50,7 @@ type _modelCache struct { |
| 49 | done bool | 50 | done bool |
| 50 | } | 51 | } |
| 51 | 52 | ||
| 53 | // get all model info | ||
| 52 | func (mc *_modelCache) all() map[string]*modelInfo { | 54 | func (mc *_modelCache) all() map[string]*modelInfo { |
| 53 | m := make(map[string]*modelInfo, len(mc.cache)) | 55 | m := make(map[string]*modelInfo, len(mc.cache)) |
| 54 | for k, v := range mc.cache { | 56 | for k, v := range mc.cache { |
| ... | @@ -57,6 +59,7 @@ func (mc *_modelCache) all() map[string]*modelInfo { | ... | @@ -57,6 +59,7 @@ func (mc *_modelCache) all() map[string]*modelInfo { |
| 57 | return m | 59 | return m |
| 58 | } | 60 | } |
| 59 | 61 | ||
| 62 | // get orderd model info | ||
| 60 | func (mc *_modelCache) allOrdered() []*modelInfo { | 63 | func (mc *_modelCache) allOrdered() []*modelInfo { |
| 61 | m := make([]*modelInfo, 0, len(mc.orders)) | 64 | m := make([]*modelInfo, 0, len(mc.orders)) |
| 62 | for _, table := range mc.orders { | 65 | for _, table := range mc.orders { |
| ... | @@ -65,16 +68,19 @@ func (mc *_modelCache) allOrdered() []*modelInfo { | ... | @@ -65,16 +68,19 @@ func (mc *_modelCache) allOrdered() []*modelInfo { |
| 65 | return m | 68 | return m |
| 66 | } | 69 | } |
| 67 | 70 | ||
| 71 | // get model info by table name | ||
| 68 | func (mc *_modelCache) get(table string) (mi *modelInfo, ok bool) { | 72 | func (mc *_modelCache) get(table string) (mi *modelInfo, ok bool) { |
| 69 | mi, ok = mc.cache[table] | 73 | mi, ok = mc.cache[table] |
| 70 | return | 74 | return |
| 71 | } | 75 | } |
| 72 | 76 | ||
| 77 | // get model info by field name | ||
| 73 | func (mc *_modelCache) getByFN(name string) (mi *modelInfo, ok bool) { | 78 | func (mc *_modelCache) getByFN(name string) (mi *modelInfo, ok bool) { |
| 74 | mi, ok = mc.cacheByFN[name] | 79 | mi, ok = mc.cacheByFN[name] |
| 75 | return | 80 | return |
| 76 | } | 81 | } |
| 77 | 82 | ||
| 83 | // set model info to collection | ||
| 78 | func (mc *_modelCache) set(table string, mi *modelInfo) *modelInfo { | 84 | func (mc *_modelCache) set(table string, mi *modelInfo) *modelInfo { |
| 79 | mii := mc.cache[table] | 85 | mii := mc.cache[table] |
| 80 | mc.cache[table] = mi | 86 | mc.cache[table] = mi |
| ... | @@ -85,6 +91,7 @@ func (mc *_modelCache) set(table string, mi *modelInfo) *modelInfo { | ... | @@ -85,6 +91,7 @@ func (mc *_modelCache) set(table string, mi *modelInfo) *modelInfo { |
| 85 | return mii | 91 | return mii |
| 86 | } | 92 | } |
| 87 | 93 | ||
| 94 | // clean all model info. | ||
| 88 | func (mc *_modelCache) clean() { | 95 | func (mc *_modelCache) clean() { |
| 89 | mc.orders = make([]string, 0) | 96 | mc.orders = make([]string, 0) |
| 90 | mc.cache = make(map[string]*modelInfo) | 97 | mc.cache = make(map[string]*modelInfo) | ... | ... |
| ... | @@ -8,6 +8,8 @@ import ( | ... | @@ -8,6 +8,8 @@ import ( |
| 8 | "strings" | 8 | "strings" |
| 9 | ) | 9 | ) |
| 10 | 10 | ||
| 11 | // register models. | ||
| 12 | // prefix means table name prefix. | ||
| 11 | func registerModel(model interface{}, prefix string) { | 13 | func registerModel(model interface{}, prefix string) { |
| 12 | val := reflect.ValueOf(model) | 14 | val := reflect.ValueOf(model) |
| 13 | ind := reflect.Indirect(val) | 15 | ind := reflect.Indirect(val) |
| ... | @@ -67,6 +69,7 @@ func registerModel(model interface{}, prefix string) { | ... | @@ -67,6 +69,7 @@ func registerModel(model interface{}, prefix string) { |
| 67 | modelCache.set(table, info) | 69 | modelCache.set(table, info) |
| 68 | } | 70 | } |
| 69 | 71 | ||
| 72 | // boostrap models | ||
| 70 | func bootStrap() { | 73 | func bootStrap() { |
| 71 | if modelCache.done { | 74 | if modelCache.done { |
| 72 | return | 75 | return |
| ... | @@ -281,6 +284,7 @@ end: | ... | @@ -281,6 +284,7 @@ end: |
| 281 | } | 284 | } |
| 282 | } | 285 | } |
| 283 | 286 | ||
| 287 | // register models | ||
| 284 | func RegisterModel(models ...interface{}) { | 288 | func RegisterModel(models ...interface{}) { |
| 285 | if modelCache.done { | 289 | if modelCache.done { |
| 286 | panic(fmt.Errorf("RegisterModel must be run before BootStrap")) | 290 | panic(fmt.Errorf("RegisterModel must be run before BootStrap")) |
| ... | @@ -302,6 +306,8 @@ func RegisterModelWithPrefix(prefix string, models ...interface{}) { | ... | @@ -302,6 +306,8 @@ func RegisterModelWithPrefix(prefix string, models ...interface{}) { |
| 302 | } | 306 | } |
| 303 | } | 307 | } |
| 304 | 308 | ||
| 309 | // bootrap models. | ||
| 310 | // make all model parsed and can not add more models | ||
| 305 | func BootStrap() { | 311 | func BootStrap() { |
| 306 | if modelCache.done { | 312 | if modelCache.done { |
| 307 | return | 313 | return | ... | ... |
| ... | @@ -9,6 +9,7 @@ import ( | ... | @@ -9,6 +9,7 @@ import ( |
| 9 | 9 | ||
| 10 | var errSkipField = errors.New("skip field") | 10 | var errSkipField = errors.New("skip field") |
| 11 | 11 | ||
| 12 | // field info collection | ||
| 12 | type fields struct { | 13 | type fields struct { |
| 13 | pk *fieldInfo | 14 | pk *fieldInfo |
| 14 | columns map[string]*fieldInfo | 15 | columns map[string]*fieldInfo |
| ... | @@ -23,6 +24,7 @@ type fields struct { | ... | @@ -23,6 +24,7 @@ type fields struct { |
| 23 | dbcols []string | 24 | dbcols []string |
| 24 | } | 25 | } |
| 25 | 26 | ||
| 27 | // add field info | ||
| 26 | func (f *fields) Add(fi *fieldInfo) (added bool) { | 28 | func (f *fields) Add(fi *fieldInfo) (added bool) { |
| 27 | if f.fields[fi.name] == nil && f.columns[fi.column] == nil { | 29 | if f.fields[fi.name] == nil && f.columns[fi.column] == nil { |
| 28 | f.columns[fi.column] = fi | 30 | f.columns[fi.column] = fi |
| ... | @@ -49,14 +51,17 @@ func (f *fields) Add(fi *fieldInfo) (added bool) { | ... | @@ -49,14 +51,17 @@ func (f *fields) Add(fi *fieldInfo) (added bool) { |
| 49 | return true | 51 | return true |
| 50 | } | 52 | } |
| 51 | 53 | ||
| 54 | // get field info by name | ||
| 52 | func (f *fields) GetByName(name string) *fieldInfo { | 55 | func (f *fields) GetByName(name string) *fieldInfo { |
| 53 | return f.fields[name] | 56 | return f.fields[name] |
| 54 | } | 57 | } |
| 55 | 58 | ||
| 59 | // get field info by column name | ||
| 56 | func (f *fields) GetByColumn(column string) *fieldInfo { | 60 | func (f *fields) GetByColumn(column string) *fieldInfo { |
| 57 | return f.columns[column] | 61 | return f.columns[column] |
| 58 | } | 62 | } |
| 59 | 63 | ||
| 64 | // get field info by string, name is prior | ||
| 60 | func (f *fields) GetByAny(name string) (*fieldInfo, bool) { | 65 | func (f *fields) GetByAny(name string) (*fieldInfo, bool) { |
| 61 | if fi, ok := f.fields[name]; ok { | 66 | if fi, ok := f.fields[name]; ok { |
| 62 | return fi, ok | 67 | return fi, ok |
| ... | @@ -70,6 +75,7 @@ func (f *fields) GetByAny(name string) (*fieldInfo, bool) { | ... | @@ -70,6 +75,7 @@ func (f *fields) GetByAny(name string) (*fieldInfo, bool) { |
| 70 | return nil, false | 75 | return nil, false |
| 71 | } | 76 | } |
| 72 | 77 | ||
| 78 | // create new field info collection | ||
| 73 | func newFields() *fields { | 79 | func newFields() *fields { |
| 74 | f := new(fields) | 80 | f := new(fields) |
| 75 | f.fields = make(map[string]*fieldInfo) | 81 | f.fields = make(map[string]*fieldInfo) |
| ... | @@ -79,6 +85,7 @@ func newFields() *fields { | ... | @@ -79,6 +85,7 @@ func newFields() *fields { |
| 79 | return f | 85 | return f |
| 80 | } | 86 | } |
| 81 | 87 | ||
| 88 | // single field info | ||
| 82 | type fieldInfo struct { | 89 | type fieldInfo struct { |
| 83 | mi *modelInfo | 90 | mi *modelInfo |
| 84 | fieldIndex int | 91 | fieldIndex int |
| ... | @@ -115,6 +122,7 @@ type fieldInfo struct { | ... | @@ -115,6 +122,7 @@ type fieldInfo struct { |
| 115 | onDelete string | 122 | onDelete string |
| 116 | } | 123 | } |
| 117 | 124 | ||
| 125 | // new field info | ||
| 118 | func newFieldInfo(mi *modelInfo, field reflect.Value, sf reflect.StructField) (fi *fieldInfo, err error) { | 126 | func newFieldInfo(mi *modelInfo, field reflect.Value, sf reflect.StructField) (fi *fieldInfo, err error) { |
| 119 | var ( | 127 | var ( |
| 120 | tag string | 128 | tag string | ... | ... |
| ... | @@ -7,6 +7,7 @@ import ( | ... | @@ -7,6 +7,7 @@ import ( |
| 7 | "reflect" | 7 | "reflect" |
| 8 | ) | 8 | ) |
| 9 | 9 | ||
| 10 | // single model info | ||
| 10 | type modelInfo struct { | 11 | type modelInfo struct { |
| 11 | pkg string | 12 | pkg string |
| 12 | name string | 13 | name string |
| ... | @@ -20,6 +21,7 @@ type modelInfo struct { | ... | @@ -20,6 +21,7 @@ type modelInfo struct { |
| 20 | isThrough bool | 21 | isThrough bool |
| 21 | } | 22 | } |
| 22 | 23 | ||
| 24 | // new model info | ||
| 23 | func newModelInfo(val reflect.Value) (info *modelInfo) { | 25 | func newModelInfo(val reflect.Value) (info *modelInfo) { |
| 24 | var ( | 26 | var ( |
| 25 | err error | 27 | err error |
| ... | @@ -79,6 +81,8 @@ func newModelInfo(val reflect.Value) (info *modelInfo) { | ... | @@ -79,6 +81,8 @@ func newModelInfo(val reflect.Value) (info *modelInfo) { |
| 79 | return | 81 | return |
| 80 | } | 82 | } |
| 81 | 83 | ||
| 84 | // combine related model info to new model info. | ||
| 85 | // prepare for relation models query. | ||
| 82 | func newM2MModelInfo(m1, m2 *modelInfo) (info *modelInfo) { | 86 | func newM2MModelInfo(m1, m2 *modelInfo) (info *modelInfo) { |
| 83 | info = new(modelInfo) | 87 | info = new(modelInfo) |
| 84 | info.fields = newFields() | 88 | info.fields = newFields() | ... | ... |
| ... | @@ -7,10 +7,12 @@ import ( | ... | @@ -7,10 +7,12 @@ import ( |
| 7 | "time" | 7 | "time" |
| 8 | ) | 8 | ) |
| 9 | 9 | ||
| 10 | // get reflect.Type name with package path. | ||
| 10 | func getFullName(typ reflect.Type) string { | 11 | func getFullName(typ reflect.Type) string { |
| 11 | return typ.PkgPath() + "." + typ.Name() | 12 | return typ.PkgPath() + "." + typ.Name() |
| 12 | } | 13 | } |
| 13 | 14 | ||
| 15 | // get table name. method, or field name. auto snaked. | ||
| 14 | func getTableName(val reflect.Value) string { | 16 | func getTableName(val reflect.Value) string { |
| 15 | ind := reflect.Indirect(val) | 17 | ind := reflect.Indirect(val) |
| 16 | fun := val.MethodByName("TableName") | 18 | fun := val.MethodByName("TableName") |
| ... | @@ -26,6 +28,7 @@ func getTableName(val reflect.Value) string { | ... | @@ -26,6 +28,7 @@ func getTableName(val reflect.Value) string { |
| 26 | return snakeString(ind.Type().Name()) | 28 | return snakeString(ind.Type().Name()) |
| 27 | } | 29 | } |
| 28 | 30 | ||
| 31 | // get table engine, mysiam or innodb. | ||
| 29 | func getTableEngine(val reflect.Value) string { | 32 | func getTableEngine(val reflect.Value) string { |
| 30 | fun := val.MethodByName("TableEngine") | 33 | fun := val.MethodByName("TableEngine") |
| 31 | if fun.IsValid() { | 34 | if fun.IsValid() { |
| ... | @@ -40,6 +43,7 @@ func getTableEngine(val reflect.Value) string { | ... | @@ -40,6 +43,7 @@ func getTableEngine(val reflect.Value) string { |
| 40 | return "" | 43 | return "" |
| 41 | } | 44 | } |
| 42 | 45 | ||
| 46 | // get table index from method. | ||
| 43 | func getTableIndex(val reflect.Value) [][]string { | 47 | func getTableIndex(val reflect.Value) [][]string { |
| 44 | fun := val.MethodByName("TableIndex") | 48 | fun := val.MethodByName("TableIndex") |
| 45 | if fun.IsValid() { | 49 | if fun.IsValid() { |
| ... | @@ -56,6 +60,7 @@ func getTableIndex(val reflect.Value) [][]string { | ... | @@ -56,6 +60,7 @@ func getTableIndex(val reflect.Value) [][]string { |
| 56 | return nil | 60 | return nil |
| 57 | } | 61 | } |
| 58 | 62 | ||
| 63 | // get table unique from method | ||
| 59 | func getTableUnique(val reflect.Value) [][]string { | 64 | func getTableUnique(val reflect.Value) [][]string { |
| 60 | fun := val.MethodByName("TableUnique") | 65 | fun := val.MethodByName("TableUnique") |
| 61 | if fun.IsValid() { | 66 | if fun.IsValid() { |
| ... | @@ -72,6 +77,7 @@ func getTableUnique(val reflect.Value) [][]string { | ... | @@ -72,6 +77,7 @@ func getTableUnique(val reflect.Value) [][]string { |
| 72 | return nil | 77 | return nil |
| 73 | } | 78 | } |
| 74 | 79 | ||
| 80 | // get snaked column name | ||
| 75 | func getColumnName(ft int, addrField reflect.Value, sf reflect.StructField, col string) string { | 81 | func getColumnName(ft int, addrField reflect.Value, sf reflect.StructField, col string) string { |
| 76 | col = strings.ToLower(col) | 82 | col = strings.ToLower(col) |
| 77 | column := col | 83 | column := col |
| ... | @@ -89,6 +95,7 @@ func getColumnName(ft int, addrField reflect.Value, sf reflect.StructField, col | ... | @@ -89,6 +95,7 @@ func getColumnName(ft int, addrField reflect.Value, sf reflect.StructField, col |
| 89 | return column | 95 | return column |
| 90 | } | 96 | } |
| 91 | 97 | ||
| 98 | // return field type as type constant from reflect.Value | ||
| 92 | func getFieldType(val reflect.Value) (ft int, err error) { | 99 | func getFieldType(val reflect.Value) (ft int, err error) { |
| 93 | elm := reflect.Indirect(val) | 100 | elm := reflect.Indirect(val) |
| 94 | switch elm.Kind() { | 101 | switch elm.Kind() { |
| ... | @@ -128,6 +135,7 @@ func getFieldType(val reflect.Value) (ft int, err error) { | ... | @@ -128,6 +135,7 @@ func getFieldType(val reflect.Value) (ft int, err error) { |
| 128 | return | 135 | return |
| 129 | } | 136 | } |
| 130 | 137 | ||
| 138 | // parse struct tag string | ||
| 131 | func parseStructTag(data string, attrs *map[string]bool, tags *map[string]string) { | 139 | func parseStructTag(data string, attrs *map[string]bool, tags *map[string]string) { |
| 132 | attr := make(map[string]bool) | 140 | attr := make(map[string]bool) |
| 133 | tag := make(map[string]string) | 141 | tag := make(map[string]string) | ... | ... |
| ... | @@ -40,6 +40,7 @@ type orm struct { | ... | @@ -40,6 +40,7 @@ type orm struct { |
| 40 | 40 | ||
| 41 | var _ Ormer = new(orm) | 41 | var _ Ormer = new(orm) |
| 42 | 42 | ||
| 43 | // get model info and model reflect value | ||
| 43 | func (o *orm) getMiInd(md interface{}, needPtr bool) (mi *modelInfo, ind reflect.Value) { | 44 | func (o *orm) getMiInd(md interface{}, needPtr bool) (mi *modelInfo, ind reflect.Value) { |
| 44 | val := reflect.ValueOf(md) | 45 | val := reflect.ValueOf(md) |
| 45 | ind = reflect.Indirect(val) | 46 | ind = reflect.Indirect(val) |
| ... | @@ -54,6 +55,7 @@ func (o *orm) getMiInd(md interface{}, needPtr bool) (mi *modelInfo, ind reflect | ... | @@ -54,6 +55,7 @@ func (o *orm) getMiInd(md interface{}, needPtr bool) (mi *modelInfo, ind reflect |
| 54 | panic(fmt.Errorf("<Ormer> table: `%s` not found, maybe not RegisterModel", name)) | 55 | panic(fmt.Errorf("<Ormer> table: `%s` not found, maybe not RegisterModel", name)) |
| 55 | } | 56 | } |
| 56 | 57 | ||
| 58 | // get field info from model info by given field name | ||
| 57 | func (o *orm) getFieldInfo(mi *modelInfo, name string) *fieldInfo { | 59 | func (o *orm) getFieldInfo(mi *modelInfo, name string) *fieldInfo { |
| 58 | fi, ok := mi.fields.GetByAny(name) | 60 | fi, ok := mi.fields.GetByAny(name) |
| 59 | if !ok { | 61 | if !ok { |
| ... | @@ -62,6 +64,7 @@ func (o *orm) getFieldInfo(mi *modelInfo, name string) *fieldInfo { | ... | @@ -62,6 +64,7 @@ func (o *orm) getFieldInfo(mi *modelInfo, name string) *fieldInfo { |
| 62 | return fi | 64 | return fi |
| 63 | } | 65 | } |
| 64 | 66 | ||
| 67 | // read data to model | ||
| 65 | func (o *orm) Read(md interface{}, cols ...string) error { | 68 | func (o *orm) Read(md interface{}, cols ...string) error { |
| 66 | mi, ind := o.getMiInd(md, true) | 69 | mi, ind := o.getMiInd(md, true) |
| 67 | err := o.alias.DbBaser.Read(o.db, mi, ind, o.alias.TZ, cols) | 70 | err := o.alias.DbBaser.Read(o.db, mi, ind, o.alias.TZ, cols) |
| ... | @@ -71,6 +74,7 @@ func (o *orm) Read(md interface{}, cols ...string) error { | ... | @@ -71,6 +74,7 @@ func (o *orm) Read(md interface{}, cols ...string) error { |
| 71 | return nil | 74 | return nil |
| 72 | } | 75 | } |
| 73 | 76 | ||
| 77 | // insert model data to database | ||
| 74 | func (o *orm) Insert(md interface{}) (int64, error) { | 78 | func (o *orm) Insert(md interface{}) (int64, error) { |
| 75 | mi, ind := o.getMiInd(md, true) | 79 | mi, ind := o.getMiInd(md, true) |
| 76 | id, err := o.alias.DbBaser.Insert(o.db, mi, ind, o.alias.TZ) | 80 | id, err := o.alias.DbBaser.Insert(o.db, mi, ind, o.alias.TZ) |
| ... | @@ -83,6 +87,7 @@ func (o *orm) Insert(md interface{}) (int64, error) { | ... | @@ -83,6 +87,7 @@ func (o *orm) Insert(md interface{}) (int64, error) { |
| 83 | return id, nil | 87 | return id, nil |
| 84 | } | 88 | } |
| 85 | 89 | ||
| 90 | // set auto pk field | ||
| 86 | func (o *orm) setPk(mi *modelInfo, ind reflect.Value, id int64) { | 91 | func (o *orm) setPk(mi *modelInfo, ind reflect.Value, id int64) { |
| 87 | if mi.fields.pk.auto { | 92 | if mi.fields.pk.auto { |
| 88 | if mi.fields.pk.fieldType&IsPostiveIntegerField > 0 { | 93 | if mi.fields.pk.fieldType&IsPostiveIntegerField > 0 { |
| ... | @@ -93,6 +98,7 @@ func (o *orm) setPk(mi *modelInfo, ind reflect.Value, id int64) { | ... | @@ -93,6 +98,7 @@ func (o *orm) setPk(mi *modelInfo, ind reflect.Value, id int64) { |
| 93 | } | 98 | } |
| 94 | } | 99 | } |
| 95 | 100 | ||
| 101 | // insert some models to database | ||
| 96 | func (o *orm) InsertMulti(bulk int, mds interface{}) (int64, error) { | 102 | func (o *orm) InsertMulti(bulk int, mds interface{}) (int64, error) { |
| 97 | var cnt int64 | 103 | var cnt int64 |
| 98 | 104 | ||
| ... | @@ -127,6 +133,8 @@ func (o *orm) InsertMulti(bulk int, mds interface{}) (int64, error) { | ... | @@ -127,6 +133,8 @@ func (o *orm) InsertMulti(bulk int, mds interface{}) (int64, error) { |
| 127 | return cnt, nil | 133 | return cnt, nil |
| 128 | } | 134 | } |
| 129 | 135 | ||
| 136 | // update model to database. | ||
| 137 | // cols set the columns those want to update. | ||
| 130 | func (o *orm) Update(md interface{}, cols ...string) (int64, error) { | 138 | func (o *orm) Update(md interface{}, cols ...string) (int64, error) { |
| 131 | mi, ind := o.getMiInd(md, true) | 139 | mi, ind := o.getMiInd(md, true) |
| 132 | num, err := o.alias.DbBaser.Update(o.db, mi, ind, o.alias.TZ, cols) | 140 | num, err := o.alias.DbBaser.Update(o.db, mi, ind, o.alias.TZ, cols) |
| ... | @@ -136,6 +144,7 @@ func (o *orm) Update(md interface{}, cols ...string) (int64, error) { | ... | @@ -136,6 +144,7 @@ func (o *orm) Update(md interface{}, cols ...string) (int64, error) { |
| 136 | return num, nil | 144 | return num, nil |
| 137 | } | 145 | } |
| 138 | 146 | ||
| 147 | // delete model in database | ||
| 139 | func (o *orm) Delete(md interface{}) (int64, error) { | 148 | func (o *orm) Delete(md interface{}) (int64, error) { |
| 140 | mi, ind := o.getMiInd(md, true) | 149 | mi, ind := o.getMiInd(md, true) |
| 141 | num, err := o.alias.DbBaser.Delete(o.db, mi, ind, o.alias.TZ) | 150 | num, err := o.alias.DbBaser.Delete(o.db, mi, ind, o.alias.TZ) |
| ... | @@ -148,6 +157,7 @@ func (o *orm) Delete(md interface{}) (int64, error) { | ... | @@ -148,6 +157,7 @@ func (o *orm) Delete(md interface{}) (int64, error) { |
| 148 | return num, nil | 157 | return num, nil |
| 149 | } | 158 | } |
| 150 | 159 | ||
| 160 | // create a models to models queryer | ||
| 151 | func (o *orm) QueryM2M(md interface{}, name string) QueryM2Mer { | 161 | func (o *orm) QueryM2M(md interface{}, name string) QueryM2Mer { |
| 152 | mi, ind := o.getMiInd(md, true) | 162 | mi, ind := o.getMiInd(md, true) |
| 153 | fi := o.getFieldInfo(mi, name) | 163 | fi := o.getFieldInfo(mi, name) |
| ... | @@ -162,6 +172,14 @@ func (o *orm) QueryM2M(md interface{}, name string) QueryM2Mer { | ... | @@ -162,6 +172,14 @@ func (o *orm) QueryM2M(md interface{}, name string) QueryM2Mer { |
| 162 | return newQueryM2M(md, o, mi, fi, ind) | 172 | return newQueryM2M(md, o, mi, fi, ind) |
| 163 | } | 173 | } |
| 164 | 174 | ||
| 175 | // load related models to md model. | ||
| 176 | // args are limit, offset int and order string. | ||
| 177 | // | ||
| 178 | // example: | ||
| 179 | // orm.LoadRelated(post,"Tags") | ||
| 180 | // for _,tag := range post.Tags{...} | ||
| 181 | // | ||
| 182 | // make sure the relation is defined in model struct tags. | ||
| 165 | func (o *orm) LoadRelated(md interface{}, name string, args ...interface{}) (int64, error) { | 183 | func (o *orm) LoadRelated(md interface{}, name string, args ...interface{}) (int64, error) { |
| 166 | _, fi, ind, qseter := o.queryRelated(md, name) | 184 | _, fi, ind, qseter := o.queryRelated(md, name) |
| 167 | 185 | ||
| ... | @@ -223,12 +241,19 @@ func (o *orm) LoadRelated(md interface{}, name string, args ...interface{}) (int | ... | @@ -223,12 +241,19 @@ func (o *orm) LoadRelated(md interface{}, name string, args ...interface{}) (int |
| 223 | return nums, err | 241 | return nums, err |
| 224 | } | 242 | } |
| 225 | 243 | ||
| 244 | // return a QuerySeter for related models to md model. | ||
| 245 | // it can do all, update, delete in QuerySeter. | ||
| 246 | // example: | ||
| 247 | // qs := orm.QueryRelated(post,"Tag") | ||
| 248 | // qs.All(&[]*Tag{}) | ||
| 249 | // | ||
| 226 | func (o *orm) QueryRelated(md interface{}, name string) QuerySeter { | 250 | func (o *orm) QueryRelated(md interface{}, name string) QuerySeter { |
| 227 | // is this api needed ? | 251 | // is this api needed ? |
| 228 | _, _, _, qs := o.queryRelated(md, name) | 252 | _, _, _, qs := o.queryRelated(md, name) |
| 229 | return qs | 253 | return qs |
| 230 | } | 254 | } |
| 231 | 255 | ||
| 256 | // get QuerySeter for related models to md model | ||
| 232 | func (o *orm) queryRelated(md interface{}, name string) (*modelInfo, *fieldInfo, reflect.Value, QuerySeter) { | 257 | func (o *orm) queryRelated(md interface{}, name string) (*modelInfo, *fieldInfo, reflect.Value, QuerySeter) { |
| 233 | mi, ind := o.getMiInd(md, true) | 258 | mi, ind := o.getMiInd(md, true) |
| 234 | fi := o.getFieldInfo(mi, name) | 259 | fi := o.getFieldInfo(mi, name) |
| ... | @@ -260,6 +285,7 @@ func (o *orm) queryRelated(md interface{}, name string) (*modelInfo, *fieldInfo, | ... | @@ -260,6 +285,7 @@ func (o *orm) queryRelated(md interface{}, name string) (*modelInfo, *fieldInfo, |
| 260 | return mi, fi, ind, qs | 285 | return mi, fi, ind, qs |
| 261 | } | 286 | } |
| 262 | 287 | ||
| 288 | // get reverse relation QuerySeter | ||
| 263 | func (o *orm) getReverseQs(md interface{}, mi *modelInfo, fi *fieldInfo) *querySet { | 289 | func (o *orm) getReverseQs(md interface{}, mi *modelInfo, fi *fieldInfo) *querySet { |
| 264 | switch fi.fieldType { | 290 | switch fi.fieldType { |
| 265 | case RelReverseOne, RelReverseMany: | 291 | case RelReverseOne, RelReverseMany: |
| ... | @@ -280,6 +306,7 @@ func (o *orm) getReverseQs(md interface{}, mi *modelInfo, fi *fieldInfo) *queryS | ... | @@ -280,6 +306,7 @@ func (o *orm) getReverseQs(md interface{}, mi *modelInfo, fi *fieldInfo) *queryS |
| 280 | return q | 306 | return q |
| 281 | } | 307 | } |
| 282 | 308 | ||
| 309 | // get relation QuerySeter | ||
| 283 | func (o *orm) getRelQs(md interface{}, mi *modelInfo, fi *fieldInfo) *querySet { | 310 | func (o *orm) getRelQs(md interface{}, mi *modelInfo, fi *fieldInfo) *querySet { |
| 284 | switch fi.fieldType { | 311 | switch fi.fieldType { |
| 285 | case RelOneToOne, RelForeignKey, RelManyToMany: | 312 | case RelOneToOne, RelForeignKey, RelManyToMany: |
| ... | @@ -299,6 +326,9 @@ func (o *orm) getRelQs(md interface{}, mi *modelInfo, fi *fieldInfo) *querySet { | ... | @@ -299,6 +326,9 @@ func (o *orm) getRelQs(md interface{}, mi *modelInfo, fi *fieldInfo) *querySet { |
| 299 | return q | 326 | return q |
| 300 | } | 327 | } |
| 301 | 328 | ||
| 329 | // return a QuerySeter for table operations. | ||
| 330 | // table name can be string or struct. | ||
| 331 | // e.g. QueryTable("user"), QueryTable(&user{}) or QueryTable((*User)(nil)), | ||
| 302 | func (o *orm) QueryTable(ptrStructOrTableName interface{}) (qs QuerySeter) { | 332 | func (o *orm) QueryTable(ptrStructOrTableName interface{}) (qs QuerySeter) { |
| 303 | name := "" | 333 | name := "" |
| 304 | if table, ok := ptrStructOrTableName.(string); ok { | 334 | if table, ok := ptrStructOrTableName.(string); ok { |
| ... | @@ -318,6 +348,7 @@ func (o *orm) QueryTable(ptrStructOrTableName interface{}) (qs QuerySeter) { | ... | @@ -318,6 +348,7 @@ func (o *orm) QueryTable(ptrStructOrTableName interface{}) (qs QuerySeter) { |
| 318 | return | 348 | return |
| 319 | } | 349 | } |
| 320 | 350 | ||
| 351 | // switch to another registered database driver by given name. | ||
| 321 | func (o *orm) Using(name string) error { | 352 | func (o *orm) Using(name string) error { |
| 322 | if o.isTx { | 353 | if o.isTx { |
| 323 | panic(fmt.Errorf("<Ormer.Using> transaction has been start, cannot change db")) | 354 | panic(fmt.Errorf("<Ormer.Using> transaction has been start, cannot change db")) |
| ... | @@ -335,6 +366,7 @@ func (o *orm) Using(name string) error { | ... | @@ -335,6 +366,7 @@ func (o *orm) Using(name string) error { |
| 335 | return nil | 366 | return nil |
| 336 | } | 367 | } |
| 337 | 368 | ||
| 369 | // begin transaction | ||
| 338 | func (o *orm) Begin() error { | 370 | func (o *orm) Begin() error { |
| 339 | if o.isTx { | 371 | if o.isTx { |
| 340 | return ErrTxHasBegan | 372 | return ErrTxHasBegan |
| ... | @@ -353,6 +385,7 @@ func (o *orm) Begin() error { | ... | @@ -353,6 +385,7 @@ func (o *orm) Begin() error { |
| 353 | return nil | 385 | return nil |
| 354 | } | 386 | } |
| 355 | 387 | ||
| 388 | // commit transaction | ||
| 356 | func (o *orm) Commit() error { | 389 | func (o *orm) Commit() error { |
| 357 | if o.isTx == false { | 390 | if o.isTx == false { |
| 358 | return ErrTxDone | 391 | return ErrTxDone |
| ... | @@ -367,6 +400,7 @@ func (o *orm) Commit() error { | ... | @@ -367,6 +400,7 @@ func (o *orm) Commit() error { |
| 367 | return err | 400 | return err |
| 368 | } | 401 | } |
| 369 | 402 | ||
| 403 | // rollback transaction | ||
| 370 | func (o *orm) Rollback() error { | 404 | func (o *orm) Rollback() error { |
| 371 | if o.isTx == false { | 405 | if o.isTx == false { |
| 372 | return ErrTxDone | 406 | return ErrTxDone |
| ... | @@ -381,14 +415,17 @@ func (o *orm) Rollback() error { | ... | @@ -381,14 +415,17 @@ func (o *orm) Rollback() error { |
| 381 | return err | 415 | return err |
| 382 | } | 416 | } |
| 383 | 417 | ||
| 418 | // return a raw query seter for raw sql string. | ||
| 384 | func (o *orm) Raw(query string, args ...interface{}) RawSeter { | 419 | func (o *orm) Raw(query string, args ...interface{}) RawSeter { |
| 385 | return newRawSet(o, query, args) | 420 | return newRawSet(o, query, args) |
| 386 | } | 421 | } |
| 387 | 422 | ||
| 423 | // return current using database Driver | ||
| 388 | func (o *orm) Driver() Driver { | 424 | func (o *orm) Driver() Driver { |
| 389 | return driver(o.alias.Name) | 425 | return driver(o.alias.Name) |
| 390 | } | 426 | } |
| 391 | 427 | ||
| 428 | // create new orm | ||
| 392 | func NewOrm() Ormer { | 429 | func NewOrm() Ormer { |
| 393 | BootStrap() // execute only once | 430 | BootStrap() // execute only once |
| 394 | 431 | ... | ... |
| ... | @@ -18,15 +18,19 @@ type condValue struct { | ... | @@ -18,15 +18,19 @@ type condValue struct { |
| 18 | isCond bool | 18 | isCond bool |
| 19 | } | 19 | } |
| 20 | 20 | ||
| 21 | // condition struct. | ||
| 22 | // work for WHERE conditions. | ||
| 21 | type Condition struct { | 23 | type Condition struct { |
| 22 | params []condValue | 24 | params []condValue |
| 23 | } | 25 | } |
| 24 | 26 | ||
| 27 | // return new condition struct | ||
| 25 | func NewCondition() *Condition { | 28 | func NewCondition() *Condition { |
| 26 | c := &Condition{} | 29 | c := &Condition{} |
| 27 | return c | 30 | return c |
| 28 | } | 31 | } |
| 29 | 32 | ||
| 33 | // add expression to condition | ||
| 30 | func (c Condition) And(expr string, args ...interface{}) *Condition { | 34 | func (c Condition) And(expr string, args ...interface{}) *Condition { |
| 31 | if expr == "" || len(args) == 0 { | 35 | if expr == "" || len(args) == 0 { |
| 32 | panic(fmt.Errorf("<Condition.And> args cannot empty")) | 36 | panic(fmt.Errorf("<Condition.And> args cannot empty")) |
| ... | @@ -35,6 +39,7 @@ func (c Condition) And(expr string, args ...interface{}) *Condition { | ... | @@ -35,6 +39,7 @@ func (c Condition) And(expr string, args ...interface{}) *Condition { |
| 35 | return &c | 39 | return &c |
| 36 | } | 40 | } |
| 37 | 41 | ||
| 42 | // add NOT expression to condition | ||
| 38 | func (c Condition) AndNot(expr string, args ...interface{}) *Condition { | 43 | func (c Condition) AndNot(expr string, args ...interface{}) *Condition { |
| 39 | if expr == "" || len(args) == 0 { | 44 | if expr == "" || len(args) == 0 { |
| 40 | panic(fmt.Errorf("<Condition.AndNot> args cannot empty")) | 45 | panic(fmt.Errorf("<Condition.AndNot> args cannot empty")) |
| ... | @@ -43,6 +48,7 @@ func (c Condition) AndNot(expr string, args ...interface{}) *Condition { | ... | @@ -43,6 +48,7 @@ func (c Condition) AndNot(expr string, args ...interface{}) *Condition { |
| 43 | return &c | 48 | return &c |
| 44 | } | 49 | } |
| 45 | 50 | ||
| 51 | // combine a condition to current condition | ||
| 46 | func (c *Condition) AndCond(cond *Condition) *Condition { | 52 | func (c *Condition) AndCond(cond *Condition) *Condition { |
| 47 | c = c.clone() | 53 | c = c.clone() |
| 48 | if c == cond { | 54 | if c == cond { |
| ... | @@ -54,6 +60,7 @@ func (c *Condition) AndCond(cond *Condition) *Condition { | ... | @@ -54,6 +60,7 @@ func (c *Condition) AndCond(cond *Condition) *Condition { |
| 54 | return c | 60 | return c |
| 55 | } | 61 | } |
| 56 | 62 | ||
| 63 | // add OR expression to condition | ||
| 57 | func (c Condition) Or(expr string, args ...interface{}) *Condition { | 64 | func (c Condition) Or(expr string, args ...interface{}) *Condition { |
| 58 | if expr == "" || len(args) == 0 { | 65 | if expr == "" || len(args) == 0 { |
| 59 | panic(fmt.Errorf("<Condition.Or> args cannot empty")) | 66 | panic(fmt.Errorf("<Condition.Or> args cannot empty")) |
| ... | @@ -62,6 +69,7 @@ func (c Condition) Or(expr string, args ...interface{}) *Condition { | ... | @@ -62,6 +69,7 @@ func (c Condition) Or(expr string, args ...interface{}) *Condition { |
| 62 | return &c | 69 | return &c |
| 63 | } | 70 | } |
| 64 | 71 | ||
| 72 | // add OR NOT expression to condition | ||
| 65 | func (c Condition) OrNot(expr string, args ...interface{}) *Condition { | 73 | func (c Condition) OrNot(expr string, args ...interface{}) *Condition { |
| 66 | if expr == "" || len(args) == 0 { | 74 | if expr == "" || len(args) == 0 { |
| 67 | panic(fmt.Errorf("<Condition.OrNot> args cannot empty")) | 75 | panic(fmt.Errorf("<Condition.OrNot> args cannot empty")) |
| ... | @@ -70,6 +78,7 @@ func (c Condition) OrNot(expr string, args ...interface{}) *Condition { | ... | @@ -70,6 +78,7 @@ func (c Condition) OrNot(expr string, args ...interface{}) *Condition { |
| 70 | return &c | 78 | return &c |
| 71 | } | 79 | } |
| 72 | 80 | ||
| 81 | // combine a OR condition to current condition | ||
| 73 | func (c *Condition) OrCond(cond *Condition) *Condition { | 82 | func (c *Condition) OrCond(cond *Condition) *Condition { |
| 74 | c = c.clone() | 83 | c = c.clone() |
| 75 | if c == cond { | 84 | if c == cond { |
| ... | @@ -81,10 +90,12 @@ func (c *Condition) OrCond(cond *Condition) *Condition { | ... | @@ -81,10 +90,12 @@ func (c *Condition) OrCond(cond *Condition) *Condition { |
| 81 | return c | 90 | return c |
| 82 | } | 91 | } |
| 83 | 92 | ||
| 93 | // check the condition arguments are empty or not. | ||
| 84 | func (c *Condition) IsEmpty() bool { | 94 | func (c *Condition) IsEmpty() bool { |
| 85 | return len(c.params) == 0 | 95 | return len(c.params) == 0 |
| 86 | } | 96 | } |
| 87 | 97 | ||
| 98 | // clone a condition | ||
| 88 | func (c Condition) clone() *Condition { | 99 | func (c Condition) clone() *Condition { |
| 89 | return &c | 100 | return &c |
| 90 | } | 101 | } | ... | ... |
| ... | @@ -13,6 +13,7 @@ type Log struct { | ... | @@ -13,6 +13,7 @@ type Log struct { |
| 13 | *log.Logger | 13 | *log.Logger |
| 14 | } | 14 | } |
| 15 | 15 | ||
| 16 | // set io.Writer to create a Logger. | ||
| 16 | func NewLog(out io.Writer) *Log { | 17 | func NewLog(out io.Writer) *Log { |
| 17 | d := new(Log) | 18 | d := new(Log) |
| 18 | d.Logger = log.New(out, "[ORM]", 1e9) | 19 | d.Logger = log.New(out, "[ORM]", 1e9) |
| ... | @@ -40,6 +41,8 @@ func debugLogQueies(alias *alias, operaton, query string, t time.Time, err error | ... | @@ -40,6 +41,8 @@ func debugLogQueies(alias *alias, operaton, query string, t time.Time, err error |
| 40 | DebugLog.Println(con) | 41 | DebugLog.Println(con) |
| 41 | } | 42 | } |
| 42 | 43 | ||
| 44 | // statement query logger struct. | ||
| 45 | // if dev mode, use stmtQueryLog, or use stmtQuerier. | ||
| 43 | type stmtQueryLog struct { | 46 | type stmtQueryLog struct { |
| 44 | alias *alias | 47 | alias *alias |
| 45 | query string | 48 | query string |
| ... | @@ -84,6 +87,8 @@ func newStmtQueryLog(alias *alias, stmt stmtQuerier, query string) stmtQuerier { | ... | @@ -84,6 +87,8 @@ func newStmtQueryLog(alias *alias, stmt stmtQuerier, query string) stmtQuerier { |
| 84 | return d | 87 | return d |
| 85 | } | 88 | } |
| 86 | 89 | ||
| 90 | // database query logger struct. | ||
| 91 | // if dev mode, use dbQueryLog, or use dbQuerier. | ||
| 87 | type dbQueryLog struct { | 92 | type dbQueryLog struct { |
| 88 | alias *alias | 93 | alias *alias |
| 89 | db dbQuerier | 94 | db dbQuerier | ... | ... |
| ... | @@ -5,6 +5,7 @@ import ( | ... | @@ -5,6 +5,7 @@ import ( |
| 5 | "reflect" | 5 | "reflect" |
| 6 | ) | 6 | ) |
| 7 | 7 | ||
| 8 | // an insert queryer struct | ||
| 8 | type insertSet struct { | 9 | type insertSet struct { |
| 9 | mi *modelInfo | 10 | mi *modelInfo |
| 10 | orm *orm | 11 | orm *orm |
| ... | @@ -14,6 +15,7 @@ type insertSet struct { | ... | @@ -14,6 +15,7 @@ type insertSet struct { |
| 14 | 15 | ||
| 15 | var _ Inserter = new(insertSet) | 16 | var _ Inserter = new(insertSet) |
| 16 | 17 | ||
| 18 | // insert model ignore it's registered or not. | ||
| 17 | func (o *insertSet) Insert(md interface{}) (int64, error) { | 19 | func (o *insertSet) Insert(md interface{}) (int64, error) { |
| 18 | if o.closed { | 20 | if o.closed { |
| 19 | return 0, ErrStmtClosed | 21 | return 0, ErrStmtClosed |
| ... | @@ -44,6 +46,7 @@ func (o *insertSet) Insert(md interface{}) (int64, error) { | ... | @@ -44,6 +46,7 @@ func (o *insertSet) Insert(md interface{}) (int64, error) { |
| 44 | return id, nil | 46 | return id, nil |
| 45 | } | 47 | } |
| 46 | 48 | ||
| 49 | // close insert queryer statement | ||
| 47 | func (o *insertSet) Close() error { | 50 | func (o *insertSet) Close() error { |
| 48 | if o.closed { | 51 | if o.closed { |
| 49 | return ErrStmtClosed | 52 | return ErrStmtClosed |
| ... | @@ -52,6 +55,7 @@ func (o *insertSet) Close() error { | ... | @@ -52,6 +55,7 @@ func (o *insertSet) Close() error { |
| 52 | return o.stmt.Close() | 55 | return o.stmt.Close() |
| 53 | } | 56 | } |
| 54 | 57 | ||
| 58 | // create new insert queryer. | ||
| 55 | func newInsertSet(orm *orm, mi *modelInfo) (Inserter, error) { | 59 | func newInsertSet(orm *orm, mi *modelInfo) (Inserter, error) { |
| 56 | bi := new(insertSet) | 60 | bi := new(insertSet) |
| 57 | bi.orm = orm | 61 | bi.orm = orm | ... | ... |
| ... | @@ -4,6 +4,7 @@ import ( | ... | @@ -4,6 +4,7 @@ import ( |
| 4 | "reflect" | 4 | "reflect" |
| 5 | ) | 5 | ) |
| 6 | 6 | ||
| 7 | // model to model struct | ||
| 7 | type queryM2M struct { | 8 | type queryM2M struct { |
| 8 | md interface{} | 9 | md interface{} |
| 9 | mi *modelInfo | 10 | mi *modelInfo |
| ... | @@ -12,6 +13,13 @@ type queryM2M struct { | ... | @@ -12,6 +13,13 @@ type queryM2M struct { |
| 12 | ind reflect.Value | 13 | ind reflect.Value |
| 13 | } | 14 | } |
| 14 | 15 | ||
| 16 | // add models to origin models when creating queryM2M. | ||
| 17 | // example: | ||
| 18 | // m2m := orm.QueryM2M(post,"Tag") | ||
| 19 | // m2m.Add(&Tag1{},&Tag2{}) | ||
| 20 | // for _,tag := range post.Tags{} | ||
| 21 | // | ||
| 22 | // make sure the relation is defined in post model struct tag. | ||
| 15 | func (o *queryM2M) Add(mds ...interface{}) (int64, error) { | 23 | func (o *queryM2M) Add(mds ...interface{}) (int64, error) { |
| 16 | fi := o.fi | 24 | fi := o.fi |
| 17 | mi := fi.relThroughModelInfo | 25 | mi := fi.relThroughModelInfo |
| ... | @@ -67,6 +75,7 @@ func (o *queryM2M) Add(mds ...interface{}) (int64, error) { | ... | @@ -67,6 +75,7 @@ func (o *queryM2M) Add(mds ...interface{}) (int64, error) { |
| 67 | return dbase.InsertValue(orm.db, mi, true, names, values) | 75 | return dbase.InsertValue(orm.db, mi, true, names, values) |
| 68 | } | 76 | } |
| 69 | 77 | ||
| 78 | // remove models following the origin model relationship | ||
| 70 | func (o *queryM2M) Remove(mds ...interface{}) (int64, error) { | 79 | func (o *queryM2M) Remove(mds ...interface{}) (int64, error) { |
| 71 | fi := o.fi | 80 | fi := o.fi |
| 72 | qs := o.qs.Filter(fi.reverseFieldInfo.name, o.md) | 81 | qs := o.qs.Filter(fi.reverseFieldInfo.name, o.md) |
| ... | @@ -78,17 +87,20 @@ func (o *queryM2M) Remove(mds ...interface{}) (int64, error) { | ... | @@ -78,17 +87,20 @@ func (o *queryM2M) Remove(mds ...interface{}) (int64, error) { |
| 78 | return nums, nil | 87 | return nums, nil |
| 79 | } | 88 | } |
| 80 | 89 | ||
| 90 | // check model is existed in relationship of origin model | ||
| 81 | func (o *queryM2M) Exist(md interface{}) bool { | 91 | func (o *queryM2M) Exist(md interface{}) bool { |
| 82 | fi := o.fi | 92 | fi := o.fi |
| 83 | return o.qs.Filter(fi.reverseFieldInfo.name, o.md). | 93 | return o.qs.Filter(fi.reverseFieldInfo.name, o.md). |
| 84 | Filter(fi.reverseFieldInfoTwo.name, md).Exist() | 94 | Filter(fi.reverseFieldInfoTwo.name, md).Exist() |
| 85 | } | 95 | } |
| 86 | 96 | ||
| 97 | // clean all models in related of origin model | ||
| 87 | func (o *queryM2M) Clear() (int64, error) { | 98 | func (o *queryM2M) Clear() (int64, error) { |
| 88 | fi := o.fi | 99 | fi := o.fi |
| 89 | return o.qs.Filter(fi.reverseFieldInfo.name, o.md).Delete() | 100 | return o.qs.Filter(fi.reverseFieldInfo.name, o.md).Delete() |
| 90 | } | 101 | } |
| 91 | 102 | ||
| 103 | // count all related models of origin model | ||
| 92 | func (o *queryM2M) Count() (int64, error) { | 104 | func (o *queryM2M) Count() (int64, error) { |
| 93 | fi := o.fi | 105 | fi := o.fi |
| 94 | return o.qs.Filter(fi.reverseFieldInfo.name, o.md).Count() | 106 | return o.qs.Filter(fi.reverseFieldInfo.name, o.md).Count() |
| ... | @@ -96,6 +108,7 @@ func (o *queryM2M) Count() (int64, error) { | ... | @@ -96,6 +108,7 @@ func (o *queryM2M) Count() (int64, error) { |
| 96 | 108 | ||
| 97 | var _ QueryM2Mer = new(queryM2M) | 109 | var _ QueryM2Mer = new(queryM2M) |
| 98 | 110 | ||
| 111 | // create new M2M queryer. | ||
| 99 | func newQueryM2M(md interface{}, o *orm, mi *modelInfo, fi *fieldInfo, ind reflect.Value) QueryM2Mer { | 112 | func newQueryM2M(md interface{}, o *orm, mi *modelInfo, fi *fieldInfo, ind reflect.Value) QueryM2Mer { |
| 100 | qm2m := new(queryM2M) | 113 | qm2m := new(queryM2M) |
| 101 | qm2m.md = md | 114 | qm2m.md = md | ... | ... |
| ... | @@ -18,6 +18,10 @@ const ( | ... | @@ -18,6 +18,10 @@ const ( |
| 18 | Col_Except | 18 | Col_Except |
| 19 | ) | 19 | ) |
| 20 | 20 | ||
| 21 | // ColValue do the field raw changes. e.g Nums = Nums + 10. usage: | ||
| 22 | // Params{ | ||
| 23 | // "Nums": ColValue(Col_Add, 10), | ||
| 24 | // } | ||
| 21 | func ColValue(opt operator, value interface{}) interface{} { | 25 | func ColValue(opt operator, value interface{}) interface{} { |
| 22 | switch opt { | 26 | switch opt { |
| 23 | case Col_Add, Col_Minus, Col_Multiply, Col_Except: | 27 | case Col_Add, Col_Minus, Col_Multiply, Col_Except: |
| ... | @@ -34,6 +38,7 @@ func ColValue(opt operator, value interface{}) interface{} { | ... | @@ -34,6 +38,7 @@ func ColValue(opt operator, value interface{}) interface{} { |
| 34 | return val | 38 | return val |
| 35 | } | 39 | } |
| 36 | 40 | ||
| 41 | // real query struct | ||
| 37 | type querySet struct { | 42 | type querySet struct { |
| 38 | mi *modelInfo | 43 | mi *modelInfo |
| 39 | cond *Condition | 44 | cond *Condition |
| ... | @@ -47,6 +52,7 @@ type querySet struct { | ... | @@ -47,6 +52,7 @@ type querySet struct { |
| 47 | 52 | ||
| 48 | var _ QuerySeter = new(querySet) | 53 | var _ QuerySeter = new(querySet) |
| 49 | 54 | ||
| 55 | // add condition expression to QuerySeter. | ||
| 50 | func (o querySet) Filter(expr string, args ...interface{}) QuerySeter { | 56 | func (o querySet) Filter(expr string, args ...interface{}) QuerySeter { |
| 51 | if o.cond == nil { | 57 | if o.cond == nil { |
| 52 | o.cond = NewCondition() | 58 | o.cond = NewCondition() |
| ... | @@ -55,6 +61,7 @@ func (o querySet) Filter(expr string, args ...interface{}) QuerySeter { | ... | @@ -55,6 +61,7 @@ func (o querySet) Filter(expr string, args ...interface{}) QuerySeter { |
| 55 | return &o | 61 | return &o |
| 56 | } | 62 | } |
| 57 | 63 | ||
| 64 | // add NOT condition to querySeter. | ||
| 58 | func (o querySet) Exclude(expr string, args ...interface{}) QuerySeter { | 65 | func (o querySet) Exclude(expr string, args ...interface{}) QuerySeter { |
| 59 | if o.cond == nil { | 66 | if o.cond == nil { |
| 60 | o.cond = NewCondition() | 67 | o.cond = NewCondition() |
| ... | @@ -63,10 +70,13 @@ func (o querySet) Exclude(expr string, args ...interface{}) QuerySeter { | ... | @@ -63,10 +70,13 @@ func (o querySet) Exclude(expr string, args ...interface{}) QuerySeter { |
| 63 | return &o | 70 | return &o |
| 64 | } | 71 | } |
| 65 | 72 | ||
| 73 | // set offset number | ||
| 66 | func (o *querySet) setOffset(num interface{}) { | 74 | func (o *querySet) setOffset(num interface{}) { |
| 67 | o.offset = ToInt64(num) | 75 | o.offset = ToInt64(num) |
| 68 | } | 76 | } |
| 69 | 77 | ||
| 78 | // add LIMIT value. | ||
| 79 | // args[0] means offset, e.g. LIMIT num,offset. | ||
| 70 | func (o querySet) Limit(limit interface{}, args ...interface{}) QuerySeter { | 80 | func (o querySet) Limit(limit interface{}, args ...interface{}) QuerySeter { |
| 71 | o.limit = ToInt64(limit) | 81 | o.limit = ToInt64(limit) |
| 72 | if len(args) > 0 { | 82 | if len(args) > 0 { |
| ... | @@ -75,16 +85,21 @@ func (o querySet) Limit(limit interface{}, args ...interface{}) QuerySeter { | ... | @@ -75,16 +85,21 @@ func (o querySet) Limit(limit interface{}, args ...interface{}) QuerySeter { |
| 75 | return &o | 85 | return &o |
| 76 | } | 86 | } |
| 77 | 87 | ||
| 88 | // add OFFSET value | ||
| 78 | func (o querySet) Offset(offset interface{}) QuerySeter { | 89 | func (o querySet) Offset(offset interface{}) QuerySeter { |
| 79 | o.setOffset(offset) | 90 | o.setOffset(offset) |
| 80 | return &o | 91 | return &o |
| 81 | } | 92 | } |
| 82 | 93 | ||
| 94 | // add ORDER expression. | ||
| 95 | // "column" means ASC, "-column" means DESC. | ||
| 83 | func (o querySet) OrderBy(exprs ...string) QuerySeter { | 96 | func (o querySet) OrderBy(exprs ...string) QuerySeter { |
| 84 | o.orders = exprs | 97 | o.orders = exprs |
| 85 | return &o | 98 | return &o |
| 86 | } | 99 | } |
| 87 | 100 | ||
| 101 | // set relation model to query together. | ||
| 102 | // it will query relation models and assign to parent model. | ||
| 88 | func (o querySet) RelatedSel(params ...interface{}) QuerySeter { | 103 | func (o querySet) RelatedSel(params ...interface{}) QuerySeter { |
| 89 | var related []string | 104 | var related []string |
| 90 | if len(params) == 0 { | 105 | if len(params) == 0 { |
| ... | @@ -105,36 +120,50 @@ func (o querySet) RelatedSel(params ...interface{}) QuerySeter { | ... | @@ -105,36 +120,50 @@ func (o querySet) RelatedSel(params ...interface{}) QuerySeter { |
| 105 | return &o | 120 | return &o |
| 106 | } | 121 | } |
| 107 | 122 | ||
| 123 | // set condition to QuerySeter. | ||
| 108 | func (o querySet) SetCond(cond *Condition) QuerySeter { | 124 | func (o querySet) SetCond(cond *Condition) QuerySeter { |
| 109 | o.cond = cond | 125 | o.cond = cond |
| 110 | return &o | 126 | return &o |
| 111 | } | 127 | } |
| 112 | 128 | ||
| 129 | // return QuerySeter execution result number | ||
| 113 | func (o *querySet) Count() (int64, error) { | 130 | func (o *querySet) Count() (int64, error) { |
| 114 | return o.orm.alias.DbBaser.Count(o.orm.db, o, o.mi, o.cond, o.orm.alias.TZ) | 131 | return o.orm.alias.DbBaser.Count(o.orm.db, o, o.mi, o.cond, o.orm.alias.TZ) |
| 115 | } | 132 | } |
| 116 | 133 | ||
| 134 | // check result empty or not after QuerySeter executed | ||
| 117 | func (o *querySet) Exist() bool { | 135 | func (o *querySet) Exist() bool { |
| 118 | cnt, _ := o.orm.alias.DbBaser.Count(o.orm.db, o, o.mi, o.cond, o.orm.alias.TZ) | 136 | cnt, _ := o.orm.alias.DbBaser.Count(o.orm.db, o, o.mi, o.cond, o.orm.alias.TZ) |
| 119 | return cnt > 0 | 137 | return cnt > 0 |
| 120 | } | 138 | } |
| 121 | 139 | ||
| 140 | // execute update with parameters | ||
| 122 | func (o *querySet) Update(values Params) (int64, error) { | 141 | func (o *querySet) Update(values Params) (int64, error) { |
| 123 | return o.orm.alias.DbBaser.UpdateBatch(o.orm.db, o, o.mi, o.cond, values, o.orm.alias.TZ) | 142 | return o.orm.alias.DbBaser.UpdateBatch(o.orm.db, o, o.mi, o.cond, values, o.orm.alias.TZ) |
| 124 | } | 143 | } |
| 125 | 144 | ||
| 145 | // execute delete | ||
| 126 | func (o *querySet) Delete() (int64, error) { | 146 | func (o *querySet) Delete() (int64, error) { |
| 127 | return o.orm.alias.DbBaser.DeleteBatch(o.orm.db, o, o.mi, o.cond, o.orm.alias.TZ) | 147 | return o.orm.alias.DbBaser.DeleteBatch(o.orm.db, o, o.mi, o.cond, o.orm.alias.TZ) |
| 128 | } | 148 | } |
| 129 | 149 | ||
| 150 | // return a insert queryer. | ||
| 151 | // it can be used in times. | ||
| 152 | // example: | ||
| 153 | // i,err := sq.PrepareInsert() | ||
| 154 | // i.Add(&user1{},&user2{}) | ||
| 130 | func (o *querySet) PrepareInsert() (Inserter, error) { | 155 | func (o *querySet) PrepareInsert() (Inserter, error) { |
| 131 | return newInsertSet(o.orm, o.mi) | 156 | return newInsertSet(o.orm, o.mi) |
| 132 | } | 157 | } |
| 133 | 158 | ||
| 159 | // query all data and map to containers. | ||
| 160 | // cols means the columns when querying. | ||
| 134 | func (o *querySet) All(container interface{}, cols ...string) (int64, error) { | 161 | func (o *querySet) All(container interface{}, cols ...string) (int64, error) { |
| 135 | return o.orm.alias.DbBaser.ReadBatch(o.orm.db, o, o.mi, o.cond, container, o.orm.alias.TZ, cols) | 162 | return o.orm.alias.DbBaser.ReadBatch(o.orm.db, o, o.mi, o.cond, container, o.orm.alias.TZ, cols) |
| 136 | } | 163 | } |
| 137 | 164 | ||
| 165 | // query one row data and map to containers. | ||
| 166 | // cols means the columns when querying. | ||
| 138 | func (o *querySet) One(container interface{}, cols ...string) error { | 167 | func (o *querySet) One(container interface{}, cols ...string) error { |
| 139 | num, err := o.orm.alias.DbBaser.ReadBatch(o.orm.db, o, o.mi, o.cond, container, o.orm.alias.TZ, cols) | 168 | num, err := o.orm.alias.DbBaser.ReadBatch(o.orm.db, o, o.mi, o.cond, container, o.orm.alias.TZ, cols) |
| 140 | if err != nil { | 169 | if err != nil { |
| ... | @@ -149,18 +178,26 @@ func (o *querySet) One(container interface{}, cols ...string) error { | ... | @@ -149,18 +178,26 @@ func (o *querySet) One(container interface{}, cols ...string) error { |
| 149 | return nil | 178 | return nil |
| 150 | } | 179 | } |
| 151 | 180 | ||
| 181 | // query all data and map to []map[string]interface. | ||
| 182 | // expres means condition expression. | ||
| 183 | // it converts data to []map[column]value. | ||
| 152 | func (o *querySet) Values(results *[]Params, exprs ...string) (int64, error) { | 184 | func (o *querySet) Values(results *[]Params, exprs ...string) (int64, error) { |
| 153 | return o.orm.alias.DbBaser.ReadValues(o.orm.db, o, o.mi, o.cond, exprs, results, o.orm.alias.TZ) | 185 | return o.orm.alias.DbBaser.ReadValues(o.orm.db, o, o.mi, o.cond, exprs, results, o.orm.alias.TZ) |
| 154 | } | 186 | } |
| 155 | 187 | ||
| 188 | // query all data and map to [][]interface | ||
| 189 | // it converts data to [][column_index]value | ||
| 156 | func (o *querySet) ValuesList(results *[]ParamsList, exprs ...string) (int64, error) { | 190 | func (o *querySet) ValuesList(results *[]ParamsList, exprs ...string) (int64, error) { |
| 157 | return o.orm.alias.DbBaser.ReadValues(o.orm.db, o, o.mi, o.cond, exprs, results, o.orm.alias.TZ) | 191 | return o.orm.alias.DbBaser.ReadValues(o.orm.db, o, o.mi, o.cond, exprs, results, o.orm.alias.TZ) |
| 158 | } | 192 | } |
| 159 | 193 | ||
| 194 | // query all data and map to []interface. | ||
| 195 | // it's designed for one row record set, auto change to []value, not [][column]value. | ||
| 160 | func (o *querySet) ValuesFlat(result *ParamsList, expr string) (int64, error) { | 196 | func (o *querySet) ValuesFlat(result *ParamsList, expr string) (int64, error) { |
| 161 | return o.orm.alias.DbBaser.ReadValues(o.orm.db, o, o.mi, o.cond, []string{expr}, result, o.orm.alias.TZ) | 197 | return o.orm.alias.DbBaser.ReadValues(o.orm.db, o, o.mi, o.cond, []string{expr}, result, o.orm.alias.TZ) |
| 162 | } | 198 | } |
| 163 | 199 | ||
| 200 | // create new QuerySeter. | ||
| 164 | func newQuerySet(orm *orm, mi *modelInfo) QuerySeter { | 201 | func newQuerySet(orm *orm, mi *modelInfo) QuerySeter { |
| 165 | o := new(querySet) | 202 | o := new(querySet) |
| 166 | o.mi = mi | 203 | o.mi = mi | ... | ... |
| ... | @@ -7,6 +7,7 @@ import ( | ... | @@ -7,6 +7,7 @@ import ( |
| 7 | "time" | 7 | "time" |
| 8 | ) | 8 | ) |
| 9 | 9 | ||
| 10 | // raw sql string prepared statement | ||
| 10 | type rawPrepare struct { | 11 | type rawPrepare struct { |
| 11 | rs *rawSet | 12 | rs *rawSet |
| 12 | stmt stmtQuerier | 13 | stmt stmtQuerier |
| ... | @@ -44,6 +45,7 @@ func newRawPreparer(rs *rawSet) (RawPreparer, error) { | ... | @@ -44,6 +45,7 @@ func newRawPreparer(rs *rawSet) (RawPreparer, error) { |
| 44 | return o, nil | 45 | return o, nil |
| 45 | } | 46 | } |
| 46 | 47 | ||
| 48 | // raw query seter | ||
| 47 | type rawSet struct { | 49 | type rawSet struct { |
| 48 | query string | 50 | query string |
| 49 | args []interface{} | 51 | args []interface{} |
| ... | @@ -52,11 +54,13 @@ type rawSet struct { | ... | @@ -52,11 +54,13 @@ type rawSet struct { |
| 52 | 54 | ||
| 53 | var _ RawSeter = new(rawSet) | 55 | var _ RawSeter = new(rawSet) |
| 54 | 56 | ||
| 57 | // set args for every query | ||
| 55 | func (o rawSet) SetArgs(args ...interface{}) RawSeter { | 58 | func (o rawSet) SetArgs(args ...interface{}) RawSeter { |
| 56 | o.args = args | 59 | o.args = args |
| 57 | return &o | 60 | return &o |
| 58 | } | 61 | } |
| 59 | 62 | ||
| 63 | // execute raw sql and return sql.Result | ||
| 60 | func (o *rawSet) Exec() (sql.Result, error) { | 64 | func (o *rawSet) Exec() (sql.Result, error) { |
| 61 | query := o.query | 65 | query := o.query |
| 62 | o.orm.alias.DbBaser.ReplaceMarks(&query) | 66 | o.orm.alias.DbBaser.ReplaceMarks(&query) |
| ... | @@ -65,6 +69,7 @@ func (o *rawSet) Exec() (sql.Result, error) { | ... | @@ -65,6 +69,7 @@ func (o *rawSet) Exec() (sql.Result, error) { |
| 65 | return o.orm.db.Exec(query, args...) | 69 | return o.orm.db.Exec(query, args...) |
| 66 | } | 70 | } |
| 67 | 71 | ||
| 72 | // set field value to row container | ||
| 68 | func (o *rawSet) setFieldValue(ind reflect.Value, value interface{}) { | 73 | func (o *rawSet) setFieldValue(ind reflect.Value, value interface{}) { |
| 69 | switch ind.Kind() { | 74 | switch ind.Kind() { |
| 70 | case reflect.Bool: | 75 | case reflect.Bool: |
| ... | @@ -163,6 +168,7 @@ func (o *rawSet) setFieldValue(ind reflect.Value, value interface{}) { | ... | @@ -163,6 +168,7 @@ func (o *rawSet) setFieldValue(ind reflect.Value, value interface{}) { |
| 163 | } | 168 | } |
| 164 | } | 169 | } |
| 165 | 170 | ||
| 171 | // set field value in loop for slice container | ||
| 166 | func (o *rawSet) loopSetRefs(refs []interface{}, sInds []reflect.Value, nIndsPtr *[]reflect.Value, eTyps []reflect.Type, init bool) { | 172 | func (o *rawSet) loopSetRefs(refs []interface{}, sInds []reflect.Value, nIndsPtr *[]reflect.Value, eTyps []reflect.Type, init bool) { |
| 167 | nInds := *nIndsPtr | 173 | nInds := *nIndsPtr |
| 168 | 174 | ||
| ... | @@ -233,6 +239,7 @@ func (o *rawSet) loopSetRefs(refs []interface{}, sInds []reflect.Value, nIndsPtr | ... | @@ -233,6 +239,7 @@ func (o *rawSet) loopSetRefs(refs []interface{}, sInds []reflect.Value, nIndsPtr |
| 233 | } | 239 | } |
| 234 | } | 240 | } |
| 235 | 241 | ||
| 242 | // query data and map to container | ||
| 236 | func (o *rawSet) QueryRow(containers ...interface{}) error { | 243 | func (o *rawSet) QueryRow(containers ...interface{}) error { |
| 237 | refs := make([]interface{}, 0, len(containers)) | 244 | refs := make([]interface{}, 0, len(containers)) |
| 238 | sInds := make([]reflect.Value, 0) | 245 | sInds := make([]reflect.Value, 0) |
| ... | @@ -362,6 +369,7 @@ func (o *rawSet) QueryRow(containers ...interface{}) error { | ... | @@ -362,6 +369,7 @@ func (o *rawSet) QueryRow(containers ...interface{}) error { |
| 362 | return nil | 369 | return nil |
| 363 | } | 370 | } |
| 364 | 371 | ||
| 372 | // query data rows and map to container | ||
| 365 | func (o *rawSet) QueryRows(containers ...interface{}) (int64, error) { | 373 | func (o *rawSet) QueryRows(containers ...interface{}) (int64, error) { |
| 366 | refs := make([]interface{}, 0, len(containers)) | 374 | refs := make([]interface{}, 0, len(containers)) |
| 367 | sInds := make([]reflect.Value, 0) | 375 | sInds := make([]reflect.Value, 0) |
| ... | @@ -615,18 +623,22 @@ func (o *rawSet) readValues(container interface{}) (int64, error) { | ... | @@ -615,18 +623,22 @@ func (o *rawSet) readValues(container interface{}) (int64, error) { |
| 615 | return cnt, nil | 623 | return cnt, nil |
| 616 | } | 624 | } |
| 617 | 625 | ||
| 626 | // query data to []map[string]interface | ||
| 618 | func (o *rawSet) Values(container *[]Params) (int64, error) { | 627 | func (o *rawSet) Values(container *[]Params) (int64, error) { |
| 619 | return o.readValues(container) | 628 | return o.readValues(container) |
| 620 | } | 629 | } |
| 621 | 630 | ||
| 631 | // query data to [][]interface | ||
| 622 | func (o *rawSet) ValuesList(container *[]ParamsList) (int64, error) { | 632 | func (o *rawSet) ValuesList(container *[]ParamsList) (int64, error) { |
| 623 | return o.readValues(container) | 633 | return o.readValues(container) |
| 624 | } | 634 | } |
| 625 | 635 | ||
| 636 | // query data to []interface | ||
| 626 | func (o *rawSet) ValuesFlat(container *ParamsList) (int64, error) { | 637 | func (o *rawSet) ValuesFlat(container *ParamsList) (int64, error) { |
| 627 | return o.readValues(container) | 638 | return o.readValues(container) |
| 628 | } | 639 | } |
| 629 | 640 | ||
| 641 | // return prepared raw statement for used in times. | ||
| 630 | func (o *rawSet) Prepare() (RawPreparer, error) { | 642 | func (o *rawSet) Prepare() (RawPreparer, error) { |
| 631 | return newRawPreparer(o) | 643 | return newRawPreparer(o) |
| 632 | } | 644 | } | ... | ... |
| ... | @@ -6,11 +6,13 @@ import ( | ... | @@ -6,11 +6,13 @@ import ( |
| 6 | "time" | 6 | "time" |
| 7 | ) | 7 | ) |
| 8 | 8 | ||
| 9 | // database driver | ||
| 9 | type Driver interface { | 10 | type Driver interface { |
| 10 | Name() string | 11 | Name() string |
| 11 | Type() DriverType | 12 | Type() DriverType |
| 12 | } | 13 | } |
| 13 | 14 | ||
| 15 | // field info | ||
| 14 | type Fielder interface { | 16 | type Fielder interface { |
| 15 | String() string | 17 | String() string |
| 16 | FieldType() int | 18 | FieldType() int |
| ... | @@ -18,6 +20,7 @@ type Fielder interface { | ... | @@ -18,6 +20,7 @@ type Fielder interface { |
| 18 | RawValue() interface{} | 20 | RawValue() interface{} |
| 19 | } | 21 | } |
| 20 | 22 | ||
| 23 | // orm struct | ||
| 21 | type Ormer interface { | 24 | type Ormer interface { |
| 22 | Read(interface{}, ...string) error | 25 | Read(interface{}, ...string) error |
| 23 | Insert(interface{}) (int64, error) | 26 | Insert(interface{}) (int64, error) |
| ... | @@ -35,11 +38,13 @@ type Ormer interface { | ... | @@ -35,11 +38,13 @@ type Ormer interface { |
| 35 | Driver() Driver | 38 | Driver() Driver |
| 36 | } | 39 | } |
| 37 | 40 | ||
| 41 | // insert prepared statement | ||
| 38 | type Inserter interface { | 42 | type Inserter interface { |
| 39 | Insert(interface{}) (int64, error) | 43 | Insert(interface{}) (int64, error) |
| 40 | Close() error | 44 | Close() error |
| 41 | } | 45 | } |
| 42 | 46 | ||
| 47 | // query seter | ||
| 43 | type QuerySeter interface { | 48 | type QuerySeter interface { |
| 44 | Filter(string, ...interface{}) QuerySeter | 49 | Filter(string, ...interface{}) QuerySeter |
| 45 | Exclude(string, ...interface{}) QuerySeter | 50 | Exclude(string, ...interface{}) QuerySeter |
| ... | @@ -60,6 +65,7 @@ type QuerySeter interface { | ... | @@ -60,6 +65,7 @@ type QuerySeter interface { |
| 60 | ValuesFlat(*ParamsList, string) (int64, error) | 65 | ValuesFlat(*ParamsList, string) (int64, error) |
| 61 | } | 66 | } |
| 62 | 67 | ||
| 68 | // model to model query struct | ||
| 63 | type QueryM2Mer interface { | 69 | type QueryM2Mer interface { |
| 64 | Add(...interface{}) (int64, error) | 70 | Add(...interface{}) (int64, error) |
| 65 | Remove(...interface{}) (int64, error) | 71 | Remove(...interface{}) (int64, error) |
| ... | @@ -68,11 +74,13 @@ type QueryM2Mer interface { | ... | @@ -68,11 +74,13 @@ type QueryM2Mer interface { |
| 68 | Count() (int64, error) | 74 | Count() (int64, error) |
| 69 | } | 75 | } |
| 70 | 76 | ||
| 77 | // raw query statement | ||
| 71 | type RawPreparer interface { | 78 | type RawPreparer interface { |
| 72 | Exec(...interface{}) (sql.Result, error) | 79 | Exec(...interface{}) (sql.Result, error) |
| 73 | Close() error | 80 | Close() error |
| 74 | } | 81 | } |
| 75 | 82 | ||
| 83 | // raw query seter | ||
| 76 | type RawSeter interface { | 84 | type RawSeter interface { |
| 77 | Exec() (sql.Result, error) | 85 | Exec() (sql.Result, error) |
| 78 | QueryRow(...interface{}) error | 86 | QueryRow(...interface{}) error |
| ... | @@ -84,6 +92,7 @@ type RawSeter interface { | ... | @@ -84,6 +92,7 @@ type RawSeter interface { |
| 84 | Prepare() (RawPreparer, error) | 92 | Prepare() (RawPreparer, error) |
| 85 | } | 93 | } |
| 86 | 94 | ||
| 95 | // statement querier | ||
| 87 | type stmtQuerier interface { | 96 | type stmtQuerier interface { |
| 88 | Close() error | 97 | Close() error |
| 89 | Exec(args ...interface{}) (sql.Result, error) | 98 | Exec(args ...interface{}) (sql.Result, error) |
| ... | @@ -91,6 +100,7 @@ type stmtQuerier interface { | ... | @@ -91,6 +100,7 @@ type stmtQuerier interface { |
| 91 | QueryRow(args ...interface{}) *sql.Row | 100 | QueryRow(args ...interface{}) *sql.Row |
| 92 | } | 101 | } |
| 93 | 102 | ||
| 103 | // db querier | ||
| 94 | type dbQuerier interface { | 104 | type dbQuerier interface { |
| 95 | Prepare(query string) (*sql.Stmt, error) | 105 | Prepare(query string) (*sql.Stmt, error) |
| 96 | Exec(query string, args ...interface{}) (sql.Result, error) | 106 | Exec(query string, args ...interface{}) (sql.Result, error) |
| ... | @@ -98,15 +108,18 @@ type dbQuerier interface { | ... | @@ -98,15 +108,18 @@ type dbQuerier interface { |
| 98 | QueryRow(query string, args ...interface{}) *sql.Row | 108 | QueryRow(query string, args ...interface{}) *sql.Row |
| 99 | } | 109 | } |
| 100 | 110 | ||
| 111 | // transaction beginner | ||
| 101 | type txer interface { | 112 | type txer interface { |
| 102 | Begin() (*sql.Tx, error) | 113 | Begin() (*sql.Tx, error) |
| 103 | } | 114 | } |
| 104 | 115 | ||
| 116 | // transaction ending | ||
| 105 | type txEnder interface { | 117 | type txEnder interface { |
| 106 | Commit() error | 118 | Commit() error |
| 107 | Rollback() error | 119 | Rollback() error |
| 108 | } | 120 | } |
| 109 | 121 | ||
| 122 | // base database struct | ||
| 110 | type dbBaser interface { | 123 | type dbBaser interface { |
| 111 | Read(dbQuerier, *modelInfo, reflect.Value, *time.Location, []string) error | 124 | Read(dbQuerier, *modelInfo, reflect.Value, *time.Location, []string) error |
| 112 | Insert(dbQuerier, *modelInfo, reflect.Value, *time.Location) (int64, error) | 125 | Insert(dbQuerier, *modelInfo, reflect.Value, *time.Location) (int64, error) | ... | ... |
| ... | @@ -10,6 +10,7 @@ import ( | ... | @@ -10,6 +10,7 @@ import ( |
| 10 | 10 | ||
| 11 | type StrTo string | 11 | type StrTo string |
| 12 | 12 | ||
| 13 | // set string | ||
| 13 | func (f *StrTo) Set(v string) { | 14 | func (f *StrTo) Set(v string) { |
| 14 | if v != "" { | 15 | if v != "" { |
| 15 | *f = StrTo(v) | 16 | *f = StrTo(v) |
| ... | @@ -18,77 +19,93 @@ func (f *StrTo) Set(v string) { | ... | @@ -18,77 +19,93 @@ func (f *StrTo) Set(v string) { |
| 18 | } | 19 | } |
| 19 | } | 20 | } |
| 20 | 21 | ||
| 22 | // clean string | ||
| 21 | func (f *StrTo) Clear() { | 23 | func (f *StrTo) Clear() { |
| 22 | *f = StrTo(0x1E) | 24 | *f = StrTo(0x1E) |
| 23 | } | 25 | } |
| 24 | 26 | ||
| 27 | // check string exist | ||
| 25 | func (f StrTo) Exist() bool { | 28 | func (f StrTo) Exist() bool { |
| 26 | return string(f) != string(0x1E) | 29 | return string(f) != string(0x1E) |
| 27 | } | 30 | } |
| 28 | 31 | ||
| 32 | // string to bool | ||
| 29 | func (f StrTo) Bool() (bool, error) { | 33 | func (f StrTo) Bool() (bool, error) { |
| 30 | return strconv.ParseBool(f.String()) | 34 | return strconv.ParseBool(f.String()) |
| 31 | } | 35 | } |
| 32 | 36 | ||
| 37 | // string to float32 | ||
| 33 | func (f StrTo) Float32() (float32, error) { | 38 | func (f StrTo) Float32() (float32, error) { |
| 34 | v, err := strconv.ParseFloat(f.String(), 32) | 39 | v, err := strconv.ParseFloat(f.String(), 32) |
| 35 | return float32(v), err | 40 | return float32(v), err |
| 36 | } | 41 | } |
| 37 | 42 | ||
| 43 | // string to float64 | ||
| 38 | func (f StrTo) Float64() (float64, error) { | 44 | func (f StrTo) Float64() (float64, error) { |
| 39 | return strconv.ParseFloat(f.String(), 64) | 45 | return strconv.ParseFloat(f.String(), 64) |
| 40 | } | 46 | } |
| 41 | 47 | ||
| 48 | // string to int | ||
| 42 | func (f StrTo) Int() (int, error) { | 49 | func (f StrTo) Int() (int, error) { |
| 43 | v, err := strconv.ParseInt(f.String(), 10, 32) | 50 | v, err := strconv.ParseInt(f.String(), 10, 32) |
| 44 | return int(v), err | 51 | return int(v), err |
| 45 | } | 52 | } |
| 46 | 53 | ||
| 54 | // string to int8 | ||
| 47 | func (f StrTo) Int8() (int8, error) { | 55 | func (f StrTo) Int8() (int8, error) { |
| 48 | v, err := strconv.ParseInt(f.String(), 10, 8) | 56 | v, err := strconv.ParseInt(f.String(), 10, 8) |
| 49 | return int8(v), err | 57 | return int8(v), err |
| 50 | } | 58 | } |
| 51 | 59 | ||
| 60 | // string to int16 | ||
| 52 | func (f StrTo) Int16() (int16, error) { | 61 | func (f StrTo) Int16() (int16, error) { |
| 53 | v, err := strconv.ParseInt(f.String(), 10, 16) | 62 | v, err := strconv.ParseInt(f.String(), 10, 16) |
| 54 | return int16(v), err | 63 | return int16(v), err |
| 55 | } | 64 | } |
| 56 | 65 | ||
| 66 | // string to int32 | ||
| 57 | func (f StrTo) Int32() (int32, error) { | 67 | func (f StrTo) Int32() (int32, error) { |
| 58 | v, err := strconv.ParseInt(f.String(), 10, 32) | 68 | v, err := strconv.ParseInt(f.String(), 10, 32) |
| 59 | return int32(v), err | 69 | return int32(v), err |
| 60 | } | 70 | } |
| 61 | 71 | ||
| 72 | // string to int64 | ||
| 62 | func (f StrTo) Int64() (int64, error) { | 73 | func (f StrTo) Int64() (int64, error) { |
| 63 | v, err := strconv.ParseInt(f.String(), 10, 64) | 74 | v, err := strconv.ParseInt(f.String(), 10, 64) |
| 64 | return int64(v), err | 75 | return int64(v), err |
| 65 | } | 76 | } |
| 66 | 77 | ||
| 78 | // string to uint | ||
| 67 | func (f StrTo) Uint() (uint, error) { | 79 | func (f StrTo) Uint() (uint, error) { |
| 68 | v, err := strconv.ParseUint(f.String(), 10, 32) | 80 | v, err := strconv.ParseUint(f.String(), 10, 32) |
| 69 | return uint(v), err | 81 | return uint(v), err |
| 70 | } | 82 | } |
| 71 | 83 | ||
| 84 | // string to uint8 | ||
| 72 | func (f StrTo) Uint8() (uint8, error) { | 85 | func (f StrTo) Uint8() (uint8, error) { |
| 73 | v, err := strconv.ParseUint(f.String(), 10, 8) | 86 | v, err := strconv.ParseUint(f.String(), 10, 8) |
| 74 | return uint8(v), err | 87 | return uint8(v), err |
| 75 | } | 88 | } |
| 76 | 89 | ||
| 90 | // string to uint16 | ||
| 77 | func (f StrTo) Uint16() (uint16, error) { | 91 | func (f StrTo) Uint16() (uint16, error) { |
| 78 | v, err := strconv.ParseUint(f.String(), 10, 16) | 92 | v, err := strconv.ParseUint(f.String(), 10, 16) |
| 79 | return uint16(v), err | 93 | return uint16(v), err |
| 80 | } | 94 | } |
| 81 | 95 | ||
| 96 | // string to uint31 | ||
| 82 | func (f StrTo) Uint32() (uint32, error) { | 97 | func (f StrTo) Uint32() (uint32, error) { |
| 83 | v, err := strconv.ParseUint(f.String(), 10, 32) | 98 | v, err := strconv.ParseUint(f.String(), 10, 32) |
| 84 | return uint32(v), err | 99 | return uint32(v), err |
| 85 | } | 100 | } |
| 86 | 101 | ||
| 102 | // string to uint64 | ||
| 87 | func (f StrTo) Uint64() (uint64, error) { | 103 | func (f StrTo) Uint64() (uint64, error) { |
| 88 | v, err := strconv.ParseUint(f.String(), 10, 64) | 104 | v, err := strconv.ParseUint(f.String(), 10, 64) |
| 89 | return uint64(v), err | 105 | return uint64(v), err |
| 90 | } | 106 | } |
| 91 | 107 | ||
| 108 | // string to string | ||
| 92 | func (f StrTo) String() string { | 109 | func (f StrTo) String() string { |
| 93 | if f.Exist() { | 110 | if f.Exist() { |
| 94 | return string(f) | 111 | return string(f) |
| ... | @@ -96,6 +113,7 @@ func (f StrTo) String() string { | ... | @@ -96,6 +113,7 @@ func (f StrTo) String() string { |
| 96 | return "" | 113 | return "" |
| 97 | } | 114 | } |
| 98 | 115 | ||
| 116 | // interface to string | ||
| 99 | func ToStr(value interface{}, args ...int) (s string) { | 117 | func ToStr(value interface{}, args ...int) (s string) { |
| 100 | switch v := value.(type) { | 118 | switch v := value.(type) { |
| 101 | case bool: | 119 | case bool: |
| ... | @@ -134,6 +152,7 @@ func ToStr(value interface{}, args ...int) (s string) { | ... | @@ -134,6 +152,7 @@ func ToStr(value interface{}, args ...int) (s string) { |
| 134 | return s | 152 | return s |
| 135 | } | 153 | } |
| 136 | 154 | ||
| 155 | // interface to int64 | ||
| 137 | func ToInt64(value interface{}) (d int64) { | 156 | func ToInt64(value interface{}) (d int64) { |
| 138 | val := reflect.ValueOf(value) | 157 | val := reflect.ValueOf(value) |
| 139 | switch value.(type) { | 158 | switch value.(type) { |
| ... | @@ -147,6 +166,7 @@ func ToInt64(value interface{}) (d int64) { | ... | @@ -147,6 +166,7 @@ func ToInt64(value interface{}) (d int64) { |
| 147 | return | 166 | return |
| 148 | } | 167 | } |
| 149 | 168 | ||
| 169 | // snake string, XxYy to xx_yy | ||
| 150 | func snakeString(s string) string { | 170 | func snakeString(s string) string { |
| 151 | data := make([]byte, 0, len(s)*2) | 171 | data := make([]byte, 0, len(s)*2) |
| 152 | j := false | 172 | j := false |
| ... | @@ -164,6 +184,7 @@ func snakeString(s string) string { | ... | @@ -164,6 +184,7 @@ func snakeString(s string) string { |
| 164 | return strings.ToLower(string(data[:len(data)])) | 184 | return strings.ToLower(string(data[:len(data)])) |
| 165 | } | 185 | } |
| 166 | 186 | ||
| 187 | // camel string, xx_yy to XxYy | ||
| 167 | func camelString(s string) string { | 188 | func camelString(s string) string { |
| 168 | data := make([]byte, 0, len(s)) | 189 | data := make([]byte, 0, len(s)) |
| 169 | j := false | 190 | j := false |
| ... | @@ -190,6 +211,7 @@ func camelString(s string) string { | ... | @@ -190,6 +211,7 @@ func camelString(s string) string { |
| 190 | 211 | ||
| 191 | type argString []string | 212 | type argString []string |
| 192 | 213 | ||
| 214 | // get string by index from string slice | ||
| 193 | func (a argString) Get(i int, args ...string) (r string) { | 215 | func (a argString) Get(i int, args ...string) (r string) { |
| 194 | if i >= 0 && i < len(a) { | 216 | if i >= 0 && i < len(a) { |
| 195 | r = a[i] | 217 | r = a[i] |
| ... | @@ -201,6 +223,7 @@ func (a argString) Get(i int, args ...string) (r string) { | ... | @@ -201,6 +223,7 @@ func (a argString) Get(i int, args ...string) (r string) { |
| 201 | 223 | ||
| 202 | type argInt []int | 224 | type argInt []int |
| 203 | 225 | ||
| 226 | // get int by index from int slice | ||
| 204 | func (a argInt) Get(i int, args ...int) (r int) { | 227 | func (a argInt) Get(i int, args ...int) (r int) { |
| 205 | if i >= 0 && i < len(a) { | 228 | if i >= 0 && i < len(a) { |
| 206 | r = a[i] | 229 | r = a[i] |
| ... | @@ -213,6 +236,7 @@ func (a argInt) Get(i int, args ...int) (r int) { | ... | @@ -213,6 +236,7 @@ func (a argInt) Get(i int, args ...int) (r int) { |
| 213 | 236 | ||
| 214 | type argAny []interface{} | 237 | type argAny []interface{} |
| 215 | 238 | ||
| 239 | // get interface by index from interface slice | ||
| 216 | func (a argAny) Get(i int, args ...interface{}) (r interface{}) { | 240 | func (a argAny) Get(i int, args ...interface{}) (r interface{}) { |
| 217 | if i >= 0 && i < len(a) { | 241 | if i >= 0 && i < len(a) { |
| 218 | r = a[i] | 242 | r = a[i] |
| ... | @@ -223,15 +247,18 @@ func (a argAny) Get(i int, args ...interface{}) (r interface{}) { | ... | @@ -223,15 +247,18 @@ func (a argAny) Get(i int, args ...interface{}) (r interface{}) { |
| 223 | return | 247 | return |
| 224 | } | 248 | } |
| 225 | 249 | ||
| 250 | // parse time to string with location | ||
| 226 | func timeParse(dateString, format string) (time.Time, error) { | 251 | func timeParse(dateString, format string) (time.Time, error) { |
| 227 | tp, err := time.ParseInLocation(format, dateString, DefaultTimeLoc) | 252 | tp, err := time.ParseInLocation(format, dateString, DefaultTimeLoc) |
| 228 | return tp, err | 253 | return tp, err |
| 229 | } | 254 | } |
| 230 | 255 | ||
| 256 | // format time string | ||
| 231 | func timeFormat(t time.Time, format string) string { | 257 | func timeFormat(t time.Time, format string) string { |
| 232 | return t.Format(format) | 258 | return t.Format(format) |
| 233 | } | 259 | } |
| 234 | 260 | ||
| 261 | // get pointer indirect type | ||
| 235 | func indirectType(v reflect.Type) reflect.Type { | 262 | func indirectType(v reflect.Type) reflect.Type { |
| 236 | switch v.Kind() { | 263 | switch v.Kind() { |
| 237 | case reflect.Ptr: | 264 | case reflect.Ptr: | ... | ... |
-
Please register or sign in to post a comment