operator.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. package gorm2op
  2. import (
  3. "fmt"
  4. "reflect"
  5. "regexp"
  6. "strings"
  7. "github.com/qor5/admin/presets"
  8. "github.com/qor5/web"
  9. "gorm.io/gorm"
  10. )
  11. var (
  12. wildcardReg = regexp.MustCompile(`[%_]`)
  13. )
  14. func DataOperator(db *gorm.DB) (r *DataOperatorBuilder) {
  15. r = &DataOperatorBuilder{db: db}
  16. return
  17. }
  18. type DataOperatorBuilder struct {
  19. db *gorm.DB
  20. }
  21. func (op *DataOperatorBuilder) Search(obj interface{}, params *presets.SearchParams, ctx *web.EventContext) (r interface{}, totalCount int, err error) {
  22. ilike := "ILIKE"
  23. if op.db.Dialector.Name() == "sqlite" {
  24. ilike = "LIKE"
  25. }
  26. wh := op.db.Model(obj)
  27. if len(params.KeywordColumns) > 0 && len(params.Keyword) > 0 {
  28. var segs []string
  29. var args []interface{}
  30. for _, c := range params.KeywordColumns {
  31. segs = append(segs, fmt.Sprintf("%s %s ?", c, ilike))
  32. kw := wildcardReg.ReplaceAllString(params.Keyword, `\$0`)
  33. args = append(args, fmt.Sprintf("%%%s%%", kw))
  34. }
  35. wh = wh.Where(strings.Join(segs, " OR "), args...)
  36. }
  37. for _, cond := range params.SQLConditions {
  38. wh = wh.Where(strings.Replace(cond.Query, " ILIKE ", " "+ilike+" ", -1), cond.Args...)
  39. }
  40. var c int64
  41. err = wh.Count(&c).Error
  42. if err != nil {
  43. return
  44. }
  45. totalCount = int(c)
  46. if params.PerPage > 0 {
  47. wh = wh.Limit(int(params.PerPage))
  48. page := params.Page
  49. if page == 0 {
  50. page = 1
  51. }
  52. offset := (page - 1) * params.PerPage
  53. wh = wh.Offset(int(offset))
  54. }
  55. orderBy := params.OrderBy
  56. if len(orderBy) > 0 {
  57. wh = wh.Order(orderBy)
  58. }
  59. err = wh.Find(obj).Error
  60. if err != nil {
  61. return
  62. }
  63. r = reflect.ValueOf(obj).Elem().Interface()
  64. return
  65. }
  66. func (op *DataOperatorBuilder) primarySluggerWhere(obj interface{}, id string) *gorm.DB {
  67. wh := op.db.Model(obj)
  68. if id == "" {
  69. return wh
  70. }
  71. if slugger, ok := obj.(presets.SlugDecoder); ok {
  72. cs := slugger.PrimaryColumnValuesBySlug(id)
  73. for key, value := range cs {
  74. wh = wh.Where(fmt.Sprintf("%s = ?", key), value)
  75. }
  76. } else {
  77. wh = wh.Where("id = ?", id)
  78. }
  79. return wh
  80. }
  81. func (op *DataOperatorBuilder) Fetch(obj interface{}, id string, ctx *web.EventContext) (r interface{}, err error) {
  82. err = op.primarySluggerWhere(obj, id).First(obj).Error
  83. if err != nil {
  84. if err == gorm.ErrRecordNotFound {
  85. return nil, presets.ErrRecordNotFound
  86. }
  87. return
  88. }
  89. r = obj
  90. return
  91. }
  92. func (op *DataOperatorBuilder) Save(obj interface{}, id string, ctx *web.EventContext) (err error) {
  93. if id == "" {
  94. err = op.db.Create(obj).Error
  95. return
  96. }
  97. err = op.primarySluggerWhere(obj, id).Save(obj).Error
  98. return
  99. }
  100. func (op *DataOperatorBuilder) Delete(obj interface{}, id string, ctx *web.EventContext) (err error) {
  101. err = op.primarySluggerWhere(obj, id).Delete(obj).Error
  102. return
  103. }