38f93a7b by astaxie

Merge pull request #470 from fuxiaohei/develop

add comments for orm and middleware packages.
2 parents 91d75e89 828a3060
...@@ -221,7 +221,7 @@ func Run() { ...@@ -221,7 +221,7 @@ func Run() {
221 221
222 middleware.VERSION = VERSION 222 middleware.VERSION = VERSION
223 middleware.AppName = AppName 223 middleware.AppName = AppName
224 middleware.RegisterErrorHander() 224 middleware.RegisterErrorHandler()
225 225
226 if EnableAdmin { 226 if EnableAdmin {
227 go BeeAdminApp.Run() 227 go BeeAdminApp.Run()
......
...@@ -61,6 +61,7 @@ var tpl = ` ...@@ -61,6 +61,7 @@ var tpl = `
61 </html> 61 </html>
62 ` 62 `
63 63
64 // render default application error page with error and stack string.
64 func ShowErr(err interface{}, rw http.ResponseWriter, r *http.Request, Stack string) { 65 func ShowErr(err interface{}, rw http.ResponseWriter, r *http.Request, Stack string) {
65 t, _ := template.New("beegoerrortemp").Parse(tpl) 66 t, _ := template.New("beegoerrortemp").Parse(tpl)
66 data := make(map[string]string) 67 data := make(map[string]string)
...@@ -175,13 +176,14 @@ var errtpl = ` ...@@ -175,13 +176,14 @@ var errtpl = `
175 </html> 176 </html>
176 ` 177 `
177 178
179 // map of http handlers for each error string.
178 var ErrorMaps map[string]http.HandlerFunc 180 var ErrorMaps map[string]http.HandlerFunc
179 181
180 func init() { 182 func init() {
181 ErrorMaps = make(map[string]http.HandlerFunc) 183 ErrorMaps = make(map[string]http.HandlerFunc)
182 } 184 }
183 185
184 //404 186 // show 404 notfound error.
185 func NotFound(rw http.ResponseWriter, r *http.Request) { 187 func NotFound(rw http.ResponseWriter, r *http.Request) {
186 t, _ := template.New("beegoerrortemp").Parse(errtpl) 188 t, _ := template.New("beegoerrortemp").Parse(errtpl)
187 data := make(map[string]interface{}) 189 data := make(map[string]interface{})
...@@ -199,7 +201,7 @@ func NotFound(rw http.ResponseWriter, r *http.Request) { ...@@ -199,7 +201,7 @@ func NotFound(rw http.ResponseWriter, r *http.Request) {
199 t.Execute(rw, data) 201 t.Execute(rw, data)
200 } 202 }
201 203
202 //401 204 // show 401 unauthorized error.
203 func Unauthorized(rw http.ResponseWriter, r *http.Request) { 205 func Unauthorized(rw http.ResponseWriter, r *http.Request) {
204 t, _ := template.New("beegoerrortemp").Parse(errtpl) 206 t, _ := template.New("beegoerrortemp").Parse(errtpl)
205 data := make(map[string]interface{}) 207 data := make(map[string]interface{})
...@@ -215,7 +217,7 @@ func Unauthorized(rw http.ResponseWriter, r *http.Request) { ...@@ -215,7 +217,7 @@ func Unauthorized(rw http.ResponseWriter, r *http.Request) {
215 t.Execute(rw, data) 217 t.Execute(rw, data)
216 } 218 }
217 219
218 //403 220 // show 403 forbidden error.
219 func Forbidden(rw http.ResponseWriter, r *http.Request) { 221 func Forbidden(rw http.ResponseWriter, r *http.Request) {
220 t, _ := template.New("beegoerrortemp").Parse(errtpl) 222 t, _ := template.New("beegoerrortemp").Parse(errtpl)
221 data := make(map[string]interface{}) 223 data := make(map[string]interface{})
...@@ -232,7 +234,7 @@ func Forbidden(rw http.ResponseWriter, r *http.Request) { ...@@ -232,7 +234,7 @@ func Forbidden(rw http.ResponseWriter, r *http.Request) {
232 t.Execute(rw, data) 234 t.Execute(rw, data)
233 } 235 }
234 236
235 //503 237 // show 503 service unavailable error.
236 func ServiceUnavailable(rw http.ResponseWriter, r *http.Request) { 238 func ServiceUnavailable(rw http.ResponseWriter, r *http.Request) {
237 t, _ := template.New("beegoerrortemp").Parse(errtpl) 239 t, _ := template.New("beegoerrortemp").Parse(errtpl)
238 data := make(map[string]interface{}) 240 data := make(map[string]interface{})
...@@ -248,7 +250,7 @@ func ServiceUnavailable(rw http.ResponseWriter, r *http.Request) { ...@@ -248,7 +250,7 @@ func ServiceUnavailable(rw http.ResponseWriter, r *http.Request) {
248 t.Execute(rw, data) 250 t.Execute(rw, data)
249 } 251 }
250 252
251 //500 253 // show 500 internal server error.
252 func InternalServerError(rw http.ResponseWriter, r *http.Request) { 254 func InternalServerError(rw http.ResponseWriter, r *http.Request) {
253 t, _ := template.New("beegoerrortemp").Parse(errtpl) 255 t, _ := template.New("beegoerrortemp").Parse(errtpl)
254 data := make(map[string]interface{}) 256 data := make(map[string]interface{})
...@@ -262,15 +264,18 @@ func InternalServerError(rw http.ResponseWriter, r *http.Request) { ...@@ -262,15 +264,18 @@ func InternalServerError(rw http.ResponseWriter, r *http.Request) {
262 t.Execute(rw, data) 264 t.Execute(rw, data)
263 } 265 }
264 266
267 // show 500 internal error with simple text string.
265 func SimpleServerError(rw http.ResponseWriter, r *http.Request) { 268 func SimpleServerError(rw http.ResponseWriter, r *http.Request) {
266 http.Error(rw, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) 269 http.Error(rw, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
267 } 270 }
268 271
272 // add http handler for given error string.
269 func Errorhandler(err string, h http.HandlerFunc) { 273 func Errorhandler(err string, h http.HandlerFunc) {
270 ErrorMaps[err] = h 274 ErrorMaps[err] = h
271 } 275 }
272 276
273 func RegisterErrorHander() { 277 // register default error http handlers, 404,401,403,500 and 503.
278 func RegisterErrorHandler() {
274 if _, ok := ErrorMaps["404"]; !ok { 279 if _, ok := ErrorMaps["404"]; !ok {
275 ErrorMaps["404"] = NotFound 280 ErrorMaps["404"] = NotFound
276 } 281 }
...@@ -292,6 +297,8 @@ func RegisterErrorHander() { ...@@ -292,6 +297,8 @@ func RegisterErrorHander() {
292 } 297 }
293 } 298 }
294 299
300 // show error string as simple text message.
301 // if error string is empty, show 500 error as default.
295 func Exception(errcode string, w http.ResponseWriter, r *http.Request, msg string) { 302 func Exception(errcode string, w http.ResponseWriter, r *http.Request, msg string) {
296 if h, ok := ErrorMaps[errcode]; ok { 303 if h, ok := ErrorMaps[errcode]; ok {
297 isint, err := strconv.Atoi(errcode) 304 isint, err := strconv.Atoi(errcode)
......
...@@ -2,16 +2,19 @@ package middleware ...@@ -2,16 +2,19 @@ package middleware
2 2
3 import "fmt" 3 import "fmt"
4 4
5 // http exceptions
5 type HTTPException struct { 6 type HTTPException struct {
6 StatusCode int // http status code 4xx, 5xx 7 StatusCode int // http status code 4xx, 5xx
7 Description string 8 Description string
8 } 9 }
9 10
11 // return http exception error string, e.g. "400 Bad Request".
10 func (e *HTTPException) Error() string { 12 func (e *HTTPException) Error() string {
11 // return `status description`, e.g. `400 Bad Request`
12 return fmt.Sprintf("%d %s", e.StatusCode, e.Description) 13 return fmt.Sprintf("%d %s", e.StatusCode, e.Description)
13 } 14 }
14 15
16 // map of http exceptions for each http status code int.
17 // defined 400,401,403,404,405,500,502,503 and 504 default.
15 var HTTPExceptionMaps map[int]HTTPException 18 var HTTPExceptionMaps map[int]HTTPException
16 19
17 func init() { 20 func init() {
......
...@@ -16,6 +16,7 @@ var ( ...@@ -16,6 +16,7 @@ var (
16 commands = make(map[string]commander) 16 commands = make(map[string]commander)
17 ) 17 )
18 18
19 // print help.
19 func printHelp(errs ...string) { 20 func printHelp(errs ...string) {
20 content := `orm command usage: 21 content := `orm command usage:
21 22
...@@ -31,6 +32,7 @@ func printHelp(errs ...string) { ...@@ -31,6 +32,7 @@ func printHelp(errs ...string) {
31 os.Exit(2) 32 os.Exit(2)
32 } 33 }
33 34
35 // listen for orm command and then run it if command arguments passed.
34 func RunCommand() { 36 func RunCommand() {
35 if len(os.Args) < 2 || os.Args[1] != "orm" { 37 if len(os.Args) < 2 || os.Args[1] != "orm" {
36 return 38 return
...@@ -58,6 +60,7 @@ func RunCommand() { ...@@ -58,6 +60,7 @@ func RunCommand() {
58 } 60 }
59 } 61 }
60 62
63 // sync database struct command interface.
61 type commandSyncDb struct { 64 type commandSyncDb struct {
62 al *alias 65 al *alias
63 force bool 66 force bool
...@@ -66,6 +69,7 @@ type commandSyncDb struct { ...@@ -66,6 +69,7 @@ type commandSyncDb struct {
66 rtOnError bool 69 rtOnError bool
67 } 70 }
68 71
72 // parse orm command line arguments.
69 func (d *commandSyncDb) Parse(args []string) { 73 func (d *commandSyncDb) Parse(args []string) {
70 var name string 74 var name string
71 75
...@@ -78,6 +82,7 @@ func (d *commandSyncDb) Parse(args []string) { ...@@ -78,6 +82,7 @@ func (d *commandSyncDb) Parse(args []string) {
78 d.al = getDbAlias(name) 82 d.al = getDbAlias(name)
79 } 83 }
80 84
85 // run orm line command.
81 func (d *commandSyncDb) Run() error { 86 func (d *commandSyncDb) Run() error {
82 var drops []string 87 var drops []string
83 if d.force { 88 if d.force {
...@@ -208,10 +213,12 @@ func (d *commandSyncDb) Run() error { ...@@ -208,10 +213,12 @@ func (d *commandSyncDb) Run() error {
208 return nil 213 return nil
209 } 214 }
210 215
216 // database creation commander interface implement.
211 type commandSqlAll struct { 217 type commandSqlAll struct {
212 al *alias 218 al *alias
213 } 219 }
214 220
221 // parse orm command line arguments.
215 func (d *commandSqlAll) Parse(args []string) { 222 func (d *commandSqlAll) Parse(args []string) {
216 var name string 223 var name string
217 224
...@@ -222,6 +229,7 @@ func (d *commandSqlAll) Parse(args []string) { ...@@ -222,6 +229,7 @@ func (d *commandSqlAll) Parse(args []string) {
222 d.al = getDbAlias(name) 229 d.al = getDbAlias(name)
223 } 230 }
224 231
232 // run orm line command.
225 func (d *commandSqlAll) Run() error { 233 func (d *commandSqlAll) Run() error {
226 sqls, indexes := getDbCreateSql(d.al) 234 sqls, indexes := getDbCreateSql(d.al)
227 var all []string 235 var all []string
...@@ -243,6 +251,10 @@ func init() { ...@@ -243,6 +251,10 @@ func init() {
243 commands["sqlall"] = new(commandSqlAll) 251 commands["sqlall"] = new(commandSqlAll)
244 } 252 }
245 253
254 // run syncdb command line.
255 // name means table's alias name. default is "default".
256 // force means run next sql if the current is error.
257 // verbose means show all info when running command or not.
246 func RunSyncdb(name string, force bool, verbose bool) error { 258 func RunSyncdb(name string, force bool, verbose bool) error {
247 BootStrap() 259 BootStrap()
248 260
......
...@@ -12,6 +12,7 @@ type dbIndex struct { ...@@ -12,6 +12,7 @@ type dbIndex struct {
12 Sql string 12 Sql string
13 } 13 }
14 14
15 // create database drop sql.
15 func getDbDropSql(al *alias) (sqls []string) { 16 func getDbDropSql(al *alias) (sqls []string) {
16 if len(modelCache.cache) == 0 { 17 if len(modelCache.cache) == 0 {
17 fmt.Println("no Model found, need register your model") 18 fmt.Println("no Model found, need register your model")
...@@ -26,6 +27,7 @@ func getDbDropSql(al *alias) (sqls []string) { ...@@ -26,6 +27,7 @@ func getDbDropSql(al *alias) (sqls []string) {
26 return sqls 27 return sqls
27 } 28 }
28 29
30 // get database column type string.
29 func getColumnTyp(al *alias, fi *fieldInfo) (col string) { 31 func getColumnTyp(al *alias, fi *fieldInfo) (col string) {
30 T := al.DbBaser.DbTypes() 32 T := al.DbBaser.DbTypes()
31 fieldType := fi.fieldType 33 fieldType := fi.fieldType
...@@ -79,6 +81,7 @@ checkColumn: ...@@ -79,6 +81,7 @@ checkColumn:
79 return 81 return
80 } 82 }
81 83
84 // create alter sql string.
82 func getColumnAddQuery(al *alias, fi *fieldInfo) string { 85 func getColumnAddQuery(al *alias, fi *fieldInfo) string {
83 Q := al.DbBaser.TableQuote() 86 Q := al.DbBaser.TableQuote()
84 typ := getColumnTyp(al, fi) 87 typ := getColumnTyp(al, fi)
...@@ -90,6 +93,7 @@ func getColumnAddQuery(al *alias, fi *fieldInfo) string { ...@@ -90,6 +93,7 @@ func getColumnAddQuery(al *alias, fi *fieldInfo) string {
90 return fmt.Sprintf("ALTER TABLE %s%s%s ADD COLUMN %s%s%s %s", Q, fi.mi.table, Q, Q, fi.column, Q, typ) 93 return fmt.Sprintf("ALTER TABLE %s%s%s ADD COLUMN %s%s%s %s", Q, fi.mi.table, Q, Q, fi.column, Q, typ)
91 } 94 }
92 95
96 // create database creation string.
93 func getDbCreateSql(al *alias) (sqls []string, tableIndexes map[string][]dbIndex) { 97 func getDbCreateSql(al *alias) (sqls []string, tableIndexes map[string][]dbIndex) {
94 if len(modelCache.cache) == 0 { 98 if len(modelCache.cache) == 0 {
95 fmt.Println("no Model found, need register your model") 99 fmt.Println("no Model found, need register your model")
......
...@@ -15,7 +15,7 @@ const ( ...@@ -15,7 +15,7 @@ const (
15 ) 15 )
16 16
17 var ( 17 var (
18 ErrMissPK = errors.New("missed pk value") 18 ErrMissPK = errors.New("missed pk value") // missing pk error
19 ) 19 )
20 20
21 var ( 21 var (
...@@ -45,12 +45,15 @@ var ( ...@@ -45,12 +45,15 @@ var (
45 } 45 }
46 ) 46 )
47 47
48 // an instance of dbBaser interface/
48 type dbBase struct { 49 type dbBase struct {
49 ins dbBaser 50 ins dbBaser
50 } 51 }
51 52
53 // check dbBase implements dbBaser interface.
52 var _ dbBaser = new(dbBase) 54 var _ dbBaser = new(dbBase)
53 55
56 // get struct columns values as interface slice.
54 func (d *dbBase) collectValues(mi *modelInfo, ind reflect.Value, cols []string, skipAuto bool, insert bool, names *[]string, tz *time.Location) (values []interface{}, err error) { 57 func (d *dbBase) collectValues(mi *modelInfo, ind reflect.Value, cols []string, skipAuto bool, insert bool, names *[]string, tz *time.Location) (values []interface{}, err error) {
55 var columns []string 58 var columns []string
56 59
...@@ -87,6 +90,7 @@ func (d *dbBase) collectValues(mi *modelInfo, ind reflect.Value, cols []string, ...@@ -87,6 +90,7 @@ func (d *dbBase) collectValues(mi *modelInfo, ind reflect.Value, cols []string,
87 return 90 return
88 } 91 }
89 92
93 // get one field value in struct column as interface.
90 func (d *dbBase) collectFieldValue(mi *modelInfo, fi *fieldInfo, ind reflect.Value, insert bool, tz *time.Location) (interface{}, error) { 94 func (d *dbBase) collectFieldValue(mi *modelInfo, fi *fieldInfo, ind reflect.Value, insert bool, tz *time.Location) (interface{}, error) {
91 var value interface{} 95 var value interface{}
92 if fi.pk { 96 if fi.pk {
...@@ -155,6 +159,7 @@ func (d *dbBase) collectFieldValue(mi *modelInfo, fi *fieldInfo, ind reflect.Val ...@@ -155,6 +159,7 @@ func (d *dbBase) collectFieldValue(mi *modelInfo, fi *fieldInfo, ind reflect.Val
155 return value, nil 159 return value, nil
156 } 160 }
157 161
162 // create insert sql preparation statement object.
158 func (d *dbBase) PrepareInsert(q dbQuerier, mi *modelInfo) (stmtQuerier, string, error) { 163 func (d *dbBase) PrepareInsert(q dbQuerier, mi *modelInfo) (stmtQuerier, string, error) {
159 Q := d.ins.TableQuote() 164 Q := d.ins.TableQuote()
160 165
...@@ -180,6 +185,7 @@ func (d *dbBase) PrepareInsert(q dbQuerier, mi *modelInfo) (stmtQuerier, string, ...@@ -180,6 +185,7 @@ func (d *dbBase) PrepareInsert(q dbQuerier, mi *modelInfo) (stmtQuerier, string,
180 return stmt, query, err 185 return stmt, query, err
181 } 186 }
182 187
188 // insert struct with prepared statement and given struct reflect value.
183 func (d *dbBase) InsertStmt(stmt stmtQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location) (int64, error) { 189 func (d *dbBase) InsertStmt(stmt stmtQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location) (int64, error) {
184 values, err := d.collectValues(mi, ind, mi.fields.dbcols, true, true, nil, tz) 190 values, err := d.collectValues(mi, ind, mi.fields.dbcols, true, true, nil, tz)
185 if err != nil { 191 if err != nil {
...@@ -200,6 +206,7 @@ func (d *dbBase) InsertStmt(stmt stmtQuerier, mi *modelInfo, ind reflect.Value, ...@@ -200,6 +206,7 @@ func (d *dbBase) InsertStmt(stmt stmtQuerier, mi *modelInfo, ind reflect.Value,
200 } 206 }
201 } 207 }
202 208
209 // query sql ,read records and persist in dbBaser.
203 func (d *dbBase) Read(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location, cols []string) error { 210 func (d *dbBase) Read(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location, cols []string) error {
204 var whereCols []string 211 var whereCols []string
205 var args []interface{} 212 var args []interface{}
...@@ -259,6 +266,7 @@ func (d *dbBase) Read(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Lo ...@@ -259,6 +266,7 @@ func (d *dbBase) Read(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Lo
259 return nil 266 return nil
260 } 267 }
261 268
269 // execute insert sql dbQuerier with given struct reflect.Value.
262 func (d *dbBase) Insert(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location) (int64, error) { 270 func (d *dbBase) Insert(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location) (int64, error) {
263 names := make([]string, 0, len(mi.fields.dbcols)-1) 271 names := make([]string, 0, len(mi.fields.dbcols)-1)
264 values, err := d.collectValues(mi, ind, mi.fields.dbcols, true, true, &names, tz) 272 values, err := d.collectValues(mi, ind, mi.fields.dbcols, true, true, &names, tz)
...@@ -269,6 +277,7 @@ func (d *dbBase) Insert(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time. ...@@ -269,6 +277,7 @@ func (d *dbBase) Insert(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.
269 return d.InsertValue(q, mi, false, names, values) 277 return d.InsertValue(q, mi, false, names, values)
270 } 278 }
271 279
280 // multi-insert sql with given slice struct reflect.Value.
272 func (d *dbBase) InsertMulti(q dbQuerier, mi *modelInfo, sind reflect.Value, bulk int, tz *time.Location) (int64, error) { 281 func (d *dbBase) InsertMulti(q dbQuerier, mi *modelInfo, sind reflect.Value, bulk int, tz *time.Location) (int64, error) {
273 var ( 282 var (
274 cnt int64 283 cnt int64
...@@ -325,6 +334,8 @@ func (d *dbBase) InsertMulti(q dbQuerier, mi *modelInfo, sind reflect.Value, bul ...@@ -325,6 +334,8 @@ func (d *dbBase) InsertMulti(q dbQuerier, mi *modelInfo, sind reflect.Value, bul
325 return cnt, nil 334 return cnt, nil
326 } 335 }
327 336
337 // execute insert sql with given struct and given values.
338 // insert the given values, not the field values in struct.
328 func (d *dbBase) InsertValue(q dbQuerier, mi *modelInfo, isMulti bool, names []string, values []interface{}) (int64, error) { 339 func (d *dbBase) InsertValue(q dbQuerier, mi *modelInfo, isMulti bool, names []string, values []interface{}) (int64, error) {
329 Q := d.ins.TableQuote() 340 Q := d.ins.TableQuote()
330 341
...@@ -364,6 +375,7 @@ func (d *dbBase) InsertValue(q dbQuerier, mi *modelInfo, isMulti bool, names []s ...@@ -364,6 +375,7 @@ func (d *dbBase) InsertValue(q dbQuerier, mi *modelInfo, isMulti bool, names []s
364 } 375 }
365 } 376 }
366 377
378 // execute update sql dbQuerier with given struct reflect.Value.
367 func (d *dbBase) Update(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location, cols []string) (int64, error) { 379 func (d *dbBase) Update(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location, cols []string) (int64, error) {
368 pkName, pkValue, ok := getExistPk(mi, ind) 380 pkName, pkValue, ok := getExistPk(mi, ind)
369 if ok == false { 381 if ok == false {
...@@ -404,6 +416,8 @@ func (d *dbBase) Update(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time. ...@@ -404,6 +416,8 @@ func (d *dbBase) Update(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.
404 return 0, nil 416 return 0, nil
405 } 417 }
406 418
419 // execute delete sql dbQuerier with given struct reflect.Value.
420 // delete index is pk.
407 func (d *dbBase) Delete(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location) (int64, error) { 421 func (d *dbBase) Delete(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.Location) (int64, error) {
408 pkName, pkValue, ok := getExistPk(mi, ind) 422 pkName, pkValue, ok := getExistPk(mi, ind)
409 if ok == false { 423 if ok == false {
...@@ -445,6 +459,8 @@ func (d *dbBase) Delete(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time. ...@@ -445,6 +459,8 @@ func (d *dbBase) Delete(q dbQuerier, mi *modelInfo, ind reflect.Value, tz *time.
445 return 0, nil 459 return 0, nil
446 } 460 }
447 461
462 // update table-related record by querySet.
463 // need querySet not struct reflect.Value to update related records.
448 func (d *dbBase) UpdateBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition, params Params, tz *time.Location) (int64, error) { 464 func (d *dbBase) UpdateBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition, params Params, tz *time.Location) (int64, error) {
449 columns := make([]string, 0, len(params)) 465 columns := make([]string, 0, len(params))
450 values := make([]interface{}, 0, len(params)) 466 values := make([]interface{}, 0, len(params))
...@@ -520,6 +536,8 @@ func (d *dbBase) UpdateBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Con ...@@ -520,6 +536,8 @@ func (d *dbBase) UpdateBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Con
520 return 0, nil 536 return 0, nil
521 } 537 }
522 538
539 // delete related records.
540 // do UpdateBanch or DeleteBanch by condition of tables' relationship.
523 func (d *dbBase) deleteRels(q dbQuerier, mi *modelInfo, args []interface{}, tz *time.Location) error { 541 func (d *dbBase) deleteRels(q dbQuerier, mi *modelInfo, args []interface{}, tz *time.Location) error {
524 for _, fi := range mi.fields.fieldsReverse { 542 for _, fi := range mi.fields.fieldsReverse {
525 fi = fi.reverseFieldInfo 543 fi = fi.reverseFieldInfo
...@@ -546,6 +564,7 @@ func (d *dbBase) deleteRels(q dbQuerier, mi *modelInfo, args []interface{}, tz * ...@@ -546,6 +564,7 @@ func (d *dbBase) deleteRels(q dbQuerier, mi *modelInfo, args []interface{}, tz *
546 return nil 564 return nil
547 } 565 }
548 566
567 // delete table-related records.
549 func (d *dbBase) DeleteBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition, tz *time.Location) (int64, error) { 568 func (d *dbBase) DeleteBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition, tz *time.Location) (int64, error) {
550 tables := newDbTables(mi, d.ins) 569 tables := newDbTables(mi, d.ins)
551 tables.skipEnd = true 570 tables.skipEnd = true
...@@ -623,6 +642,7 @@ func (d *dbBase) DeleteBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Con ...@@ -623,6 +642,7 @@ func (d *dbBase) DeleteBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Con
623 return 0, nil 642 return 0, nil
624 } 643 }
625 644
645 // read related records.
626 func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition, container interface{}, tz *time.Location, cols []string) (int64, error) { 646 func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition, container interface{}, tz *time.Location, cols []string) (int64, error) {
627 647
628 val := reflect.ValueOf(container) 648 val := reflect.ValueOf(container)
...@@ -832,6 +852,7 @@ func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condi ...@@ -832,6 +852,7 @@ func (d *dbBase) ReadBatch(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condi
832 return cnt, nil 852 return cnt, nil
833 } 853 }
834 854
855 // excute count sql and return count result int64.
835 func (d *dbBase) Count(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition, tz *time.Location) (cnt int64, err error) { 856 func (d *dbBase) Count(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition, tz *time.Location) (cnt int64, err error) {
836 tables := newDbTables(mi, d.ins) 857 tables := newDbTables(mi, d.ins)
837 tables.parseRelated(qs.related, qs.relDepth) 858 tables.parseRelated(qs.related, qs.relDepth)
...@@ -852,6 +873,7 @@ func (d *dbBase) Count(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition ...@@ -852,6 +873,7 @@ func (d *dbBase) Count(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition
852 return 873 return
853 } 874 }
854 875
876 // generate sql with replacing operator string placeholders and replaced values.
855 func (d *dbBase) GenerateOperatorSql(mi *modelInfo, fi *fieldInfo, operator string, args []interface{}, tz *time.Location) (string, []interface{}) { 877 func (d *dbBase) GenerateOperatorSql(mi *modelInfo, fi *fieldInfo, operator string, args []interface{}, tz *time.Location) (string, []interface{}) {
856 sql := "" 878 sql := ""
857 params := getFlatParams(fi, args, tz) 879 params := getFlatParams(fi, args, tz)
...@@ -905,10 +927,12 @@ func (d *dbBase) GenerateOperatorSql(mi *modelInfo, fi *fieldInfo, operator stri ...@@ -905,10 +927,12 @@ func (d *dbBase) GenerateOperatorSql(mi *modelInfo, fi *fieldInfo, operator stri
905 return sql, params 927 return sql, params
906 } 928 }
907 929
930 // gernerate sql string with inner function, such as UPPER(text).
908 func (d *dbBase) GenerateOperatorLeftCol(*fieldInfo, string, *string) { 931 func (d *dbBase) GenerateOperatorLeftCol(*fieldInfo, string, *string) {
909 // default not use 932 // default not use
910 } 933 }
911 934
935 // set values to struct column.
912 func (d *dbBase) setColsValues(mi *modelInfo, ind *reflect.Value, cols []string, values []interface{}, tz *time.Location) { 936 func (d *dbBase) setColsValues(mi *modelInfo, ind *reflect.Value, cols []string, values []interface{}, tz *time.Location) {
913 for i, column := range cols { 937 for i, column := range cols {
914 val := reflect.Indirect(reflect.ValueOf(values[i])).Interface() 938 val := reflect.Indirect(reflect.ValueOf(values[i])).Interface()
...@@ -930,6 +954,7 @@ func (d *dbBase) setColsValues(mi *modelInfo, ind *reflect.Value, cols []string, ...@@ -930,6 +954,7 @@ func (d *dbBase) setColsValues(mi *modelInfo, ind *reflect.Value, cols []string,
930 } 954 }
931 } 955 }
932 956
957 // convert value from database result to value following in field type.
933 func (d *dbBase) convertValueFromDB(fi *fieldInfo, val interface{}, tz *time.Location) (interface{}, error) { 958 func (d *dbBase) convertValueFromDB(fi *fieldInfo, val interface{}, tz *time.Location) (interface{}, error) {
934 if val == nil { 959 if val == nil {
935 return nil, nil 960 return nil, nil
...@@ -1082,6 +1107,7 @@ end: ...@@ -1082,6 +1107,7 @@ end:
1082 1107
1083 } 1108 }
1084 1109
1110 // set one value to struct column field.
1085 func (d *dbBase) setFieldValue(fi *fieldInfo, value interface{}, field reflect.Value) (interface{}, error) { 1111 func (d *dbBase) setFieldValue(fi *fieldInfo, value interface{}, field reflect.Value) (interface{}, error) {
1086 1112
1087 fieldType := fi.fieldType 1113 fieldType := fi.fieldType
...@@ -1156,6 +1182,7 @@ setValue: ...@@ -1156,6 +1182,7 @@ setValue:
1156 return value, nil 1182 return value, nil
1157 } 1183 }
1158 1184
1185 // query sql, read values , save to *[]ParamList.
1159 func (d *dbBase) ReadValues(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition, exprs []string, container interface{}, tz *time.Location) (int64, error) { 1186 func (d *dbBase) ReadValues(q dbQuerier, qs *querySet, mi *modelInfo, cond *Condition, exprs []string, container interface{}, tz *time.Location) (int64, error) {
1160 1187
1161 var ( 1188 var (
...@@ -1323,6 +1350,7 @@ func (d *dbBase) ReadValues(q dbQuerier, qs *querySet, mi *modelInfo, cond *Cond ...@@ -1323,6 +1350,7 @@ func (d *dbBase) ReadValues(q dbQuerier, qs *querySet, mi *modelInfo, cond *Cond
1323 return cnt, nil 1350 return cnt, nil
1324 } 1351 }
1325 1352
1353 // flag of update joined record.
1326 func (d *dbBase) SupportUpdateJoin() bool { 1354 func (d *dbBase) SupportUpdateJoin() bool {
1327 return true 1355 return true
1328 } 1356 }
...@@ -1331,30 +1359,37 @@ func (d *dbBase) MaxLimit() uint64 { ...@@ -1331,30 +1359,37 @@ func (d *dbBase) MaxLimit() uint64 {
1331 return 18446744073709551615 1359 return 18446744073709551615
1332 } 1360 }
1333 1361
1362 // return quote.
1334 func (d *dbBase) TableQuote() string { 1363 func (d *dbBase) TableQuote() string {
1335 return "`" 1364 return "`"
1336 } 1365 }
1337 1366
1367 // replace value placeholer in parametered sql string.
1338 func (d *dbBase) ReplaceMarks(query *string) { 1368 func (d *dbBase) ReplaceMarks(query *string) {
1339 // default use `?` as mark, do nothing 1369 // default use `?` as mark, do nothing
1340 } 1370 }
1341 1371
1372 // flag of RETURNING sql.
1342 func (d *dbBase) HasReturningID(*modelInfo, *string) bool { 1373 func (d *dbBase) HasReturningID(*modelInfo, *string) bool {
1343 return false 1374 return false
1344 } 1375 }
1345 1376
1377 // convert time from db.
1346 func (d *dbBase) TimeFromDB(t *time.Time, tz *time.Location) { 1378 func (d *dbBase) TimeFromDB(t *time.Time, tz *time.Location) {
1347 *t = t.In(tz) 1379 *t = t.In(tz)
1348 } 1380 }
1349 1381
1382 // convert time to db.
1350 func (d *dbBase) TimeToDB(t *time.Time, tz *time.Location) { 1383 func (d *dbBase) TimeToDB(t *time.Time, tz *time.Location) {
1351 *t = t.In(tz) 1384 *t = t.In(tz)
1352 } 1385 }
1353 1386
1387 // get database types.
1354 func (d *dbBase) DbTypes() map[string]string { 1388 func (d *dbBase) DbTypes() map[string]string {
1355 return nil 1389 return nil
1356 } 1390 }
1357 1391
1392 // gt all tables.
1358 func (d *dbBase) GetTables(db dbQuerier) (map[string]bool, error) { 1393 func (d *dbBase) GetTables(db dbQuerier) (map[string]bool, error) {
1359 tables := make(map[string]bool) 1394 tables := make(map[string]bool)
1360 query := d.ins.ShowTablesQuery() 1395 query := d.ins.ShowTablesQuery()
...@@ -1379,6 +1414,7 @@ func (d *dbBase) GetTables(db dbQuerier) (map[string]bool, error) { ...@@ -1379,6 +1414,7 @@ func (d *dbBase) GetTables(db dbQuerier) (map[string]bool, error) {
1379 return tables, nil 1414 return tables, nil
1380 } 1415 }
1381 1416
1417 // get all cloumns in table.
1382 func (d *dbBase) GetColumns(db dbQuerier, table string) (map[string][3]string, error) { 1418 func (d *dbBase) GetColumns(db dbQuerier, table string) (map[string][3]string, error) {
1383 columns := make(map[string][3]string) 1419 columns := make(map[string][3]string)
1384 query := d.ins.ShowColumnsQuery(table) 1420 query := d.ins.ShowColumnsQuery(table)
...@@ -1405,18 +1441,22 @@ func (d *dbBase) GetColumns(db dbQuerier, table string) (map[string][3]string, e ...@@ -1405,18 +1441,22 @@ func (d *dbBase) GetColumns(db dbQuerier, table string) (map[string][3]string, e
1405 return columns, nil 1441 return columns, nil
1406 } 1442 }
1407 1443
1444 // not implement.
1408 func (d *dbBase) OperatorSql(operator string) string { 1445 func (d *dbBase) OperatorSql(operator string) string {
1409 panic(ErrNotImplement) 1446 panic(ErrNotImplement)
1410 } 1447 }
1411 1448
1449 // not implement.
1412 func (d *dbBase) ShowTablesQuery() string { 1450 func (d *dbBase) ShowTablesQuery() string {
1413 panic(ErrNotImplement) 1451 panic(ErrNotImplement)
1414 } 1452 }
1415 1453
1454 // not implement.
1416 func (d *dbBase) ShowColumnsQuery(table string) string { 1455 func (d *dbBase) ShowColumnsQuery(table string) string {
1417 panic(ErrNotImplement) 1456 panic(ErrNotImplement)
1418 } 1457 }
1419 1458
1459 // not implement.
1420 func (d *dbBase) IndexExists(dbQuerier, string, string) bool { 1460 func (d *dbBase) IndexExists(dbQuerier, string, string) bool {
1421 panic(ErrNotImplement) 1461 panic(ErrNotImplement)
1422 } 1462 }
......
...@@ -9,27 +9,32 @@ import ( ...@@ -9,27 +9,32 @@ import (
9 "time" 9 "time"
10 ) 10 )
11 11
12 // database driver constant int.
12 type DriverType int 13 type DriverType int
13 14
14 const ( 15 const (
15 _ DriverType = iota 16 _ DriverType = iota // int enum type
16 DR_MySQL 17 DR_MySQL // mysql
17 DR_Sqlite 18 DR_Sqlite // sqlite
18 DR_Oracle 19 DR_Oracle // oracle
19 DR_Postgres 20 DR_Postgres // pgsql
20 ) 21 )
21 22
23 // database driver string.
22 type driver string 24 type driver string
23 25
26 // get type constant int of current driver..
24 func (d driver) Type() DriverType { 27 func (d driver) Type() DriverType {
25 a, _ := dataBaseCache.get(string(d)) 28 a, _ := dataBaseCache.get(string(d))
26 return a.Driver 29 return a.Driver
27 } 30 }
28 31
32 // get name of current driver
29 func (d driver) Name() string { 33 func (d driver) Name() string {
30 return string(d) 34 return string(d)
31 } 35 }
32 36
37 // check driver iis implemented Driver interface or not.
33 var _ Driver = new(driver) 38 var _ Driver = new(driver)
34 39
35 var ( 40 var (
...@@ -47,11 +52,13 @@ var ( ...@@ -47,11 +52,13 @@ var (
47 } 52 }
48 ) 53 )
49 54
55 // database alias cacher.
50 type _dbCache struct { 56 type _dbCache struct {
51 mux sync.RWMutex 57 mux sync.RWMutex
52 cache map[string]*alias 58 cache map[string]*alias
53 } 59 }
54 60
61 // add database alias with original name.
55 func (ac *_dbCache) add(name string, al *alias) (added bool) { 62 func (ac *_dbCache) add(name string, al *alias) (added bool) {
56 ac.mux.Lock() 63 ac.mux.Lock()
57 defer ac.mux.Unlock() 64 defer ac.mux.Unlock()
...@@ -62,6 +69,7 @@ func (ac *_dbCache) add(name string, al *alias) (added bool) { ...@@ -62,6 +69,7 @@ func (ac *_dbCache) add(name string, al *alias) (added bool) {
62 return 69 return
63 } 70 }
64 71
72 // get database alias if cached.
65 func (ac *_dbCache) get(name string) (al *alias, ok bool) { 73 func (ac *_dbCache) get(name string) (al *alias, ok bool) {
66 ac.mux.RLock() 74 ac.mux.RLock()
67 defer ac.mux.RUnlock() 75 defer ac.mux.RUnlock()
...@@ -69,6 +77,7 @@ func (ac *_dbCache) get(name string) (al *alias, ok bool) { ...@@ -69,6 +77,7 @@ func (ac *_dbCache) get(name string) (al *alias, ok bool) {
69 return 77 return
70 } 78 }
71 79
80 // get default alias.
72 func (ac *_dbCache) getDefault() (al *alias) { 81 func (ac *_dbCache) getDefault() (al *alias) {
73 al, _ = ac.get("default") 82 al, _ = ac.get("default")
74 return 83 return
......
...@@ -4,6 +4,7 @@ import ( ...@@ -4,6 +4,7 @@ import (
4 "fmt" 4 "fmt"
5 ) 5 )
6 6
7 // mysql operators.
7 var mysqlOperators = map[string]string{ 8 var mysqlOperators = map[string]string{
8 "exact": "= ?", 9 "exact": "= ?",
9 "iexact": "LIKE ?", 10 "iexact": "LIKE ?",
...@@ -21,6 +22,7 @@ var mysqlOperators = map[string]string{ ...@@ -21,6 +22,7 @@ var mysqlOperators = map[string]string{
21 "iendswith": "LIKE ?", 22 "iendswith": "LIKE ?",
22 } 23 }
23 24
25 // mysql column field types.
24 var mysqlTypes = map[string]string{ 26 var mysqlTypes = map[string]string{
25 "auto": "AUTO_INCREMENT NOT NULL PRIMARY KEY", 27 "auto": "AUTO_INCREMENT NOT NULL PRIMARY KEY",
26 "pk": "NOT NULL PRIMARY KEY", 28 "pk": "NOT NULL PRIMARY KEY",
...@@ -41,29 +43,35 @@ var mysqlTypes = map[string]string{ ...@@ -41,29 +43,35 @@ var mysqlTypes = map[string]string{
41 "float64-decimal": "numeric(%d, %d)", 43 "float64-decimal": "numeric(%d, %d)",
42 } 44 }
43 45
46 // mysql dbBaser implementation.
44 type dbBaseMysql struct { 47 type dbBaseMysql struct {
45 dbBase 48 dbBase
46 } 49 }
47 50
48 var _ dbBaser = new(dbBaseMysql) 51 var _ dbBaser = new(dbBaseMysql)
49 52
53 // get mysql operator.
50 func (d *dbBaseMysql) OperatorSql(operator string) string { 54 func (d *dbBaseMysql) OperatorSql(operator string) string {
51 return mysqlOperators[operator] 55 return mysqlOperators[operator]
52 } 56 }
53 57
58 // get mysql table field types.
54 func (d *dbBaseMysql) DbTypes() map[string]string { 59 func (d *dbBaseMysql) DbTypes() map[string]string {
55 return mysqlTypes 60 return mysqlTypes
56 } 61 }
57 62
63 // show table sql for mysql.
58 func (d *dbBaseMysql) ShowTablesQuery() string { 64 func (d *dbBaseMysql) ShowTablesQuery() string {
59 return "SELECT table_name FROM information_schema.tables WHERE table_type = 'BASE TABLE' AND table_schema = DATABASE()" 65 return "SELECT table_name FROM information_schema.tables WHERE table_type = 'BASE TABLE' AND table_schema = DATABASE()"
60 } 66 }
61 67
68 // show columns sql of table for mysql.
62 func (d *dbBaseMysql) ShowColumnsQuery(table string) string { 69 func (d *dbBaseMysql) ShowColumnsQuery(table string) string {
63 return fmt.Sprintf("SELECT COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE FROM information_schema.columns "+ 70 return fmt.Sprintf("SELECT COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE FROM information_schema.columns "+
64 "WHERE table_schema = DATABASE() AND table_name = '%s'", table) 71 "WHERE table_schema = DATABASE() AND table_name = '%s'", table)
65 } 72 }
66 73
74 // execute sql to check index exist.
67 func (d *dbBaseMysql) IndexExists(db dbQuerier, table string, name string) bool { 75 func (d *dbBaseMysql) IndexExists(db dbQuerier, table string, name string) bool {
68 row := db.QueryRow("SELECT count(*) FROM information_schema.statistics "+ 76 row := db.QueryRow("SELECT count(*) FROM information_schema.statistics "+
69 "WHERE table_schema = DATABASE() AND table_name = ? AND index_name = ?", table, name) 77 "WHERE table_schema = DATABASE() AND table_name = ? AND index_name = ?", table, name)
...@@ -72,6 +80,7 @@ func (d *dbBaseMysql) IndexExists(db dbQuerier, table string, name string) bool ...@@ -72,6 +80,7 @@ func (d *dbBaseMysql) IndexExists(db dbQuerier, table string, name string) bool
72 return cnt > 0 80 return cnt > 0
73 } 81 }
74 82
83 // create new mysql dbBaser.
75 func newdbBaseMysql() dbBaser { 84 func newdbBaseMysql() dbBaser {
76 b := new(dbBaseMysql) 85 b := new(dbBaseMysql)
77 b.ins = b 86 b.ins = b
......
1 package orm 1 package orm
2 2
3 // oracle dbBaser
3 type dbBaseOracle struct { 4 type dbBaseOracle struct {
4 dbBase 5 dbBase
5 } 6 }
6 7
7 var _ dbBaser = new(dbBaseOracle) 8 var _ dbBaser = new(dbBaseOracle)
8 9
10 // create oracle dbBaser.
9 func newdbBaseOracle() dbBaser { 11 func newdbBaseOracle() dbBaser {
10 b := new(dbBaseOracle) 12 b := new(dbBaseOracle)
11 b.ins = b 13 b.ins = b
......
...@@ -5,6 +5,7 @@ import ( ...@@ -5,6 +5,7 @@ import (
5 "strconv" 5 "strconv"
6 ) 6 )
7 7
8 // postgresql operators.
8 var postgresOperators = map[string]string{ 9 var postgresOperators = map[string]string{
9 "exact": "= ?", 10 "exact": "= ?",
10 "iexact": "= UPPER(?)", 11 "iexact": "= UPPER(?)",
...@@ -20,6 +21,7 @@ var postgresOperators = map[string]string{ ...@@ -20,6 +21,7 @@ var postgresOperators = map[string]string{
20 "iendswith": "LIKE UPPER(?)", 21 "iendswith": "LIKE UPPER(?)",
21 } 22 }
22 23
24 // postgresql column field types.
23 var postgresTypes = map[string]string{ 25 var postgresTypes = map[string]string{
24 "auto": "serial NOT NULL PRIMARY KEY", 26 "auto": "serial NOT NULL PRIMARY KEY",
25 "pk": "NOT NULL PRIMARY KEY", 27 "pk": "NOT NULL PRIMARY KEY",
...@@ -40,16 +42,19 @@ var postgresTypes = map[string]string{ ...@@ -40,16 +42,19 @@ var postgresTypes = map[string]string{
40 "float64-decimal": "numeric(%d, %d)", 42 "float64-decimal": "numeric(%d, %d)",
41 } 43 }
42 44
45 // postgresql dbBaser.
43 type dbBasePostgres struct { 46 type dbBasePostgres struct {
44 dbBase 47 dbBase
45 } 48 }
46 49
47 var _ dbBaser = new(dbBasePostgres) 50 var _ dbBaser = new(dbBasePostgres)
48 51
52 // get postgresql operator.
49 func (d *dbBasePostgres) OperatorSql(operator string) string { 53 func (d *dbBasePostgres) OperatorSql(operator string) string {
50 return postgresOperators[operator] 54 return postgresOperators[operator]
51 } 55 }
52 56
57 // generate functioned sql string, such as contains(text).
53 func (d *dbBasePostgres) GenerateOperatorLeftCol(fi *fieldInfo, operator string, leftCol *string) { 58 func (d *dbBasePostgres) GenerateOperatorLeftCol(fi *fieldInfo, operator string, leftCol *string) {
54 switch operator { 59 switch operator {
55 case "contains", "startswith", "endswith": 60 case "contains", "startswith", "endswith":
...@@ -59,6 +64,7 @@ func (d *dbBasePostgres) GenerateOperatorLeftCol(fi *fieldInfo, operator string, ...@@ -59,6 +64,7 @@ func (d *dbBasePostgres) GenerateOperatorLeftCol(fi *fieldInfo, operator string,
59 } 64 }
60 } 65 }
61 66
67 // postgresql unsupports updating joined record.
62 func (d *dbBasePostgres) SupportUpdateJoin() bool { 68 func (d *dbBasePostgres) SupportUpdateJoin() bool {
63 return false 69 return false
64 } 70 }
...@@ -67,10 +73,13 @@ func (d *dbBasePostgres) MaxLimit() uint64 { ...@@ -67,10 +73,13 @@ func (d *dbBasePostgres) MaxLimit() uint64 {
67 return 0 73 return 0
68 } 74 }
69 75
76 // postgresql quote is ".
70 func (d *dbBasePostgres) TableQuote() string { 77 func (d *dbBasePostgres) TableQuote() string {
71 return `"` 78 return `"`
72 } 79 }
73 80
81 // postgresql value placeholder is $n.
82 // replace default ? to $n.
74 func (d *dbBasePostgres) ReplaceMarks(query *string) { 83 func (d *dbBasePostgres) ReplaceMarks(query *string) {
75 q := *query 84 q := *query
76 num := 0 85 num := 0
...@@ -97,6 +106,7 @@ func (d *dbBasePostgres) ReplaceMarks(query *string) { ...@@ -97,6 +106,7 @@ func (d *dbBasePostgres) ReplaceMarks(query *string) {
97 *query = string(data) 106 *query = string(data)
98 } 107 }
99 108
109 // make returning sql support for postgresql.
100 func (d *dbBasePostgres) HasReturningID(mi *modelInfo, query *string) (has bool) { 110 func (d *dbBasePostgres) HasReturningID(mi *modelInfo, query *string) (has bool) {
101 if mi.fields.pk.auto { 111 if mi.fields.pk.auto {
102 if query != nil { 112 if query != nil {
...@@ -107,18 +117,22 @@ func (d *dbBasePostgres) HasReturningID(mi *modelInfo, query *string) (has bool) ...@@ -107,18 +117,22 @@ func (d *dbBasePostgres) HasReturningID(mi *modelInfo, query *string) (has bool)
107 return 117 return
108 } 118 }
109 119
120 // show table sql for postgresql.
110 func (d *dbBasePostgres) ShowTablesQuery() string { 121 func (d *dbBasePostgres) ShowTablesQuery() string {
111 return "SELECT table_name FROM information_schema.tables WHERE table_type = 'BASE TABLE' AND table_schema NOT IN ('pg_catalog', 'information_schema')" 122 return "SELECT table_name FROM information_schema.tables WHERE table_type = 'BASE TABLE' AND table_schema NOT IN ('pg_catalog', 'information_schema')"
112 } 123 }
113 124
125 // show table columns sql for postgresql.
114 func (d *dbBasePostgres) ShowColumnsQuery(table string) string { 126 func (d *dbBasePostgres) ShowColumnsQuery(table string) string {
115 return fmt.Sprintf("SELECT column_name, data_type, is_nullable FROM information_schema.columns where table_schema NOT IN ('pg_catalog', 'information_schema') and table_name = '%s'", table) 127 return fmt.Sprintf("SELECT column_name, data_type, is_nullable FROM information_schema.columns where table_schema NOT IN ('pg_catalog', 'information_schema') and table_name = '%s'", table)
116 } 128 }
117 129
130 // get column types of postgresql.
118 func (d *dbBasePostgres) DbTypes() map[string]string { 131 func (d *dbBasePostgres) DbTypes() map[string]string {
119 return postgresTypes 132 return postgresTypes
120 } 133 }
121 134
135 // check index exist in postgresql.
122 func (d *dbBasePostgres) IndexExists(db dbQuerier, table string, name string) bool { 136 func (d *dbBasePostgres) IndexExists(db dbQuerier, table string, name string) bool {
123 query := fmt.Sprintf("SELECT COUNT(*) FROM pg_indexes WHERE tablename = '%s' AND indexname = '%s'", table, name) 137 query := fmt.Sprintf("SELECT COUNT(*) FROM pg_indexes WHERE tablename = '%s' AND indexname = '%s'", table, name)
124 row := db.QueryRow(query) 138 row := db.QueryRow(query)
...@@ -127,6 +141,7 @@ func (d *dbBasePostgres) IndexExists(db dbQuerier, table string, name string) bo ...@@ -127,6 +141,7 @@ func (d *dbBasePostgres) IndexExists(db dbQuerier, table string, name string) bo
127 return cnt > 0 141 return cnt > 0
128 } 142 }
129 143
144 // create new postgresql dbBaser.
130 func newdbBasePostgres() dbBaser { 145 func newdbBasePostgres() dbBaser {
131 b := new(dbBasePostgres) 146 b := new(dbBasePostgres)
132 b.ins = b 147 b.ins = b
......
...@@ -5,6 +5,7 @@ import ( ...@@ -5,6 +5,7 @@ import (
5 "fmt" 5 "fmt"
6 ) 6 )
7 7
8 // sqlite operators.
8 var sqliteOperators = map[string]string{ 9 var sqliteOperators = map[string]string{
9 "exact": "= ?", 10 "exact": "= ?",
10 "iexact": "LIKE ? ESCAPE '\\'", 11 "iexact": "LIKE ? ESCAPE '\\'",
...@@ -20,6 +21,7 @@ var sqliteOperators = map[string]string{ ...@@ -20,6 +21,7 @@ var sqliteOperators = map[string]string{
20 "iendswith": "LIKE ? ESCAPE '\\'", 21 "iendswith": "LIKE ? ESCAPE '\\'",
21 } 22 }
22 23
24 // sqlite column types.
23 var sqliteTypes = map[string]string{ 25 var sqliteTypes = map[string]string{
24 "auto": "integer NOT NULL PRIMARY KEY AUTOINCREMENT", 26 "auto": "integer NOT NULL PRIMARY KEY AUTOINCREMENT",
25 "pk": "NOT NULL PRIMARY KEY", 27 "pk": "NOT NULL PRIMARY KEY",
...@@ -40,38 +42,47 @@ var sqliteTypes = map[string]string{ ...@@ -40,38 +42,47 @@ var sqliteTypes = map[string]string{
40 "float64-decimal": "decimal", 42 "float64-decimal": "decimal",
41 } 43 }
42 44
45 // sqlite dbBaser.
43 type dbBaseSqlite struct { 46 type dbBaseSqlite struct {
44 dbBase 47 dbBase
45 } 48 }
46 49
47 var _ dbBaser = new(dbBaseSqlite) 50 var _ dbBaser = new(dbBaseSqlite)
48 51
52 // get sqlite operator.
49 func (d *dbBaseSqlite) OperatorSql(operator string) string { 53 func (d *dbBaseSqlite) OperatorSql(operator string) string {
50 return sqliteOperators[operator] 54 return sqliteOperators[operator]
51 } 55 }
52 56
57 // generate functioned sql for sqlite.
58 // only support DATE(text).
53 func (d *dbBaseSqlite) GenerateOperatorLeftCol(fi *fieldInfo, operator string, leftCol *string) { 59 func (d *dbBaseSqlite) GenerateOperatorLeftCol(fi *fieldInfo, operator string, leftCol *string) {
54 if fi.fieldType == TypeDateField { 60 if fi.fieldType == TypeDateField {
55 *leftCol = fmt.Sprintf("DATE(%s)", *leftCol) 61 *leftCol = fmt.Sprintf("DATE(%s)", *leftCol)
56 } 62 }
57 } 63 }
58 64
65 // unable updating joined record in sqlite.
59 func (d *dbBaseSqlite) SupportUpdateJoin() bool { 66 func (d *dbBaseSqlite) SupportUpdateJoin() bool {
60 return false 67 return false
61 } 68 }
62 69
70 // max int in sqlite.
63 func (d *dbBaseSqlite) MaxLimit() uint64 { 71 func (d *dbBaseSqlite) MaxLimit() uint64 {
64 return 9223372036854775807 72 return 9223372036854775807
65 } 73 }
66 74
75 // get column types in sqlite.
67 func (d *dbBaseSqlite) DbTypes() map[string]string { 76 func (d *dbBaseSqlite) DbTypes() map[string]string {
68 return sqliteTypes 77 return sqliteTypes
69 } 78 }
70 79
80 // get show tables sql in sqlite.
71 func (d *dbBaseSqlite) ShowTablesQuery() string { 81 func (d *dbBaseSqlite) ShowTablesQuery() string {
72 return "SELECT name FROM sqlite_master WHERE type = 'table'" 82 return "SELECT name FROM sqlite_master WHERE type = 'table'"
73 } 83 }
74 84
85 // get columns in sqlite.
75 func (d *dbBaseSqlite) GetColumns(db dbQuerier, table string) (map[string][3]string, error) { 86 func (d *dbBaseSqlite) GetColumns(db dbQuerier, table string) (map[string][3]string, error) {
76 query := d.ins.ShowColumnsQuery(table) 87 query := d.ins.ShowColumnsQuery(table)
77 rows, err := db.Query(query) 88 rows, err := db.Query(query)
...@@ -92,10 +103,12 @@ func (d *dbBaseSqlite) GetColumns(db dbQuerier, table string) (map[string][3]str ...@@ -92,10 +103,12 @@ func (d *dbBaseSqlite) GetColumns(db dbQuerier, table string) (map[string][3]str
92 return columns, nil 103 return columns, nil
93 } 104 }
94 105
106 // get show columns sql in sqlite.
95 func (d *dbBaseSqlite) ShowColumnsQuery(table string) string { 107 func (d *dbBaseSqlite) ShowColumnsQuery(table string) string {
96 return fmt.Sprintf("pragma table_info('%s')", table) 108 return fmt.Sprintf("pragma table_info('%s')", table)
97 } 109 }
98 110
111 // check index exist in sqlite.
99 func (d *dbBaseSqlite) IndexExists(db dbQuerier, table string, name string) bool { 112 func (d *dbBaseSqlite) IndexExists(db dbQuerier, table string, name string) bool {
100 query := fmt.Sprintf("PRAGMA index_list('%s')", table) 113 query := fmt.Sprintf("PRAGMA index_list('%s')", table)
101 rows, err := db.Query(query) 114 rows, err := db.Query(query)
...@@ -113,6 +126,7 @@ func (d *dbBaseSqlite) IndexExists(db dbQuerier, table string, name string) bool ...@@ -113,6 +126,7 @@ func (d *dbBaseSqlite) IndexExists(db dbQuerier, table string, name string) bool
113 return false 126 return false
114 } 127 }
115 128
129 // create new sqlite dbBaser.
116 func newdbBaseSqlite() dbBaser { 130 func newdbBaseSqlite() dbBaser {
117 b := new(dbBaseSqlite) 131 b := new(dbBaseSqlite)
118 b.ins = b 132 b.ins = b
......
...@@ -6,6 +6,7 @@ import ( ...@@ -6,6 +6,7 @@ import (
6 "time" 6 "time"
7 ) 7 )
8 8
9 // table info struct.
9 type dbTable struct { 10 type dbTable struct {
10 id int 11 id int
11 index string 12 index string
...@@ -18,6 +19,7 @@ type dbTable struct { ...@@ -18,6 +19,7 @@ type dbTable struct {
18 jtl *dbTable 19 jtl *dbTable
19 } 20 }
20 21
22 // tables collection struct, contains some tables.
21 type dbTables struct { 23 type dbTables struct {
22 tablesM map[string]*dbTable 24 tablesM map[string]*dbTable
23 tables []*dbTable 25 tables []*dbTable
...@@ -26,6 +28,8 @@ type dbTables struct { ...@@ -26,6 +28,8 @@ type dbTables struct {
26 skipEnd bool 28 skipEnd bool
27 } 29 }
28 30
31 // set table info to collection.
32 // if not exist, create new.
29 func (t *dbTables) set(names []string, mi *modelInfo, fi *fieldInfo, inner bool) *dbTable { 33 func (t *dbTables) set(names []string, mi *modelInfo, fi *fieldInfo, inner bool) *dbTable {
30 name := strings.Join(names, ExprSep) 34 name := strings.Join(names, ExprSep)
31 if j, ok := t.tablesM[name]; ok { 35 if j, ok := t.tablesM[name]; ok {
...@@ -42,6 +46,7 @@ func (t *dbTables) set(names []string, mi *modelInfo, fi *fieldInfo, inner bool) ...@@ -42,6 +46,7 @@ func (t *dbTables) set(names []string, mi *modelInfo, fi *fieldInfo, inner bool)
42 return t.tablesM[name] 46 return t.tablesM[name]
43 } 47 }
44 48
49 // add table info to collection.
45 func (t *dbTables) add(names []string, mi *modelInfo, fi *fieldInfo, inner bool) (*dbTable, bool) { 50 func (t *dbTables) add(names []string, mi *modelInfo, fi *fieldInfo, inner bool) (*dbTable, bool) {
46 name := strings.Join(names, ExprSep) 51 name := strings.Join(names, ExprSep)
47 if _, ok := t.tablesM[name]; ok == false { 52 if _, ok := t.tablesM[name]; ok == false {
...@@ -54,11 +59,14 @@ func (t *dbTables) add(names []string, mi *modelInfo, fi *fieldInfo, inner bool) ...@@ -54,11 +59,14 @@ func (t *dbTables) add(names []string, mi *modelInfo, fi *fieldInfo, inner bool)
54 return t.tablesM[name], false 59 return t.tablesM[name], false
55 } 60 }
56 61
62 // get table info in collection.
57 func (t *dbTables) get(name string) (*dbTable, bool) { 63 func (t *dbTables) get(name string) (*dbTable, bool) {
58 j, ok := t.tablesM[name] 64 j, ok := t.tablesM[name]
59 return j, ok 65 return j, ok
60 } 66 }
61 67
68 // get related fields info in recursive depth loop.
69 // loop once, depth decreases one.
62 func (t *dbTables) loopDepth(depth int, prefix string, fi *fieldInfo, related []string) []string { 70 func (t *dbTables) loopDepth(depth int, prefix string, fi *fieldInfo, related []string) []string {
63 if depth < 0 || fi.fieldType == RelManyToMany { 71 if depth < 0 || fi.fieldType == RelManyToMany {
64 return related 72 return related
...@@ -79,6 +87,7 @@ func (t *dbTables) loopDepth(depth int, prefix string, fi *fieldInfo, related [] ...@@ -79,6 +87,7 @@ func (t *dbTables) loopDepth(depth int, prefix string, fi *fieldInfo, related []
79 return related 87 return related
80 } 88 }
81 89
90 // parse related fields.
82 func (t *dbTables) parseRelated(rels []string, depth int) { 91 func (t *dbTables) parseRelated(rels []string, depth int) {
83 92
84 relsNum := len(rels) 93 relsNum := len(rels)
...@@ -140,6 +149,7 @@ func (t *dbTables) parseRelated(rels []string, depth int) { ...@@ -140,6 +149,7 @@ func (t *dbTables) parseRelated(rels []string, depth int) {
140 } 149 }
141 } 150 }
142 151
152 // generate join string.
143 func (t *dbTables) getJoinSql() (join string) { 153 func (t *dbTables) getJoinSql() (join string) {
144 Q := t.base.TableQuote() 154 Q := t.base.TableQuote()
145 155
...@@ -186,6 +196,7 @@ func (t *dbTables) getJoinSql() (join string) { ...@@ -186,6 +196,7 @@ func (t *dbTables) getJoinSql() (join string) {
186 return 196 return
187 } 197 }
188 198
199 // parse orm model struct field tag expression.
189 func (t *dbTables) parseExprs(mi *modelInfo, exprs []string) (index, name string, info *fieldInfo, success bool) { 200 func (t *dbTables) parseExprs(mi *modelInfo, exprs []string) (index, name string, info *fieldInfo, success bool) {
190 var ( 201 var (
191 jtl *dbTable 202 jtl *dbTable
...@@ -300,6 +311,7 @@ loopFor: ...@@ -300,6 +311,7 @@ loopFor:
300 return 311 return
301 } 312 }
302 313
314 // generate condition sql.
303 func (t *dbTables) getCondSql(cond *Condition, sub bool, tz *time.Location) (where string, params []interface{}) { 315 func (t *dbTables) getCondSql(cond *Condition, sub bool, tz *time.Location) (where string, params []interface{}) {
304 if cond == nil || cond.IsEmpty() { 316 if cond == nil || cond.IsEmpty() {
305 return 317 return
...@@ -364,6 +376,7 @@ func (t *dbTables) getCondSql(cond *Condition, sub bool, tz *time.Location) (whe ...@@ -364,6 +376,7 @@ func (t *dbTables) getCondSql(cond *Condition, sub bool, tz *time.Location) (whe
364 return 376 return
365 } 377 }
366 378
379 // generate order sql.
367 func (t *dbTables) getOrderSql(orders []string) (orderSql string) { 380 func (t *dbTables) getOrderSql(orders []string) (orderSql string) {
368 if len(orders) == 0 { 381 if len(orders) == 0 {
369 return 382 return
...@@ -392,6 +405,7 @@ func (t *dbTables) getOrderSql(orders []string) (orderSql string) { ...@@ -392,6 +405,7 @@ func (t *dbTables) getOrderSql(orders []string) (orderSql string) {
392 return 405 return
393 } 406 }
394 407
408 // generate limit sql.
395 func (t *dbTables) getLimitSql(mi *modelInfo, offset int64, limit int64) (limits string) { 409 func (t *dbTables) getLimitSql(mi *modelInfo, offset int64, limit int64) (limits string) {
396 if limit == 0 { 410 if limit == 0 {
397 limit = int64(DefaultRowsLimit) 411 limit = int64(DefaultRowsLimit)
...@@ -414,6 +428,7 @@ func (t *dbTables) getLimitSql(mi *modelInfo, offset int64, limit int64) (limits ...@@ -414,6 +428,7 @@ func (t *dbTables) getLimitSql(mi *modelInfo, offset int64, limit int64) (limits
414 return 428 return
415 } 429 }
416 430
431 // crete new tables collection.
417 func newDbTables(mi *modelInfo, base dbBaser) *dbTables { 432 func newDbTables(mi *modelInfo, base dbBaser) *dbTables {
418 tables := &dbTables{} 433 tables := &dbTables{}
419 tables.tablesM = make(map[string]*dbTable) 434 tables.tablesM = make(map[string]*dbTable)
......
...@@ -6,6 +6,7 @@ import ( ...@@ -6,6 +6,7 @@ import (
6 "time" 6 "time"
7 ) 7 )
8 8
9 // get table alias.
9 func getDbAlias(name string) *alias { 10 func getDbAlias(name string) *alias {
10 if al, ok := dataBaseCache.get(name); ok { 11 if al, ok := dataBaseCache.get(name); ok {
11 return al 12 return al
...@@ -15,6 +16,7 @@ func getDbAlias(name string) *alias { ...@@ -15,6 +16,7 @@ func getDbAlias(name string) *alias {
15 return nil 16 return nil
16 } 17 }
17 18
19 // get pk column info.
18 func getExistPk(mi *modelInfo, ind reflect.Value) (column string, value interface{}, exist bool) { 20 func getExistPk(mi *modelInfo, ind reflect.Value) (column string, value interface{}, exist bool) {
19 fi := mi.fields.pk 21 fi := mi.fields.pk
20 22
...@@ -37,6 +39,7 @@ func getExistPk(mi *modelInfo, ind reflect.Value) (column string, value interfac ...@@ -37,6 +39,7 @@ func getExistPk(mi *modelInfo, ind reflect.Value) (column string, value interfac
37 return 39 return
38 } 40 }
39 41
42 // get fields description as flatted string.
40 func getFlatParams(fi *fieldInfo, args []interface{}, tz *time.Location) (params []interface{}) { 43 func getFlatParams(fi *fieldInfo, args []interface{}, tz *time.Location) (params []interface{}) {
41 44
42 outFor: 45 outFor:
......
...@@ -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:
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!