浏览代码

in progress

0x4a52466c696e74 4 月之前
父节点
当前提交
8ecd567d0d
共有 2 个文件被更改,包括 99 次插入0 次删除
  1. 26 0
      rest_gorm/case.go
  2. 73 0
      rest_gorm/request_list.go

+ 26 - 0
rest_gorm/case.go

@@ -0,0 +1,26 @@
+package rest_gorm
+
+import (
+	"bytes"
+	"strings"
+	"unicode"
+)
+
+// CamelToSnake преобразует строку из CamelCase в snake_case.
+func CamelToSnake(s string) string {
+	var result bytes.Buffer
+	var lastIndex int = 0
+
+	for i, char := range s {
+		if i > 0 && unicode.IsUpper(char) && ((i+1 < len(s) && unicode.IsLower(rune(s[i+1]))) || unicode.IsLower(rune(s[i-1]))) {
+			result.WriteString(strings.ToLower(s[lastIndex:i]))
+			if lastIndex != i {
+				result.WriteString("_")
+			}
+			lastIndex = i
+		}
+	}
+	result.WriteString(strings.ToLower(s[lastIndex:]))
+
+	return result.String()
+}

+ 73 - 0
rest_gorm/request_list.go

@@ -0,0 +1,73 @@
+package rest_gorm
+
+import (
+	"fmt"
+
+	"git.ali33.ru/fcg-xvii/rest"
+	"gorm.io/gorm"
+	"gorm.io/gorm/clause"
+)
+
+type List struct {
+	Conditions rest.ConditionList `json:"Conditions" swagger:"items=$ref:rest.Condition"`
+	Orders     []*rest.Order      `json:"Orders" swagger:"items=$ref:rest.Order"`
+	Offset     int                `json:"Offset"`
+	Limit      int                `json:"Limit"`
+}
+
+func (s *List) Prepare() {
+	if s.Limit <= 0 || s.Limit > 20 {
+		s.Limit = 20
+	}
+}
+
+func (s *List) Result(pg *gorm.DB, fields rest.FieldNamesList, res any) (count int64, err rest.IErrorArgs) {
+	s.Prepare()
+	for i, cond := range s.Conditions {
+		if !cond.Logic.IsValid() {
+			err = rest.ErrorFiled(cond.Field, "Unexpected logic")
+			return
+		}
+		if !cond.Operator.IsValid() {
+			err = rest.ErrorFiled(cond.Field, "Unexpected operator")
+			return
+		}
+		if !fields.Exists(cond.Field) {
+			err = rest.ErrorFiled(cond.Field, "Unexpected field")
+			return
+		}
+		q := fmt.Sprintf("%s %s ?", CamelToSnake(cond.Field), cond.Operator)
+		if i == 0 || cond.Logic == rest.LogicAND {
+			pg = pg.Where(q, cond.Value)
+		} else {
+			pg = pg.Or(q, cond.Value)
+		}
+	}
+
+	// count
+	if dbRes := pg.Count(&count); dbRes.Error != nil {
+		err = rest.ErrorFiled("ErrDB", dbRes.Error.Error())
+		return
+	}
+
+	// offset limit
+	pg = pg.Offset(s.Offset).Limit(s.Limit)
+
+	// orders
+	for _, order := range s.Orders {
+		pg = pg.Order(
+			clause.OrderByColumn{
+				Column: clause.Column{
+					Name: CamelToSnake(order.Name),
+				},
+				Desc: !order.IsAsc,
+			},
+		)
+	}
+
+	if pg = pg.Find(res); pg.Error != nil {
+		err = rest.ErrorFiled("ErrDB", pg.Error.Error())
+		return
+	}
+	return
+}