github.com/godaddy-x/freego@v1.0.156/ormx/sqld/base_manager.go (about) 1 package sqld 2 3 import ( 4 "bytes" 5 "context" 6 "database/sql" 7 "github.com/godaddy-x/freego/cache" 8 DIC "github.com/godaddy-x/freego/common" 9 "github.com/godaddy-x/freego/ormx/sqlc" 10 "github.com/godaddy-x/freego/ormx/sqld/dialect" 11 "github.com/godaddy-x/freego/utils" 12 "github.com/godaddy-x/freego/zlog" 13 "reflect" 14 "time" 15 ) 16 17 var ( 18 ZERO = int64(0) 19 TRUE = true 20 FALSE = false 21 rdbs = map[string]*RDBManager{} 22 ) 23 24 const ( 25 SAVE = 1 26 UPDATE = 2 27 DELETE = 3 28 UPDATE_BY_CND = 4 29 ) 30 31 /********************************** 数据库配置参数 **********************************/ 32 33 // 数据库配置 34 type DBConfig struct { 35 Option 36 Host string // 地址IP 37 Port int // 数据库端口 38 Username string // 账号 39 Password string // 密码 40 SlowQuery int64 // 0.不开启筛选 >0开启筛选查询 毫秒 41 SlowLogPath string // 慢查询写入地址 42 } 43 44 // 数据选项 45 type Option struct { 46 DsName string // 数据源,分库时使用 47 Database string // 数据库名称 48 Charset string // 连接字符集,默认utf8mb4 49 OpenTx bool // 是否开启事务 true.是 false.否 50 AutoID bool // 是否自增ID 51 MongoSync bool // 是否自动同步mongo数据库写入 52 Timeout int64 // 请求超时设置/毫秒,默认10000 53 SlowQuery int64 // 0.不开启筛选 >0开启筛选查询 毫秒 54 SlowLogPath string // 慢查询写入地址 55 } 56 57 type MGOSyncData struct { 58 CacheOption int // 1.save 2.update 3.delete 59 CacheModel sqlc.Object // 对象模型 60 CacheCnd *sqlc.Cnd // 需要缓存的数据 CacheSync为true时有效 61 CacheObject []sqlc.Object // 需要缓存的数据 CacheSync为true时有效 62 } 63 64 // 数据库管理器 65 type DBManager struct { 66 Option 67 CacheManager cache.Cache // 缓存管理器 68 MGOSyncData []*MGOSyncData // 同步数据对象 69 Errors []error // 错误异常记录 70 } 71 72 /********************************** 数据库ORM实现 **********************************/ 73 74 // orm数据库接口 75 type IDBase interface { 76 // 初始化数据库配置 77 InitConfig(input interface{}) error 78 // 获取数据库管理器 79 GetDB(option ...Option) error 80 // 保存数据 81 Save(datas ...sqlc.Object) error 82 // 更新数据 83 Update(datas ...sqlc.Object) error 84 // 按条件更新数据 85 UpdateByCnd(cnd *sqlc.Cnd) (int64, error) 86 // 删除数据 87 Delete(datas ...sqlc.Object) error 88 // 删除数据 89 DeleteById(object sqlc.Object, data ...interface{}) (int64, error) 90 // 按条件删除数据 91 DeleteByCnd(cnd *sqlc.Cnd) (int64, error) 92 // 统计数据 93 Count(cnd *sqlc.Cnd) (int64, error) 94 // 检测是否存在 95 Exists(cnd *sqlc.Cnd) (bool, error) 96 // 按ID查询单条数据 97 FindById(data sqlc.Object) error 98 // 按条件查询单条数据 99 FindOne(cnd *sqlc.Cnd, data sqlc.Object) error 100 // 按条件查询数据 101 FindList(cnd *sqlc.Cnd, data interface{}) error 102 // 按复杂条件查询数据 103 FindOneComplex(cnd *sqlc.Cnd, data sqlc.Object) error 104 // 按复杂条件查询数据列表 105 FindListComplex(cnd *sqlc.Cnd, data interface{}) error 106 // 构建数据表别名 107 BuildCondKey(cnd *sqlc.Cnd, key string) []byte 108 // 构建逻辑条件 109 BuildWhereCase(cnd *sqlc.Cnd) (*bytes.Buffer, []interface{}) 110 // 构建分组条件 111 BuildGroupBy(cnd *sqlc.Cnd) string 112 // 构建排序条件 113 BuildSortBy(cnd *sqlc.Cnd) string 114 // 构建分页条件 115 BuildPagination(cnd *sqlc.Cnd, sql string, values []interface{}) (string, error) 116 // 数据库操作缓存异常 117 Error(data ...interface{}) error 118 } 119 120 func (self *DBManager) InitConfig(input interface{}) error { 121 return utils.Error("No implementation method [InitConfig] was found") 122 } 123 124 func (self *DBManager) GetDB(option ...Option) error { 125 return utils.Error("No implementation method [GetDB] was found") 126 } 127 128 func (self *DBManager) Save(datas ...sqlc.Object) error { 129 return utils.Error("No implementation method [Save] was found") 130 } 131 132 func (self *DBManager) Update(datas ...sqlc.Object) error { 133 return utils.Error("No implementation method [Update] was found") 134 } 135 136 func (self *DBManager) UpdateByCnd(cnd *sqlc.Cnd) (int64, error) { 137 return 0, utils.Error("No implementation method [UpdateByCnd] was found") 138 } 139 140 func (self *DBManager) Delete(datas ...sqlc.Object) error { 141 return utils.Error("No implementation method [Delete] was found") 142 } 143 144 func (self *DBManager) DeleteById(object sqlc.Object, data ...interface{}) (int64, error) { 145 return 0, utils.Error("No implementation method [DeleteById] was found") 146 } 147 148 func (self *DBManager) DeleteByCnd(cnd *sqlc.Cnd) (int64, error) { 149 return 0, utils.Error("No implementation method [DeleteByCnd] was found") 150 } 151 152 func (self *DBManager) Count(cnd *sqlc.Cnd) (int64, error) { 153 return 0, utils.Error("No implementation method [Count] was found") 154 } 155 156 func (self *DBManager) Exists(cnd *sqlc.Cnd) (bool, error) { 157 return false, utils.Error("No implementation method [Exists] was found") 158 } 159 160 func (self *DBManager) FindById(data sqlc.Object) error { 161 return utils.Error("No implementation method [FindById] was found") 162 } 163 164 func (self *DBManager) FindOne(cnd *sqlc.Cnd, data sqlc.Object) error { 165 return utils.Error("No implementation method [FindOne] was found") 166 } 167 168 func (self *DBManager) FindList(cnd *sqlc.Cnd, data interface{}) error { 169 return utils.Error("No implementation method [FindList] was found") 170 } 171 172 func (self *DBManager) FindOneComplex(cnd *sqlc.Cnd, data sqlc.Object) error { 173 return utils.Error("No implementation method [FindOneComplexOne] was found") 174 } 175 176 func (self *DBManager) FindListComplex(cnd *sqlc.Cnd, data interface{}) error { 177 return utils.Error("No implementation method [FindListComplex] was found") 178 } 179 180 func (self *DBManager) Close() error { 181 return utils.Error("No implementation method [Close] was found") 182 } 183 184 func (self *DBManager) BuildCondKey(cnd *sqlc.Cnd, key string) []byte { 185 zlog.Warn("No implementation method [BuildCondKey] was found", 0) 186 return nil 187 } 188 189 func (self *DBManager) BuildWhereCase(cnd *sqlc.Cnd) (*bytes.Buffer, []interface{}) { 190 zlog.Warn("No implementation method [BuildWhereCase] was found", 0) 191 return nil, nil 192 } 193 194 func (self *DBManager) BuildGroupBy(cnd *sqlc.Cnd) string { 195 zlog.Warn("No implementation method [BuilGroupBy] was found", 0) 196 return "" 197 } 198 199 func (self *DBManager) BuildSortBy(cnd *sqlc.Cnd) string { 200 zlog.Warn("No implementation method [BuilSortBy] was found", 0) 201 return "" 202 } 203 204 func (self *DBManager) BuildPagination(cnd *sqlc.Cnd, sql string, values []interface{}) (string, error) { 205 return "", utils.Error("No implementation method [BuildPagination] was found") 206 } 207 208 func (self *DBManager) Error(data ...interface{}) error { 209 if data == nil || len(data) == 0 { 210 return nil 211 } 212 err := utils.Error(data...) 213 self.Errors = append(self.Errors, err) 214 return err 215 } 216 217 /********************************** 关系数据库ORM默认实现 -> MySQL(如需实现其他类型数据库则自行实现IDBase接口) **********************************/ 218 219 // 关系数据库连接管理器 220 type RDBManager struct { 221 DBManager 222 Db *sql.DB 223 Tx *sql.Tx 224 } 225 226 func (self *RDBManager) GetDB(options ...Option) error { 227 dsName := DIC.MASTER 228 var option Option 229 if len(options) > 0 { 230 option = options[0] 231 if len(option.DsName) > 0 { 232 dsName = option.DsName 233 } else { 234 option.DsName = dsName 235 } 236 } 237 rdb := rdbs[dsName] 238 if rdb == nil { 239 return self.Error("datasource [", dsName, "] not found...") 240 } 241 self.Db = rdb.Db 242 self.DsName = rdb.DsName 243 self.Database = rdb.Database 244 self.Timeout = 10000 245 self.MongoSync = rdb.MongoSync 246 self.CacheManager = rdb.CacheManager 247 self.OpenTx = false 248 self.Option.AutoID = option.AutoID 249 if len(option.DsName) > 0 { 250 if len(option.DsName) > 0 { 251 self.DsName = option.DsName 252 } 253 if option.OpenTx { 254 self.OpenTx = option.OpenTx 255 } 256 if option.MongoSync { 257 self.MongoSync = option.MongoSync 258 } 259 if option.Timeout > 0 { 260 self.Timeout = option.Timeout 261 } 262 if len(option.Database) > 0 { 263 self.Database = option.Database 264 } 265 if option.OpenTx { 266 if txv, err := self.Db.Begin(); err != nil { 267 return self.Error("database open transaction failed: ", err) 268 } else { 269 self.Tx = txv 270 } 271 } 272 } 273 return nil 274 } 275 276 func (self *RDBManager) Save(data ...sqlc.Object) error { 277 if data == nil || len(data) == 0 { 278 return self.Error("[Mysql.Save] data is nil") 279 } 280 if len(data) > 2000 { 281 return self.Error("[Mysql.Save] data length > 2000") 282 } 283 obv, ok := modelDrivers[data[0].GetTable()] 284 if !ok { 285 return self.Error("[Mysql.Save] registration object type not found [", data[0].GetTable(), "]") 286 } 287 var fready bool 288 parameter := make([]interface{}, 0, len(obv.FieldElem)*len(data)) 289 fpart := bytes.NewBuffer(make([]byte, 0, 14*len(obv.FieldElem))) 290 vpart := bytes.NewBuffer(make([]byte, 0, 64*len(data))) 291 for _, v := range data { 292 vpart_ := bytes.NewBuffer(make([]byte, 0, 64)) 293 vpart_.WriteString(" (") 294 for _, vv := range obv.FieldElem { 295 if vv.Ignore { 296 continue 297 } 298 if vv.Primary { 299 if self.AutoID { 300 continue 301 } 302 if vv.FieldKind == reflect.Int64 { 303 lastInsertId := utils.GetInt64(utils.GetPtr(v, obv.PkOffset)) 304 if lastInsertId == 0 { 305 if obv.AutoId { 306 continue 307 } 308 lastInsertId = utils.NextIID() 309 utils.SetInt64(utils.GetPtr(v, vv.FieldOffset), lastInsertId) 310 } 311 parameter = append(parameter, lastInsertId) 312 } else if vv.FieldKind == reflect.String { 313 lastInsertId := utils.GetString(utils.GetPtr(v, obv.PkOffset)) 314 if len(lastInsertId) == 0 { 315 if obv.AutoId { 316 continue 317 } 318 lastInsertId := utils.NextSID() 319 utils.SetString(utils.GetPtr(v, vv.FieldOffset), lastInsertId) 320 } 321 parameter = append(parameter, lastInsertId) 322 } else { 323 return utils.Error("only Int64 and string type IDs are supported") 324 } 325 } else { 326 fval, err := GetValue(v, vv) 327 if err != nil { 328 zlog.Error("[Mysql.Save] parameter value acquisition failed", 0, zlog.String("field", vv.FieldName), zlog.AddError(err)) 329 continue 330 } 331 if vv.IsDate && fval == "" { // time = 0 332 fval = utils.Time2Str(utils.UnixMilli()) 333 } 334 parameter = append(parameter, fval) 335 } 336 if !fready { 337 fpart.WriteString("`") 338 fpart.WriteString(vv.FieldJsonName) 339 fpart.WriteString("`") 340 fpart.WriteString(",") 341 } 342 vpart_.WriteString("?,") 343 } 344 if !fready { 345 fready = true 346 } 347 vstr := utils.Bytes2Str(vpart_.Bytes()) 348 vpart.WriteString(utils.Substr(vstr, 0, len(vstr)-1)) 349 vpart.WriteString("),") 350 } 351 str1 := utils.Bytes2Str(fpart.Bytes()) 352 str2 := utils.Bytes2Str(vpart.Bytes()) 353 sqlbuf := bytes.NewBuffer(make([]byte, 0, len(str1)+len(str2)+64)) 354 sqlbuf.WriteString("insert into ") 355 sqlbuf.WriteString(obv.TableName) 356 sqlbuf.WriteString(" (") 357 sqlbuf.WriteString(utils.Substr(str1, 0, len(str1)-1)) 358 sqlbuf.WriteString(")") 359 sqlbuf.WriteString(" values ") 360 if len(str2) > 0 { 361 sqlbuf.WriteString(utils.Substr(str2, 0, len(str2)-1)) 362 } 363 prepare := utils.Bytes2Str(sqlbuf.Bytes()) 364 if zlog.IsDebug() { 365 defer zlog.Debug("[Mysql.Save] sql log", utils.UnixMilli(), zlog.String("sql", prepare), zlog.Any("values", parameter)) 366 } 367 ctx, cancel := context.WithTimeout(context.Background(), time.Duration(self.Timeout)*time.Millisecond) 368 defer cancel() 369 var err error 370 var stmt *sql.Stmt 371 if self.OpenTx { 372 stmt, err = self.Tx.PrepareContext(ctx, prepare) 373 } else { 374 stmt, err = self.Db.PrepareContext(ctx, prepare) 375 } 376 if err != nil { 377 return self.Error("[Mysql.Save] [ ", prepare, " ] prepare failed: ", err) 378 } 379 defer stmt.Close() 380 if ret, err := stmt.ExecContext(ctx, parameter...); err != nil { 381 return self.Error("[Mysql.Save] save failed: ", err) 382 } else if rowsAffected, err := ret.RowsAffected(); err != nil { 383 return self.Error("[Mysql.Save] affected rows failed: ", err) 384 } else if rowsAffected <= 0 { 385 return self.Error("[Mysql.Save] affected rows <= 0: ", rowsAffected) 386 } 387 if self.MongoSync && obv.ToMongo { 388 self.MGOSyncData = append(self.MGOSyncData, &MGOSyncData{SAVE, data[0], nil, data}) 389 } 390 return nil 391 } 392 393 func (self *RDBManager) Update(data ...sqlc.Object) error { 394 if data == nil || len(data) == 0 { 395 return self.Error("[Mysql.Update] data is nil") 396 } 397 if len(data) > 1 { 398 return self.Error("[Mysql.Update] data length must 1") 399 } 400 oneData := data[0] 401 obv, ok := modelDrivers[oneData.GetTable()] 402 if !ok { 403 return self.Error("[Mysql.Update] registration object type not found [", data[0].GetTable(), "]") 404 } 405 406 parameter := make([]interface{}, 0, len(obv.FieldElem)) 407 fpart := bytes.NewBuffer(make([]byte, 0, 96)) 408 var lastInsertId interface{} 409 for _, v := range obv.FieldElem { // 遍历对象字段 410 if v.Ignore { 411 continue 412 } 413 if v.Primary { 414 if obv.PkKind == reflect.Int64 { 415 lastInsertId = utils.GetInt64(utils.GetPtr(oneData, obv.PkOffset)) 416 if lastInsertId == 0 { 417 return self.Error("[Mysql.Update] data object id is nil") 418 } 419 } else if obv.PkKind == reflect.String { 420 lastInsertId = utils.GetString(utils.GetPtr(oneData, obv.PkOffset)) 421 if lastInsertId == "" { 422 return self.Error("[Mysql.Update] data object id is nil") 423 } 424 } else { 425 return utils.Error("only Int64 and string type IDs are supported") 426 } 427 continue 428 } 429 fval, err := GetValue(oneData, v) 430 if err != nil { 431 zlog.Error("[Mysql.update] parameter value acquisition failed", 0, zlog.String("field", v.FieldName), zlog.AddError(err)) 432 return utils.Error(err) 433 } 434 if v.IsDate && fval == "" { 435 continue 436 } 437 fpart.WriteString(" ") 438 fpart.WriteString("`") 439 fpart.WriteString(v.FieldJsonName) 440 fpart.WriteString("`") 441 fpart.WriteString(" = ?,") 442 parameter = append(parameter, fval) 443 } 444 parameter = append(parameter, lastInsertId) 445 str1 := utils.Bytes2Str(fpart.Bytes()) 446 sqlbuf := bytes.NewBuffer(make([]byte, 0, len(str1))) 447 sqlbuf.WriteString("update ") 448 sqlbuf.WriteString(obv.TableName) 449 sqlbuf.WriteString(" set ") 450 sqlbuf.WriteString(utils.Substr(str1, 0, len(str1)-1)) 451 sqlbuf.WriteString(" where ") 452 sqlbuf.WriteString("`") 453 sqlbuf.WriteString(obv.PkName) 454 sqlbuf.WriteString("`") 455 sqlbuf.WriteString(" = ?") 456 457 prepare := utils.Bytes2Str(sqlbuf.Bytes()) 458 if zlog.IsDebug() { 459 defer zlog.Debug("[Mysql.Update] sql log", utils.UnixMilli(), zlog.String("sql", prepare), zlog.Any("values", parameter)) 460 } 461 ctx, cancel := context.WithTimeout(context.Background(), time.Duration(self.Timeout)*time.Millisecond) 462 defer cancel() 463 var err error 464 var stmt *sql.Stmt 465 if self.OpenTx { 466 stmt, err = self.Tx.PrepareContext(ctx, prepare) 467 } else { 468 stmt, err = self.Db.PrepareContext(ctx, prepare) 469 } 470 if err != nil { 471 return self.Error("[Mysql.Update] [ ", prepare, " ] prepare failed: ", err) 472 } 473 defer stmt.Close() 474 if ret, err := stmt.ExecContext(ctx, parameter...); err != nil { 475 return self.Error("[Mysql.Update] update failed: ", err) 476 } else if rowsAffected, err := ret.RowsAffected(); err != nil { 477 return self.Error("[Mysql.Update] affected rows failed: ", err) 478 } else if rowsAffected <= 0 { 479 zlog.Warn(utils.AddStr("[Mysql.Update] affected rows <= 0 -> ", rowsAffected), 0, zlog.String("sql", prepare)) 480 return nil 481 } 482 if self.MongoSync && obv.ToMongo { 483 self.MGOSyncData = append(self.MGOSyncData, &MGOSyncData{UPDATE, oneData, nil, nil}) 484 } 485 return nil 486 } 487 488 func (self *RDBManager) UpdateByCnd(cnd *sqlc.Cnd) (int64, error) { 489 if cnd.Model == nil { 490 return 0, self.Error("[Mysql.UpdateByCnd] data is nil") 491 } 492 if cnd.Upsets == nil || len(cnd.Upsets) == 0 { 493 return 0, self.Error("[Mysql.UpdateByCnd] upset fields is nil") 494 } 495 obv, ok := modelDrivers[cnd.Model.GetTable()] 496 if !ok { 497 return 0, self.Error("[Mysql.UpdateByCnd] registration object type not found [", cnd.Model.GetTable(), "]") 498 } 499 case_part, case_arg := self.BuildWhereCase(cnd) 500 if case_part.Len() == 0 || len(case_arg) == 0 { 501 return 0, self.Error("[Mysql.UpdateByCnd] update WhereCase is nil") 502 } 503 parameter := make([]interface{}, 0, len(cnd.Upsets)+len(case_arg)) 504 fpart := bytes.NewBuffer(make([]byte, 0, 96)) 505 for k, v := range cnd.Upsets { // 遍历对象字段 506 if cnd.Escape { 507 fpart.WriteString(" ") 508 fpart.WriteString("`") 509 fpart.WriteString(k) 510 fpart.WriteString("`") 511 fpart.WriteString(" = ?,") 512 } else { 513 fpart.WriteString(" ") 514 fpart.WriteString(k) 515 fpart.WriteString(" = ?,") 516 } 517 parameter = append(parameter, v) 518 } 519 for _, v := range case_arg { 520 parameter = append(parameter, v) 521 } 522 vpart := bytes.NewBuffer(make([]byte, 0, case_part.Len()+16)) 523 vpart.WriteString("where") 524 str := case_part.String() 525 vpart.WriteString(utils.Substr(str, 0, len(str)-3)) 526 str1 := utils.Bytes2Str(fpart.Bytes()) 527 str2 := utils.Bytes2Str(vpart.Bytes()) 528 sqlbuf := bytes.NewBuffer(make([]byte, 0, len(str1)+len(str2)+64)) 529 sqlbuf.WriteString("update ") 530 sqlbuf.WriteString(obv.TableName) 531 sqlbuf.WriteString(" set ") 532 sqlbuf.WriteString(utils.Substr(str1, 0, len(str1)-1)) 533 sqlbuf.WriteString(" ") 534 if len(str2) > 0 { 535 sqlbuf.WriteString(utils.Substr(str2, 0, len(str2)-1)) 536 } 537 prepare := utils.Bytes2Str(sqlbuf.Bytes()) 538 if zlog.IsDebug() { 539 defer zlog.Debug("[Mysql.UpdateByCnd] sql log", utils.UnixMilli(), zlog.String("sql", prepare), zlog.Any("values", parameter)) 540 } 541 ctx, cancel := context.WithTimeout(context.Background(), time.Duration(self.Timeout)*time.Millisecond) 542 defer cancel() 543 var err error 544 var stmt *sql.Stmt 545 if self.OpenTx { 546 stmt, err = self.Tx.PrepareContext(ctx, prepare) 547 } else { 548 stmt, err = self.Db.PrepareContext(ctx, prepare) 549 } 550 if err != nil { 551 return 0, self.Error("[Mysql.UpdateByCnd] [ ", prepare, " ] prepare failed: ", err) 552 } 553 defer stmt.Close() 554 ret, err := stmt.ExecContext(ctx, parameter...) 555 if err != nil { 556 return 0, self.Error("[Mysql.UpdateByCnd] update failed: ", err) 557 } 558 rowsAffected, err := ret.RowsAffected() 559 if err != nil { 560 return 0, self.Error("[Mysql.UpdateByCnd] affected rows failed: ", err) 561 } 562 if rowsAffected <= 0 { 563 zlog.Warn(utils.AddStr("[Mysql.UpdateByCnd] affected rows <= 0 -> ", rowsAffected), 0, zlog.String("sql", prepare)) 564 return 0, nil 565 } 566 if self.MongoSync && obv.ToMongo { 567 self.MGOSyncData = append(self.MGOSyncData, &MGOSyncData{UPDATE_BY_CND, cnd.Model, cnd, nil}) 568 } 569 return rowsAffected, nil 570 } 571 572 func (self *RDBManager) Delete(data ...sqlc.Object) error { 573 if data == nil || len(data) == 0 { 574 return self.Error("[Mysql.Delete] data is nil") 575 } 576 if len(data) > 2000 { 577 return self.Error("[Mysql.Delete] data length > 2000") 578 } 579 obv, ok := modelDrivers[data[0].GetTable()] 580 if !ok { 581 return self.Error("[Mysql.Delete] registration object type not found [", data[0].GetTable(), "]") 582 } 583 parameter := make([]interface{}, 0, len(data)) 584 vpart := bytes.NewBuffer(make([]byte, 0, 2*len(data))) 585 for _, v := range data { 586 if obv.PkKind == reflect.Int64 { 587 lastInsertId := utils.GetInt64(utils.GetPtr(v, obv.PkOffset)) 588 if lastInsertId == 0 { 589 return self.Error("[Mysql.Delete] data object id is nil") 590 } 591 parameter = append(parameter, lastInsertId) 592 } else if obv.PkKind == reflect.String { 593 lastInsertId := utils.GetString(utils.GetPtr(v, obv.PkOffset)) 594 if len(lastInsertId) == 0 { 595 return self.Error("[Mysql.Delete] data object id is nil") 596 } 597 parameter = append(parameter, lastInsertId) 598 } 599 vpart.WriteString("?,") 600 } 601 str2 := utils.Bytes2Str(vpart.Bytes()) 602 if len(str2) == 0 { 603 return self.Error("where case is nil") 604 } 605 sqlbuf := bytes.NewBuffer(make([]byte, 0, len(str2)+64)) 606 sqlbuf.WriteString("delete from ") 607 sqlbuf.WriteString(obv.TableName) 608 sqlbuf.WriteString(" where ") 609 sqlbuf.WriteString("`") 610 sqlbuf.WriteString(obv.PkName) 611 sqlbuf.WriteString("`") 612 sqlbuf.WriteString(" in (") 613 sqlbuf.WriteString(utils.Substr(str2, 0, len(str2)-1)) 614 sqlbuf.WriteString(")") 615 616 prepare := utils.Bytes2Str(sqlbuf.Bytes()) 617 if zlog.IsDebug() { 618 defer zlog.Debug("[Mysql.Delete] sql log", utils.UnixMilli(), zlog.String("sql", prepare), zlog.Any("values", parameter)) 619 } 620 ctx, cancel := context.WithTimeout(context.Background(), time.Duration(self.Timeout)*time.Millisecond) 621 defer cancel() 622 var err error 623 var stmt *sql.Stmt 624 if self.OpenTx { 625 stmt, err = self.Tx.PrepareContext(ctx, prepare) 626 } else { 627 stmt, err = self.Db.PrepareContext(ctx, prepare) 628 } 629 if err != nil { 630 return self.Error("[Mysql.Delete] [ ", prepare, " ] prepare failed: ", err) 631 } 632 defer stmt.Close() 633 if ret, err := stmt.ExecContext(ctx, parameter...); err != nil { 634 return self.Error("[Mysql.Delete] delete failed: ", err) 635 } else if rowsAffected, err := ret.RowsAffected(); err != nil { 636 return self.Error("[Mysql.Delete] affected rows failed: ", err) 637 } else if rowsAffected <= 0 { 638 zlog.Warn(utils.AddStr("[Mysql.Delete] affected rows <= 0 -> ", rowsAffected), 0, zlog.String("sql", prepare)) 639 return nil 640 } 641 if self.MongoSync && obv.ToMongo { 642 self.MGOSyncData = append(self.MGOSyncData, &MGOSyncData{DELETE, data[0], nil, data}) 643 } 644 return nil 645 } 646 647 func (self *RDBManager) DeleteById(object sqlc.Object, data ...interface{}) (int64, error) { 648 if data == nil || len(data) == 0 { 649 return 0, self.Error("[Mysql.DeleteById] data is nil") 650 } 651 if len(data) > 2000 { 652 return 0, self.Error("[Mysql.DeleteById] data length > 2000") 653 } 654 obv, ok := modelDrivers[object.GetTable()] 655 if !ok { 656 return 0, self.Error("[Mysql.DeleteById] registration object type not found [", object.GetTable(), "]") 657 } 658 parameter := make([]interface{}, 0, len(data)) 659 vpart := bytes.NewBuffer(make([]byte, 0, 2*len(data))) 660 for _, v := range data { 661 vpart.WriteString("?,") 662 parameter = append(parameter, v) 663 } 664 str2 := utils.Bytes2Str(vpart.Bytes()) 665 if len(str2) == 0 { 666 return 0, self.Error("where case is nil") 667 } 668 sqlbuf := bytes.NewBuffer(make([]byte, 0, len(str2)+64)) 669 sqlbuf.WriteString("delete from ") 670 sqlbuf.WriteString(obv.TableName) 671 sqlbuf.WriteString(" where ") 672 sqlbuf.WriteString("`") 673 sqlbuf.WriteString(obv.PkName) 674 sqlbuf.WriteString("`") 675 sqlbuf.WriteString(" in (") 676 sqlbuf.WriteString(utils.Substr(str2, 0, len(str2)-1)) 677 sqlbuf.WriteString(")") 678 679 prepare := utils.Bytes2Str(sqlbuf.Bytes()) 680 if zlog.IsDebug() { 681 defer zlog.Debug("[Mysql.DeleteById] sql log", utils.UnixMilli(), zlog.String("sql", prepare), zlog.Any("values", parameter)) 682 } 683 ctx, cancel := context.WithTimeout(context.Background(), time.Duration(self.Timeout)*time.Millisecond) 684 defer cancel() 685 var err error 686 var stmt *sql.Stmt 687 if self.OpenTx { 688 stmt, err = self.Tx.PrepareContext(ctx, prepare) 689 } else { 690 stmt, err = self.Db.PrepareContext(ctx, prepare) 691 } 692 if err != nil { 693 return 0, self.Error("[Mysql.DeleteById] [ ", prepare, " ] prepare failed: ", err) 694 } 695 defer stmt.Close() 696 ret, err := stmt.ExecContext(ctx, parameter...) 697 if err != nil { 698 return 0, self.Error("[Mysql.DeleteById] delete failed: ", err) 699 } 700 rowsAffected, err := ret.RowsAffected() 701 if err != nil { 702 return 0, self.Error("[Mysql.DeleteById] affected rows failed: ", err) 703 } 704 if rowsAffected <= 0 { 705 zlog.Warn(utils.AddStr("[Mysql.DeleteById] affected rows <= 0 -> ", rowsAffected), 0, zlog.String("sql", prepare)) 706 return 0, nil 707 } 708 return rowsAffected, nil 709 } 710 711 func (self *RDBManager) DeleteByCnd(cnd *sqlc.Cnd) (int64, error) { 712 if cnd.Model == nil { 713 return 0, self.Error("[Mysql.DeleteByCnd] data is nil") 714 } 715 obv, ok := modelDrivers[cnd.Model.GetTable()] 716 if !ok { 717 return 0, self.Error("[Mysql.DeleteByCnd] registration object type not found [", cnd.Model.GetTable(), "]") 718 } 719 case_part, case_arg := self.BuildWhereCase(cnd) 720 if case_part.Len() == 0 || len(case_arg) == 0 { 721 return 0, self.Error("[Mysql.DeleteByCnd] update WhereCase is nil") 722 } 723 parameter := make([]interface{}, 0, len(case_arg)) 724 //fpart := bytes.NewBuffer(make([]byte, 0, 96)) 725 //for k, v := range cnd.Upsets { // 遍历对象字段 726 // if cnd.Escape { 727 // fpart.WriteString(" ") 728 // fpart.WriteString("`") 729 // fpart.WriteString(k) 730 // fpart.WriteString("`") 731 // fpart.WriteString(" = ?,") 732 // } else { 733 // fpart.WriteString(" ") 734 // fpart.WriteString(k) 735 // fpart.WriteString(" = ?,") 736 // } 737 // parameter = append(parameter, v) 738 //} 739 for _, v := range case_arg { 740 parameter = append(parameter, v) 741 } 742 vpart := bytes.NewBuffer(make([]byte, 0, case_part.Len()+16)) 743 vpart.WriteString(" where") 744 str := case_part.String() 745 vpart.WriteString(utils.Substr(str, 0, len(str)-3)) 746 //str1 := utils.Bytes2Str(fpart.Bytes()) 747 str2 := utils.Bytes2Str(vpart.Bytes()) 748 sqlbuf := bytes.NewBuffer(make([]byte, 0, len(str2)+64)) 749 sqlbuf.WriteString("delete from ") 750 sqlbuf.WriteString(obv.TableName) 751 //sqlbuf.WriteString(" set ") 752 //sqlbuf.WriteString(utils.Substr(str1, 0, len(str1)-1)) 753 //sqlbuf.WriteString(" ") 754 if len(str2) > 0 { 755 sqlbuf.WriteString(utils.Substr(str2, 0, len(str2)-1)) 756 } 757 prepare := utils.Bytes2Str(sqlbuf.Bytes()) 758 if zlog.IsDebug() { 759 defer zlog.Debug("[Mysql.DeleteByCnd] sql log", utils.UnixMilli(), zlog.String("sql", prepare), zlog.Any("values", parameter)) 760 } 761 ctx, cancel := context.WithTimeout(context.Background(), time.Duration(self.Timeout)*time.Millisecond) 762 defer cancel() 763 var err error 764 var stmt *sql.Stmt 765 if self.OpenTx { 766 stmt, err = self.Tx.PrepareContext(ctx, prepare) 767 } else { 768 stmt, err = self.Db.PrepareContext(ctx, prepare) 769 } 770 if err != nil { 771 return 0, self.Error("[Mysql.DeleteByCnd] [ ", prepare, " ] prepare failed: ", err) 772 } 773 defer stmt.Close() 774 ret, err := stmt.ExecContext(ctx, parameter...) 775 if err != nil { 776 return 0, self.Error("[Mysql.DeleteByCnd] update failed: ", err) 777 } 778 rowsAffected, err := ret.RowsAffected() 779 if err != nil { 780 return 0, self.Error("[Mysql.DeleteByCnd] affected rows failed: ", err) 781 } 782 if rowsAffected <= 0 { 783 zlog.Warn(utils.AddStr("[Mysql.DeleteByCnd] affected rows <= 0 -> ", rowsAffected), 0, zlog.String("sql", prepare)) 784 return 0, nil 785 } 786 if self.MongoSync && obv.ToMongo { 787 self.MGOSyncData = append(self.MGOSyncData, &MGOSyncData{DELETE, cnd.Model, cnd, nil}) 788 } 789 return rowsAffected, nil 790 } 791 792 func (self *RDBManager) FindById(data sqlc.Object) error { 793 if data == nil { 794 return self.Error("[Mysql.FindById] data is nil") 795 } 796 obv, ok := modelDrivers[data.GetTable()] 797 if !ok { 798 return self.Error("[Mysql.FindById] registration object type not found [", data.GetTable(), "]") 799 } 800 var parameter []interface{} 801 if obv.PkKind == reflect.Int64 { 802 lastInsertId := utils.GetInt64(utils.GetPtr(data, obv.PkOffset)) 803 if lastInsertId == 0 { 804 return self.Error("[Mysql.FindById] data object id is nil") 805 } 806 parameter = append(parameter, lastInsertId) 807 } else if obv.PkKind == reflect.String { 808 lastInsertId := utils.GetString(utils.GetPtr(data, obv.PkOffset)) 809 if len(lastInsertId) == 0 { 810 return self.Error("[Mysql.FindById] data object id is nil") 811 } 812 parameter = append(parameter, lastInsertId) 813 } 814 fpart := bytes.NewBuffer(make([]byte, 0, 14*len(obv.FieldElem))) 815 for _, vv := range obv.FieldElem { 816 if vv.Ignore { 817 continue 818 } 819 fpart.WriteString("`") 820 fpart.WriteString(vv.FieldJsonName) 821 fpart.WriteString("`") 822 fpart.WriteString(",") 823 } 824 str1 := utils.Bytes2Str(fpart.Bytes()) 825 sqlbuf := bytes.NewBuffer(make([]byte, 0, len(str1)+64)) 826 sqlbuf.WriteString("select ") 827 sqlbuf.WriteString(utils.Substr(str1, 0, len(str1)-1)) 828 sqlbuf.WriteString(" from ") 829 sqlbuf.WriteString(obv.TableName) 830 sqlbuf.WriteString(" where ") 831 sqlbuf.WriteString("`") 832 sqlbuf.WriteString(obv.PkName) 833 sqlbuf.WriteString("`") 834 sqlbuf.WriteString(" = ?") 835 sqlbuf.WriteString(" limit 1") 836 prepare := utils.Bytes2Str(sqlbuf.Bytes()) 837 if zlog.IsDebug() { 838 defer zlog.Debug("[Mysql.FindById] sql log", utils.UnixMilli(), zlog.String("sql", prepare), zlog.Any("values", parameter)) 839 } 840 ctx, cancel := context.WithTimeout(context.Background(), time.Duration(self.Timeout)*time.Millisecond) 841 defer cancel() 842 var err error 843 var stmt *sql.Stmt 844 var rows *sql.Rows 845 if self.OpenTx { 846 stmt, err = self.Tx.PrepareContext(ctx, prepare) 847 } else { 848 stmt, err = self.Db.PrepareContext(ctx, prepare) 849 } 850 if err != nil { 851 return self.Error("[Mysql.FindById] [", prepare, "] prepare failed: ", err) 852 } 853 defer stmt.Close() 854 rows, err = stmt.QueryContext(ctx, parameter...) 855 if err != nil { 856 return self.Error("[Mysql.FindById] query failed: ", err) 857 } 858 defer rows.Close() 859 cols, err := rows.Columns() 860 if err != nil { 861 return self.Error("[Mysql.FindById] read columns failed: ", err) 862 } 863 var first [][]byte 864 if out, err := OutDest(rows, len(cols)); err != nil { 865 return self.Error("[Mysql.FindById] read result failed: ", err) 866 } else if len(out) == 0 { 867 return nil 868 } else { 869 first = out[0] 870 } 871 for i, vv := range obv.FieldElem { 872 if vv.Ignore { 873 continue 874 } 875 if err := SetValue(data, vv, first[i]); err != nil { 876 return self.Error(err) 877 } 878 } 879 return nil 880 } 881 882 func (self *RDBManager) FindOne(cnd *sqlc.Cnd, data sqlc.Object) error { 883 if data == nil { 884 return self.Error("[Mysql.FindOne] data is nil") 885 } 886 obv, ok := modelDrivers[data.GetTable()] 887 if !ok { 888 return self.Error("[Mysql.FindOne] registration object type not found [", data.GetTable(), "]") 889 } 890 var parameter []interface{} 891 fpart := bytes.NewBuffer(make([]byte, 0, 14*len(obv.FieldElem))) 892 for _, vv := range obv.FieldElem { 893 if vv.Ignore { 894 continue 895 } 896 fpart.WriteString("`") 897 fpart.WriteString(vv.FieldJsonName) 898 fpart.WriteString("`") 899 fpart.WriteString(",") 900 } 901 case_part, case_arg := self.BuildWhereCase(cnd.Offset(0, 1)) 902 for _, v := range case_arg { 903 parameter = append(parameter, v) 904 } 905 var vpart *bytes.Buffer 906 if case_part.Len() > 0 { 907 vpart = bytes.NewBuffer(make([]byte, 0, case_part.Len()+16)) 908 vpart.WriteString("where") 909 str := case_part.String() 910 vpart.WriteString(utils.Substr(str, 0, len(str)-3)) 911 } 912 str1 := utils.Bytes2Str(fpart.Bytes()) 913 str2 := "" 914 if vpart != nil { 915 str2 = utils.Bytes2Str(vpart.Bytes()) 916 } 917 sortby := self.BuildSortBy(cnd) 918 sqlbuf := bytes.NewBuffer(make([]byte, 0, len(str1)+len(str2)+len(sortby)+32)) 919 sqlbuf.WriteString("select ") 920 sqlbuf.WriteString(utils.Substr(str1, 0, len(str1)-1)) 921 sqlbuf.WriteString(" from ") 922 sqlbuf.WriteString(obv.TableName) 923 sqlbuf.WriteString(" ") 924 if len(str2) > 0 { 925 sqlbuf.WriteString(utils.Substr(str2, 0, len(str2)-1)) 926 } 927 if len(sortby) > 0 { 928 sqlbuf.WriteString(sortby) 929 } 930 sqlbuf.WriteString(" limit 1") 931 // cnd.Pagination = dialect.Dialect{PageNo: 1, PageSize: 1} 932 // prepare, err := self.BuildPagination(cnd, utils.Bytes2Str(sqlbuf.Bytes()), parameter) 933 // if err != nil { 934 // return self.Error(err) 935 // } 936 prepare := utils.Bytes2Str(sqlbuf.Bytes()) 937 if zlog.IsDebug() { 938 defer zlog.Debug("[Mysql.FindOne] sql log", utils.UnixMilli(), zlog.String("sql", prepare), zlog.Any("values", parameter)) 939 } 940 ctx, cancel := context.WithTimeout(context.Background(), time.Duration(self.Timeout)*time.Millisecond) 941 defer cancel() 942 var err error 943 var stmt *sql.Stmt 944 var rows *sql.Rows 945 if self.OpenTx { 946 stmt, err = self.Tx.PrepareContext(ctx, prepare) 947 } else { 948 stmt, err = self.Db.PrepareContext(ctx, prepare) 949 } 950 if err != nil { 951 return self.Error("[Mysql.FindOne] [ ", prepare, " ] prepare failed: ", err) 952 } 953 defer stmt.Close() 954 rows, err = stmt.QueryContext(ctx, parameter...) 955 if err != nil { 956 return self.Error("[Mysql.FindOne] query failed: ", err) 957 } 958 defer rows.Close() 959 cols, err := rows.Columns() 960 if err != nil { 961 return self.Error("[Mysql.FindOne] read columns failed: ", err) 962 } 963 var first [][]byte 964 if out, err := OutDest(rows, len(cols)); err != nil { 965 return self.Error("[Mysql.FindOne] read result failed: ", err) 966 } else if len(out) == 0 { 967 return nil 968 } else { 969 first = out[0] 970 } 971 for i, vv := range obv.FieldElem { 972 if vv.Ignore { 973 continue 974 } 975 if err := SetValue(data, vv, first[i]); err != nil { 976 return self.Error(err) 977 } 978 } 979 return nil 980 } 981 982 func (self *RDBManager) FindList(cnd *sqlc.Cnd, data interface{}) error { 983 if data == nil { 984 return self.Error("[Mysql.FindList] data is nil") 985 } 986 if cnd.Model == nil { 987 return self.Error("[Mysql.FindList] model is nil") 988 } 989 obv, ok := modelDrivers[cnd.Model.GetTable()] 990 if !ok { 991 return self.Error("[Mysql.FindList] registration object type not found [", cnd.Model.GetTable(), "]") 992 } 993 fpart := bytes.NewBuffer(make([]byte, 0, 14*len(obv.FieldElem))) 994 for _, vv := range obv.FieldElem { 995 if vv.Ignore { 996 continue 997 } 998 fpart.WriteString("`") 999 fpart.WriteString(vv.FieldJsonName) 1000 fpart.WriteString("`") 1001 fpart.WriteString(",") 1002 } 1003 case_part, case_arg := self.BuildWhereCase(cnd) 1004 parameter := make([]interface{}, 0, len(case_arg)) 1005 for _, v := range case_arg { 1006 parameter = append(parameter, v) 1007 } 1008 var vpart *bytes.Buffer 1009 if case_part.Len() > 0 { 1010 vpart = bytes.NewBuffer(make([]byte, 0, case_part.Len()+16)) 1011 vpart.WriteString("where") 1012 str := case_part.String() 1013 vpart.WriteString(utils.Substr(str, 0, len(str)-3)) 1014 } 1015 str1 := utils.Bytes2Str(fpart.Bytes()) 1016 str2 := "" 1017 if vpart != nil { 1018 str2 = utils.Bytes2Str(vpart.Bytes()) 1019 } 1020 groupby := self.BuildGroupBy(cnd) 1021 sortby := self.BuildSortBy(cnd) 1022 sqlbuf := bytes.NewBuffer(make([]byte, 0, len(str1)+len(str2)+len(groupby)+len(sortby)+32)) 1023 sqlbuf.WriteString("select ") 1024 sqlbuf.WriteString(utils.Substr(str1, 0, len(str1)-1)) 1025 sqlbuf.WriteString(" from ") 1026 sqlbuf.WriteString(obv.TableName) 1027 sqlbuf.WriteString(" ") 1028 if len(str2) > 0 { 1029 sqlbuf.WriteString(utils.Substr(str2, 0, len(str2)-1)) 1030 } 1031 if len(groupby) > 0 { 1032 sqlbuf.WriteString(groupby) 1033 } 1034 if len(sortby) > 0 { 1035 sqlbuf.WriteString(sortby) 1036 } 1037 prepare, err := self.BuildPagination(cnd, utils.Bytes2Str(sqlbuf.Bytes()), parameter) 1038 if err != nil { 1039 return self.Error(err) 1040 } 1041 if zlog.IsDebug() { 1042 defer zlog.Debug("[Mysql.FindList] sql log", utils.UnixMilli(), zlog.String("sql", prepare), zlog.Any("values", parameter)) 1043 } 1044 ctx, cancel := context.WithTimeout(context.Background(), time.Duration(self.Timeout)*time.Millisecond) 1045 defer cancel() 1046 var stmt *sql.Stmt 1047 var rows *sql.Rows 1048 if self.OpenTx { 1049 stmt, err = self.Tx.PrepareContext(ctx, prepare) 1050 } else { 1051 stmt, err = self.Db.PrepareContext(ctx, prepare) 1052 } 1053 if err != nil { 1054 return self.Error("[Mysql.FindList] [ ", prepare, " ] prepare failed: ", err) 1055 } 1056 defer stmt.Close() 1057 rows, err = stmt.QueryContext(ctx, parameter...) 1058 if err != nil { 1059 return self.Error("[Mysql.FindList] query failed: ", err) 1060 } 1061 defer rows.Close() 1062 cols, err := rows.Columns() 1063 if err != nil { 1064 return self.Error("[Mysql.FindList] read columns failed: ", err) 1065 } 1066 out, err := OutDest(rows, len(cols)) 1067 if err != nil { 1068 return self.Error("[Mysql.FindList] read result failed: ", err) 1069 } else if len(out) == 0 { 1070 if cnd.Pagination.IsPage { 1071 cnd.Pagination.PageCount = 0 1072 cnd.Pagination.PageTotal = 0 1073 } 1074 return nil 1075 } 1076 resultv := reflect.ValueOf(data) 1077 if resultv.Kind() != reflect.Ptr { 1078 return self.Error("[Mysql.FindList] target value kind not ptr") 1079 } 1080 slicev := resultv.Elem() 1081 if slicev.Kind() != reflect.Slice { 1082 return self.Error("[Mysql.FindList] target value kind not slice") 1083 } 1084 slicev = slicev.Slice(0, slicev.Cap()) 1085 for _, v := range out { 1086 model := cnd.Model.NewObject() 1087 for i := 0; i < len(obv.FieldElem); i++ { 1088 vv := obv.FieldElem[i] 1089 if vv.Ignore { 1090 continue 1091 } 1092 if vv.IsDate && v[i] == nil { 1093 continue 1094 } 1095 if err := SetValue(model, vv, v[i]); err != nil { 1096 return self.Error(err) 1097 } 1098 } 1099 slicev = reflect.Append(slicev, reflect.ValueOf(model)) 1100 } 1101 slicev = slicev.Slice(0, slicev.Cap()) 1102 resultv.Elem().Set(slicev.Slice(0, len(out))) 1103 return nil 1104 } 1105 1106 func (self *RDBManager) Count(cnd *sqlc.Cnd) (int64, error) { 1107 if cnd.Model == nil { 1108 return 0, self.Error("[Mysql.Count] data is nil") 1109 } 1110 obv, ok := modelDrivers[cnd.Model.GetTable()] 1111 if !ok { 1112 return 0, self.Error("[Mysql.Count] registration object type not found [", cnd.Model.GetTable(), "]") 1113 } 1114 fpart := bytes.NewBuffer(make([]byte, 0, 32)) 1115 fpart.WriteString("count(1)") 1116 case_part, case_arg := self.BuildWhereCase(cnd) 1117 parameter := make([]interface{}, 0, len(case_arg)) 1118 for _, v := range case_arg { 1119 parameter = append(parameter, v) 1120 } 1121 var vpart *bytes.Buffer 1122 if case_part.Len() > 0 { 1123 vpart = bytes.NewBuffer(make([]byte, 0, case_part.Len()+16)) 1124 vpart.WriteString("where") 1125 str := case_part.String() 1126 vpart.WriteString(utils.Substr(str, 0, len(str)-3)) 1127 } 1128 str1 := utils.Bytes2Str(fpart.Bytes()) 1129 str2 := "" 1130 if vpart != nil { 1131 str2 = utils.Bytes2Str(vpart.Bytes()) 1132 } 1133 sqlbuf := bytes.NewBuffer(make([]byte, 0, len(str1)+len(str2)+32)) 1134 sqlbuf.WriteString("select ") 1135 sqlbuf.WriteString(str1) 1136 sqlbuf.WriteString(" from ") 1137 sqlbuf.WriteString(obv.TableName) 1138 sqlbuf.WriteString(" ") 1139 if len(str2) > 0 { 1140 sqlbuf.WriteString(utils.Substr(str2, 0, len(str2)-1)) 1141 } 1142 prepare := utils.Bytes2Str(sqlbuf.Bytes()) 1143 if zlog.IsDebug() { 1144 defer zlog.Debug("[Mysql.Count] sql log", utils.UnixMilli(), zlog.String("sql", prepare), zlog.Any("values", parameter)) 1145 } 1146 ctx, cancel := context.WithTimeout(context.Background(), time.Duration(self.Timeout)*time.Millisecond) 1147 defer cancel() 1148 var err error 1149 var rows *sql.Rows 1150 var stmt *sql.Stmt 1151 if self.OpenTx { 1152 stmt, err = self.Tx.PrepareContext(ctx, prepare) 1153 } else { 1154 stmt, err = self.Db.PrepareContext(ctx, prepare) 1155 } 1156 if err != nil { 1157 return 0, self.Error("[Mysql.Count] [ ", prepare, " ] prepare failed: ", err) 1158 } 1159 defer stmt.Close() 1160 rows, err = stmt.QueryContext(ctx, parameter...) 1161 if err != nil { 1162 return 0, utils.Error("[Mysql.Count] query failed: ", err) 1163 } 1164 defer rows.Close() 1165 var pageTotal int64 1166 for rows.Next() { 1167 if err := rows.Scan(&pageTotal); err != nil { 1168 return 0, self.Error("[Mysql.Count] read total failed: ", err) 1169 } 1170 } 1171 if err := rows.Err(); err != nil { 1172 return 0, self.Error("[Mysql.Count] read result failed: ", err) 1173 } 1174 if pageTotal > 0 && cnd.Pagination.PageSize > 0 { 1175 var pageCount int64 1176 if pageTotal%cnd.Pagination.PageSize == 0 { 1177 pageCount = pageTotal / cnd.Pagination.PageSize 1178 } else { 1179 pageCount = pageTotal/cnd.Pagination.PageSize + 1 1180 } 1181 cnd.Pagination.PageCount = pageCount 1182 } else { 1183 cnd.Pagination.PageCount = 0 1184 } 1185 cnd.Pagination.PageTotal = pageTotal 1186 return pageTotal, nil 1187 } 1188 1189 func (self *RDBManager) Exists(cnd *sqlc.Cnd) (bool, error) { 1190 if cnd.Model == nil { 1191 return false, self.Error("[Mysql.Exists] data is nil") 1192 } 1193 obv, ok := modelDrivers[cnd.Model.GetTable()] 1194 if !ok { 1195 return false, self.Error("[Mysql.Exists] registration object type not found [", cnd.Model.GetTable(), "]") 1196 } 1197 fpart := bytes.NewBuffer(make([]byte, 0, 32)) 1198 fpart.WriteString("1") 1199 case_part, case_arg := self.BuildWhereCase(cnd) 1200 parameter := make([]interface{}, 0, len(case_arg)) 1201 for _, v := range case_arg { 1202 parameter = append(parameter, v) 1203 } 1204 var vpart *bytes.Buffer 1205 if case_part.Len() > 0 { 1206 vpart = bytes.NewBuffer(make([]byte, 0, case_part.Len()+16)) 1207 vpart.WriteString("where") 1208 str := case_part.String() 1209 vpart.WriteString(utils.Substr(str, 0, len(str)-3)) 1210 } 1211 str1 := utils.Bytes2Str(fpart.Bytes()) 1212 str2 := "" 1213 if vpart != nil { 1214 str2 = utils.Bytes2Str(vpart.Bytes()) 1215 } 1216 sqlbuf := bytes.NewBuffer(make([]byte, 0, len(str1)+len(str2)+64)) 1217 sqlbuf.WriteString("select exists(") 1218 sqlbuf.WriteString("select ") 1219 sqlbuf.WriteString(str1) 1220 sqlbuf.WriteString(" from ") 1221 sqlbuf.WriteString(obv.TableName) 1222 sqlbuf.WriteString(" ") 1223 if len(str2) > 0 { 1224 sqlbuf.WriteString(utils.Substr(str2, 0, len(str2)-1)) 1225 } 1226 sqlbuf.WriteString(" limit 1 ") 1227 sqlbuf.WriteString(" ) as pub_exists") 1228 prepare := utils.Bytes2Str(sqlbuf.Bytes()) 1229 if zlog.IsDebug() { 1230 defer zlog.Debug("[Mysql.Exists] sql log", utils.UnixMilli(), zlog.String("sql", prepare), zlog.Any("values", parameter)) 1231 } 1232 ctx, cancel := context.WithTimeout(context.Background(), time.Duration(self.Timeout)*time.Millisecond) 1233 defer cancel() 1234 var err error 1235 var rows *sql.Rows 1236 var stmt *sql.Stmt 1237 if self.OpenTx { 1238 stmt, err = self.Tx.PrepareContext(ctx, prepare) 1239 } else { 1240 stmt, err = self.Db.PrepareContext(ctx, prepare) 1241 } 1242 if err != nil { 1243 return false, self.Error("[Mysql.Exists] [ ", prepare, " ] prepare failed: ", err) 1244 } 1245 defer stmt.Close() 1246 rows, err = stmt.QueryContext(ctx, parameter...) 1247 if err != nil { 1248 return false, utils.Error("[Mysql.Exists] query failed: ", err) 1249 } 1250 defer rows.Close() 1251 var exists int64 1252 for rows.Next() { 1253 if err := rows.Scan(&exists); err != nil { 1254 return false, self.Error("[Mysql.Exists] read total failed: ", err) 1255 } 1256 } 1257 if err := rows.Err(); err != nil { 1258 return false, self.Error("[Mysql.Exists] read result failed: ", err) 1259 } 1260 return exists > 0, nil 1261 } 1262 1263 func (self *RDBManager) FindListComplex(cnd *sqlc.Cnd, data interface{}) error { 1264 if data == nil { 1265 return self.Error("[Mysql.FindListComplex] data is nil") 1266 } 1267 if cnd.Model == nil { 1268 return self.Error("[Mysql.FindListComplex] model is nil") 1269 } 1270 if cnd.FromCond == nil || len(cnd.FromCond.Table) == 0 { 1271 return self.Error("[Mysql.FindListComplex] from table is nil") 1272 } 1273 if cnd.AnyFields == nil || len(cnd.AnyFields) == 0 { 1274 return self.Error("[Mysql.FindListComplex] any fields is nil") 1275 } 1276 obv, ok := modelDrivers[cnd.Model.GetTable()] 1277 if !ok { 1278 return self.Error("[Mysql.FindListComplex] registration object type not found [", cnd.Model.GetTable(), "]") 1279 } 1280 fpart := bytes.NewBuffer(make([]byte, 0, 32*len(cnd.AnyFields))) 1281 for _, vv := range cnd.AnyFields { 1282 if cnd.Escape { 1283 fpart.WriteString("`") 1284 fpart.WriteString(vv) 1285 fpart.WriteString("`") 1286 fpart.WriteString(",") 1287 } else { 1288 fpart.WriteString(vv) 1289 fpart.WriteString(",") 1290 } 1291 } 1292 case_part, case_arg := self.BuildWhereCase(cnd) 1293 parameter := make([]interface{}, 0, len(case_arg)) 1294 for _, v := range case_arg { 1295 parameter = append(parameter, v) 1296 } 1297 var vpart *bytes.Buffer 1298 if case_part.Len() > 0 { 1299 vpart = bytes.NewBuffer(make([]byte, 0, case_part.Len()+16)) 1300 vpart.WriteString("where") 1301 str := case_part.String() 1302 vpart.WriteString(utils.Substr(str, 0, len(str)-3)) 1303 } 1304 str1 := utils.Bytes2Str(fpart.Bytes()) 1305 str2 := "" 1306 if vpart != nil { 1307 str2 = utils.Bytes2Str(vpart.Bytes()) 1308 } 1309 groupby := self.BuildGroupBy(cnd) 1310 sortby := self.BuildSortBy(cnd) 1311 sqlbuf := bytes.NewBuffer(make([]byte, 0, len(str1)+len(str2)+len(groupby)+len(sortby)+32)) 1312 sqlbuf.WriteString("select ") 1313 sqlbuf.WriteString(utils.Substr(str1, 0, len(str1)-1)) 1314 sqlbuf.WriteString(" from ") 1315 sqlbuf.WriteString(cnd.FromCond.Table) 1316 sqlbuf.WriteString(" ") 1317 sqlbuf.WriteString(cnd.FromCond.Alias) 1318 sqlbuf.WriteString(" ") 1319 if len(cnd.JoinCond) > 0 { 1320 for _, v := range cnd.JoinCond { 1321 if len(v.Table) == 0 || len(v.On) == 0 { 1322 continue 1323 } 1324 if v.Type == sqlc.LEFT_ { 1325 sqlbuf.WriteString(" left join ") 1326 } else if v.Type == sqlc.RIGHT_ { 1327 sqlbuf.WriteString(" right join ") 1328 } else if v.Type == sqlc.INNER_ { 1329 sqlbuf.WriteString(" inner join ") 1330 } else { 1331 continue 1332 } 1333 sqlbuf.WriteString(v.Table) 1334 sqlbuf.WriteString(" on ") 1335 sqlbuf.WriteString(v.On) 1336 sqlbuf.WriteString(" ") 1337 } 1338 } 1339 if len(str2) > 0 { 1340 sqlbuf.WriteString(utils.Substr(str2, 0, len(str2)-1)) 1341 } 1342 if len(groupby) > 0 { 1343 sqlbuf.WriteString(groupby) 1344 } 1345 if len(sortby) > 0 { 1346 sqlbuf.WriteString(sortby) 1347 } 1348 1349 prepare, err := self.BuildPagination(cnd, utils.Bytes2Str(sqlbuf.Bytes()), parameter) 1350 if err != nil { 1351 return self.Error(err) 1352 } 1353 if zlog.IsDebug() { 1354 defer zlog.Debug("[Mysql.FindListComplex] sql log", utils.UnixMilli(), zlog.String("sql", prepare), zlog.Any("values", parameter)) 1355 } 1356 ctx, cancel := context.WithTimeout(context.Background(), time.Duration(self.Timeout)*time.Millisecond) 1357 defer cancel() 1358 var stmt *sql.Stmt 1359 var rows *sql.Rows 1360 if self.OpenTx { 1361 stmt, err = self.Tx.PrepareContext(ctx, prepare) 1362 } else { 1363 stmt, err = self.Db.PrepareContext(ctx, prepare) 1364 } 1365 if err != nil { 1366 return self.Error("[Mysql.FindListComplex] [ ", prepare, " ] prepare failed: ", err) 1367 } 1368 defer stmt.Close() 1369 rows, err = stmt.QueryContext(ctx, parameter...) 1370 if err != nil { 1371 return self.Error("[Mysql.FindListComplex] query failed: ", err) 1372 } 1373 defer rows.Close() 1374 cols, err := rows.Columns() 1375 if err != nil { 1376 return self.Error("[Mysql.FindListComplex] read columns failed: ", err) 1377 } 1378 if len(cols) != len(cnd.AnyFields) { 1379 return self.Error("[Mysql.FindListComplex] read columns length invalid") 1380 } 1381 out, err := OutDest(rows, len(cols)) 1382 if err != nil { 1383 return self.Error("[Mysql.FindListComplex] read result failed: ", err) 1384 } else if len(out) == 0 { 1385 if cnd.Pagination.IsPage { 1386 cnd.Pagination.PageCount = 0 1387 cnd.Pagination.PageTotal = 0 1388 } 1389 return nil 1390 } 1391 resultv := reflect.ValueOf(data) 1392 if resultv.Kind() != reflect.Ptr { 1393 return self.Error("[Mysql.FindList] target value kind not ptr") 1394 } 1395 slicev := resultv.Elem() 1396 if slicev.Kind() != reflect.Slice { 1397 return self.Error("[Mysql.FindList] target value kind not slice") 1398 } 1399 slicev = slicev.Slice(0, slicev.Cap()) 1400 for _, v := range out { 1401 model := cnd.Model.NewObject() 1402 for i := 0; i < len(cols); i++ { 1403 for _, vv := range obv.FieldElem { 1404 if vv.FieldJsonName == cols[i] { 1405 if err := SetValue(model, vv, v[i]); err != nil { 1406 return self.Error(err) 1407 } 1408 break 1409 } 1410 } 1411 } 1412 slicev = reflect.Append(slicev, reflect.ValueOf(model)) 1413 } 1414 slicev = slicev.Slice(0, slicev.Cap()) 1415 resultv.Elem().Set(slicev.Slice(0, len(out))) 1416 return nil 1417 } 1418 1419 func (self *RDBManager) FindOneComplex(cnd *sqlc.Cnd, data sqlc.Object) error { 1420 if data == nil { 1421 return self.Error("[Mysql.FindOneComplex] data is nil") 1422 } 1423 if cnd.FromCond == nil || len(cnd.FromCond.Table) == 0 { 1424 return self.Error("[Mysql.FindOneComplex] from table is nil") 1425 } 1426 if cnd.AnyFields == nil || len(cnd.AnyFields) == 0 { 1427 return self.Error("[Mysql.FindOneComplex] any fields is nil") 1428 } 1429 obv, ok := modelDrivers[data.GetTable()] 1430 if !ok { 1431 return self.Error("[Mysql.FindOneComplex] registration object type not found [", data.GetTable(), "]") 1432 } 1433 fpart := bytes.NewBuffer(make([]byte, 0, 32*len(cnd.AnyFields))) 1434 for _, vv := range cnd.AnyFields { 1435 if cnd.Escape { 1436 fpart.WriteString("`") 1437 fpart.WriteString(vv) 1438 fpart.WriteString("`") 1439 fpart.WriteString(",") 1440 } else { 1441 fpart.WriteString(vv) 1442 fpart.WriteString(",") 1443 } 1444 } 1445 case_part, case_arg := self.BuildWhereCase(cnd.Offset(0, 1)) 1446 parameter := make([]interface{}, 0, len(case_arg)) 1447 for _, v := range case_arg { 1448 parameter = append(parameter, v) 1449 } 1450 var vpart *bytes.Buffer 1451 if case_part.Len() > 0 { 1452 vpart = bytes.NewBuffer(make([]byte, 0, case_part.Len()+16)) 1453 vpart.WriteString("where") 1454 str := case_part.String() 1455 vpart.WriteString(utils.Substr(str, 0, len(str)-3)) 1456 } 1457 str1 := utils.Bytes2Str(fpart.Bytes()) 1458 str2 := "" 1459 if vpart != nil { 1460 str2 = utils.Bytes2Str(vpart.Bytes()) 1461 } 1462 groupby := self.BuildGroupBy(cnd) 1463 sortby := self.BuildSortBy(cnd) 1464 sqlbuf := bytes.NewBuffer(make([]byte, 0, len(str1)+len(str2)+len(groupby)+len(sortby)+32)) 1465 sqlbuf.WriteString("select ") 1466 sqlbuf.WriteString(utils.Substr(str1, 0, len(str1)-1)) 1467 sqlbuf.WriteString(" from ") 1468 sqlbuf.WriteString(cnd.FromCond.Table) 1469 sqlbuf.WriteString(" ") 1470 sqlbuf.WriteString(cnd.FromCond.Alias) 1471 sqlbuf.WriteString(" ") 1472 if len(cnd.JoinCond) > 0 { 1473 for _, v := range cnd.JoinCond { 1474 if len(v.Table) == 0 || len(v.On) == 0 { 1475 continue 1476 } 1477 if v.Type == sqlc.LEFT_ { 1478 sqlbuf.WriteString(" left join ") 1479 } else if v.Type == sqlc.RIGHT_ { 1480 sqlbuf.WriteString(" right join ") 1481 } else if v.Type == sqlc.INNER_ { 1482 sqlbuf.WriteString(" inner join ") 1483 } else { 1484 continue 1485 } 1486 sqlbuf.WriteString(v.Table) 1487 sqlbuf.WriteString(" on ") 1488 sqlbuf.WriteString(v.On) 1489 sqlbuf.WriteString(" ") 1490 } 1491 } 1492 if len(str2) > 0 { 1493 sqlbuf.WriteString(utils.Substr(str2, 0, len(str2)-1)) 1494 } 1495 if len(groupby) > 0 { 1496 sqlbuf.WriteString(groupby) 1497 } 1498 if len(sortby) > 0 { 1499 sqlbuf.WriteString(sortby) 1500 } 1501 sqlbuf.WriteString(" limit 1") 1502 // prepare, err := self.BuildPagination(cnd, utils.Bytes2Str(sqlbuf.Bytes()), parameter) 1503 // if err != nil { 1504 // return self.Error(err) 1505 // } 1506 prepare := utils.Bytes2Str(sqlbuf.Bytes()) 1507 if zlog.IsDebug() { 1508 defer zlog.Debug("[Mysql.FindOneComplex] sql log", utils.UnixMilli(), zlog.String("sql", prepare), zlog.Any("values", parameter)) 1509 } 1510 ctx, cancel := context.WithTimeout(context.Background(), time.Duration(self.Timeout)*time.Millisecond) 1511 defer cancel() 1512 var err error 1513 var stmt *sql.Stmt 1514 var rows *sql.Rows 1515 if self.OpenTx { 1516 stmt, err = self.Tx.PrepareContext(ctx, prepare) 1517 } else { 1518 stmt, err = self.Db.PrepareContext(ctx, prepare) 1519 } 1520 if err != nil { 1521 return self.Error("[Mysql.FindOneComplex] [ ", prepare, " ] prepare failed: ", err) 1522 } 1523 defer stmt.Close() 1524 rows, err = stmt.QueryContext(ctx, parameter...) 1525 if err != nil { 1526 return self.Error("[Mysql.FindOneComplex] query failed: ", err) 1527 } 1528 defer rows.Close() 1529 cols, err := rows.Columns() 1530 if err != nil { 1531 return self.Error("[Mysql.FindOneComplex] read columns failed: ", err) 1532 } 1533 if len(cols) != len(cnd.AnyFields) { 1534 return self.Error("[Mysql.FindOneComplex] read columns length invalid") 1535 } 1536 var first [][]byte 1537 if out, err := OutDest(rows, len(cols)); err != nil { 1538 return self.Error("[Mysql.FindOneComplex] read result failed: ", err) 1539 } else if len(out) == 0 { 1540 return nil 1541 } else { 1542 first = out[0] 1543 } 1544 for i := 0; i < len(cols); i++ { 1545 for _, vv := range obv.FieldElem { 1546 if vv.FieldJsonName == cols[i] { 1547 if err := SetValue(data, vv, first[i]); err != nil { 1548 return self.Error(err) 1549 } 1550 break 1551 } 1552 } 1553 } 1554 return nil 1555 } 1556 1557 func (self *RDBManager) Close() error { 1558 if self.OpenTx && self.Tx != nil { 1559 if self.Errors == nil && len(self.Errors) == 0 { 1560 if err := self.Tx.Commit(); err != nil { 1561 zlog.Error("transaction commit failed", 0, zlog.AddError(err)) 1562 return nil 1563 } 1564 } else { 1565 if err := self.Tx.Rollback(); err != nil { 1566 zlog.Error("transaction rollback failed", 0, zlog.AddError(err)) 1567 } 1568 return nil 1569 } 1570 } 1571 if self.Errors == nil && len(self.Errors) == 0 && self.MongoSync && len(self.MGOSyncData) > 0 { 1572 for _, v := range self.MGOSyncData { 1573 if len(v.CacheObject) > 0 { 1574 if err := self.mongoSyncData(v.CacheOption, v.CacheModel, v.CacheCnd, v.CacheObject...); err != nil { 1575 zlog.Error("MySQL data synchronization Mongo failed", 0, zlog.Any("data", v), zlog.AddError(err)) 1576 } 1577 } 1578 } 1579 } 1580 return nil 1581 } 1582 1583 // mongo同步数据 1584 func (self *RDBManager) mongoSyncData(option int, model sqlc.Object, cnd *sqlc.Cnd, data ...sqlc.Object) error { 1585 mongo, err := new(MGOManager).Get(self.Option) 1586 if err != nil { 1587 return utils.Error("failed to get Mongo connection: ", err) 1588 } 1589 defer mongo.Close() 1590 mongo.MGOSyncData = []*MGOSyncData{ 1591 {option, model, cnd, data}, 1592 } 1593 switch option { 1594 case SAVE: 1595 return mongo.Save(data...) 1596 case UPDATE: 1597 return mongo.Update(data...) 1598 case DELETE: 1599 return mongo.Delete(data...) 1600 case UPDATE_BY_CND: 1601 if cnd == nil { 1602 return utils.Error("synchronization condition object is nil") 1603 } 1604 _, err = mongo.UpdateByCnd(cnd) 1605 if err != nil { 1606 return err 1607 } 1608 return nil 1609 } 1610 return nil 1611 } 1612 1613 // 输出查询结果集 1614 func OutDest(rows *sql.Rows, flen int) ([][][]byte, error) { 1615 out := make([][][]byte, 0) 1616 for rows.Next() { 1617 rets := make([][]byte, flen) 1618 dest := make([]interface{}, flen) 1619 for i, _ := range rets { 1620 dest[i] = &rets[i] 1621 } 1622 if err := rows.Scan(dest...); err != nil { 1623 return nil, utils.Error("rows scan failed: ", err) 1624 } 1625 out = append(out, rets) 1626 } 1627 if err := rows.Err(); err != nil { 1628 return nil, utils.Error("rows.Err(): ", err) 1629 } 1630 return out, nil 1631 } 1632 1633 func (self *RDBManager) BuildCondKey(cnd *sqlc.Cnd, key string) []byte { 1634 fieldPart := bytes.NewBuffer(make([]byte, 0, 16)) 1635 if cnd.Escape { 1636 fieldPart.WriteString(" ") 1637 fieldPart.WriteString("`") 1638 fieldPart.WriteString(key) 1639 fieldPart.WriteString("`") 1640 } else { 1641 fieldPart.WriteString(" ") 1642 fieldPart.WriteString(key) 1643 } 1644 return fieldPart.Bytes() 1645 } 1646 1647 // 构建where条件 1648 func (self *RDBManager) BuildWhereCase(cnd *sqlc.Cnd) (*bytes.Buffer, []interface{}) { 1649 var case_arg []interface{} 1650 if cnd == nil { 1651 return bytes.NewBuffer(make([]byte, 0, 64)), case_arg 1652 } 1653 case_part := bytes.NewBuffer(make([]byte, 0, 128)) 1654 for _, v := range cnd.Conditions { 1655 key := v.Key 1656 value := v.Value 1657 values := v.Values 1658 switch v.Logic { 1659 // case condition 1660 case sqlc.EQ_: 1661 case_part.Write(self.BuildCondKey(cnd, key)) 1662 case_part.WriteString(" = ? and") 1663 case_arg = append(case_arg, value) 1664 case sqlc.NOT_EQ_: 1665 case_part.Write(self.BuildCondKey(cnd, key)) 1666 case_part.WriteString(" <> ? and") 1667 case_arg = append(case_arg, value) 1668 case sqlc.LT_: 1669 case_part.Write(self.BuildCondKey(cnd, key)) 1670 case_part.WriteString(" < ? and") 1671 case_arg = append(case_arg, value) 1672 case sqlc.LTE_: 1673 case_part.Write(self.BuildCondKey(cnd, key)) 1674 case_part.WriteString(" <= ? and") 1675 case_arg = append(case_arg, value) 1676 case sqlc.GT_: 1677 case_part.Write(self.BuildCondKey(cnd, key)) 1678 case_part.WriteString(" > ? and") 1679 case_arg = append(case_arg, value) 1680 case sqlc.GTE_: 1681 case_part.Write(self.BuildCondKey(cnd, key)) 1682 case_part.WriteString(" >= ? and") 1683 case_arg = append(case_arg, value) 1684 case sqlc.IS_NULL_: 1685 case_part.Write(self.BuildCondKey(cnd, key)) 1686 case_part.WriteString(" is null and") 1687 case sqlc.IS_NOT_NULL_: 1688 case_part.Write(self.BuildCondKey(cnd, key)) 1689 case_part.WriteString(" is not null and") 1690 case sqlc.BETWEEN_: 1691 case_part.Write(self.BuildCondKey(cnd, key)) 1692 case_part.WriteString(" between ? and ? and") 1693 case_arg = append(case_arg, values[0]) 1694 case_arg = append(case_arg, values[1]) 1695 case sqlc.NOT_BETWEEN_: 1696 case_part.Write(self.BuildCondKey(cnd, key)) 1697 case_part.WriteString(" not between ? and ? and") 1698 case_arg = append(case_arg, values[0]) 1699 case_arg = append(case_arg, values[1]) 1700 case sqlc.IN_: 1701 case_part.Write(self.BuildCondKey(cnd, key)) 1702 case_part.WriteString(" in(") 1703 var buf bytes.Buffer 1704 for _, v := range values { 1705 buf.WriteString("?,") 1706 case_arg = append(case_arg, v) 1707 } 1708 s := buf.String() 1709 case_part.WriteString(utils.Substr(s, 0, len(s)-1)) 1710 case_part.WriteString(") and") 1711 case sqlc.NOT_IN_: 1712 case_part.Write(self.BuildCondKey(cnd, key)) 1713 case_part.WriteString(" not in(") 1714 var buf bytes.Buffer 1715 for _, v := range values { 1716 buf.WriteString("?,") 1717 case_arg = append(case_arg, v) 1718 } 1719 s := buf.String() 1720 case_part.WriteString(utils.Substr(s, 0, len(s)-1)) 1721 case_part.WriteString(") and") 1722 case sqlc.LIKE_: 1723 case_part.Write(self.BuildCondKey(cnd, key)) 1724 case_part.WriteString(" like concat('%',?,'%') and") 1725 case_arg = append(case_arg, value) 1726 case sqlc.NOT_LIKE_: 1727 case_part.Write(self.BuildCondKey(cnd, key)) 1728 case_part.WriteString(" not like concat('%',?,'%') and") 1729 case_arg = append(case_arg, value) 1730 case sqlc.OR_: 1731 var orpart bytes.Buffer 1732 var args []interface{} 1733 for _, v := range values { 1734 cnd, ok := v.(*sqlc.Cnd) 1735 if !ok { 1736 continue 1737 } 1738 buf, arg := self.BuildWhereCase(cnd) 1739 s := buf.String() 1740 s = utils.Substr(s, 0, len(s)-3) 1741 orpart.WriteString(s) 1742 orpart.WriteString(" or") 1743 for _, v := range arg { 1744 args = append(args, v) 1745 } 1746 } 1747 s := orpart.String() 1748 s = utils.Substr(s, 0, len(s)-3) 1749 case_part.WriteString(" (") 1750 case_part.WriteString(s) 1751 case_part.WriteString(") and") 1752 for _, v := range args { 1753 case_arg = append(case_arg, v) 1754 } 1755 } 1756 } 1757 return case_part, case_arg 1758 } 1759 1760 // 构建分组命令 1761 func (self *RDBManager) BuildGroupBy(cnd *sqlc.Cnd) string { 1762 if cnd == nil || len(cnd.Groupbys) <= 0 { 1763 return "" 1764 } 1765 groupby := bytes.NewBuffer(make([]byte, 0, 64)) 1766 groupby.WriteString(" group by") 1767 for _, v := range cnd.Groupbys { 1768 if len(v) == 0 { 1769 continue 1770 } 1771 if cnd.Escape { 1772 groupby.WriteString(" ") 1773 groupby.WriteString("`") 1774 groupby.WriteString(v) 1775 groupby.WriteString("`") 1776 groupby.WriteString(",") 1777 } else { 1778 groupby.WriteString(" ") 1779 groupby.WriteString(v) 1780 groupby.WriteString(",") 1781 } 1782 } 1783 s := utils.Bytes2Str(groupby.Bytes()) 1784 return utils.Substr(s, 0, len(s)-1) 1785 } 1786 1787 // 构建排序命令 1788 func (self *RDBManager) BuildSortBy(cnd *sqlc.Cnd) string { 1789 if cnd == nil || len(cnd.Orderbys) <= 0 { 1790 return "" 1791 } 1792 var sortby = bytes.Buffer{} 1793 sortby.WriteString(" order by") 1794 for _, v := range cnd.Orderbys { 1795 if cnd.Escape { 1796 sortby.WriteString(" ") 1797 sortby.WriteString("`") 1798 sortby.WriteString(v.Key) 1799 sortby.WriteString("`") 1800 } else { 1801 sortby.WriteString(" ") 1802 sortby.WriteString(v.Key) 1803 } 1804 if v.Value == sqlc.DESC_ { 1805 sortby.WriteString(" desc,") 1806 } else if v.Value == sqlc.ASC_ { 1807 sortby.WriteString(" asc,") 1808 } 1809 } 1810 s := utils.Bytes2Str(sortby.Bytes()) 1811 return utils.Substr(s, 0, len(s)-1) 1812 } 1813 1814 // 构建分页命令 1815 func (self *RDBManager) BuildPagination(cnd *sqlc.Cnd, sqlbuf string, values []interface{}) (string, error) { 1816 if cnd == nil { 1817 return sqlbuf, nil 1818 } 1819 pagination := cnd.Pagination 1820 if pagination.PageNo == 0 && pagination.PageSize == 0 { 1821 return sqlbuf, nil 1822 } 1823 if pagination.PageSize <= 0 { 1824 pagination.PageSize = 10 1825 } 1826 dialect := dialect.MysqlDialect{Dialect: pagination} 1827 limitSql, err := dialect.GetLimitSql(sqlbuf) 1828 if err != nil { 1829 return "", err 1830 } 1831 if !dialect.IsPage { 1832 return limitSql, nil 1833 } 1834 if !dialect.IsOffset { 1835 countSql, err := dialect.GetCountSql(sqlbuf) 1836 if err != nil { 1837 return "", err 1838 } 1839 ctx, cancel := context.WithTimeout(context.Background(), time.Duration(self.Timeout)*time.Millisecond) 1840 defer cancel() 1841 var rows *sql.Rows 1842 if self.OpenTx { 1843 rows, err = self.Tx.QueryContext(ctx, countSql, values...) 1844 } else { 1845 rows, err = self.Db.QueryContext(ctx, countSql, values...) 1846 } 1847 if err != nil { 1848 return "", self.Error("count query failed: ", err) 1849 } 1850 defer rows.Close() 1851 var pageTotal int64 1852 for rows.Next() { 1853 if err := rows.Scan(&pageTotal); err != nil { 1854 return "", self.Error("rows scan failed: ", err) 1855 } 1856 } 1857 if err := rows.Err(); err != nil { 1858 return "", self.Error("rows.Err(): ", err) 1859 } 1860 var pageCount int64 1861 if pageTotal%cnd.Pagination.PageSize == 0 { 1862 pageCount = pageTotal / cnd.Pagination.PageSize 1863 } else { 1864 pageCount = pageTotal/cnd.Pagination.PageSize + 1 1865 } 1866 cnd.Pagination.PageTotal = pageTotal 1867 cnd.Pagination.PageCount = pageCount 1868 } 1869 return limitSql, nil 1870 }