repository.go 2.1 KB
package domain

import (
	"fmt"
	"gorm.io/gorm"
	"gorm.io/gorm/clause"
	"reflect"
)

func OffsetLimit(page, size int) (offset int, limit int) {
	if page == 0 {
		page = 1
	}
	if size == 0 {
		size = 20
	}
	offset = (page - 1) * size
	limit = size
	return
}

type QueryOptions map[string]interface{}

func NewQueryOptions() QueryOptions {
	options := make(map[string]interface{})
	return options
}
func (options QueryOptions) WithOffsetLimit(page, size int) QueryOptions {
	offset, limit := OffsetLimit(page, size)
	options["offset"] = offset
	options["limit"] = limit
	return options
}

func (options QueryOptions) WithKV(key string, value interface{}) QueryOptions {
	if reflect.ValueOf(value).IsZero() {
		return options
	}
	options[key] = value
	return options
}

func (options QueryOptions) EnableCounter() QueryOptions {
	return options.WithKV("enableCounter", true)
}

func (options QueryOptions) Copy() QueryOptions {
	newOptions := NewQueryOptions()
	for k, v := range options {
		newOptions[k] = v
	}
	return newOptions
}

type IndexQueryOptionFunc func() QueryOptions

type JSONQueryContainExpression struct {
	column       string
	contain      bool
	containValue interface{}
}

func JSONQuery(column string) *JSONQueryContainExpression {
	return &JSONQueryContainExpression{
		column: column,
	}
}

func (jsonQuery *JSONQueryContainExpression) Contains(value interface{}) *JSONQueryContainExpression {
	jsonQuery.containValue = value
	jsonQuery.contain = true
	return jsonQuery
}

func (jsonQuery *JSONQueryContainExpression) Build(builder clause.Builder) {
	if stmt, ok := builder.(*gorm.Statement); ok {
		switch stmt.Dialector.Name() {
		case "mysql", "sqlite":
			switch {
			case jsonQuery.contain:
			}
		case "postgres":
			switch {
			case jsonQuery.contain:
				builder.WriteString(fmt.Sprintf("%v::jsonb ", stmt.Quote(jsonQuery.column)))

				builder.WriteString("@>'[")
				if _, ok := jsonQuery.containValue.(string); ok {
					builder.AddVar(builder, jsonQuery.containValue)
				} else {
					builder.AddVar(builder, jsonQuery.containValue)
				}
				builder.WriteString("]'")
			}
		}
	}
}