structquery

package module
v0.0.0-...-27c1c5a Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 15, 2022 License: MIT Imports: 7 Imported by: 1

README

structquery

gorm query with struct

Usage

package main

import (
	"fmt"

	"github.com/alingse/structquery"
	"gorm.io/gorm"
)

// DB ----------------------------------------------------------
type UserModel struct {
	gorm.Model
	Name  string `json:"name"`
	Email string `json:"email"`
}

func (u UserModel) TableName() string {
	return "users"
}

var DB = initGormDB()

var queryer = structquery.NewQueryer()

type UserModelQuery struct {
	Name  string `sq:"like"`
	Email string `sq:"eq"`
}

func main() {
	var q = UserModelQuery{
		Name:  "hello",
		Email: "a@b",
	}

	db := DB.Model(&User{})

	sql := db.ToSQL(func(tx *gorm.DB) *gorm.DB {
		var users []User

		tx, _ = queryer.Where(tx, q)
		return tx.Find(&users)
	})
	// SELECT * FROM `users` WHERE (`name` LIKE "%hello%" AND `email` = "a@b")
	fmt.Println(sql)
}

Web Example

package tests_test

import (
	"encoding/json"
	"net/http"

	"github.com/alingse/structquery"
	"github.com/gorilla/schema"
	"gorm.io/gorm"
)

// DB -------------------------------------------------------------------------
var GormDB *gorm.DB

type UserModel struct {
	gorm.Model
	Name  string `json:"name"`
	Email string `json:"email"`
}

func (u UserModel) TableName() string {
	return "users"
}

// HTTP -----------------------------------------------------------------------
var queryDecoder = schema.NewDecoder()

func init() {
	queryDecoder.IgnoreUnknownKeys(true)
	queryDecoder.SetAliasTag("json")
}

// Query ----------------------------------------------------------------------

type UserQuery struct {
	Name  string `json:"name"  sq:"like"`
	Email string `json:"email" sq:"eq"`
}

var structQueryer = structquery.NewQueryer()

func GetUsers(w http.ResponseWriter, r *http.Request) {
	var query UserQuery

	// decode from URL
	err := queryDecoder.Decode(&query, r.URL.Query())
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		return
	}

	db := GormDB.Model(&UserModel{})
	// bind queryer
	db, err = structQueryer.Where(db, query)
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		return
	}

	var users []UserModel
	db.Find(&users)

	w.WriteHeader(http.StatusOK)
	_ = json.NewEncoder(w).Encode(users)
}

TODO

  1. support and/or with slice?
  2. add structQueryer.Parse return with interface
  3. more db test

Documentation

Index

Constants

View Source
const (
	OptionColumn = `column`
	OptionTable  = `table`
)

Variables

View Source
var (
	ErrBadQueryValue = errors.New("structquery: query must be struct or a pointer to struct")
	ErrBadQueryType  = errors.New("structquery: query type not registered")
)

Functions

This section is empty.

Types

type Field

type Field struct {
	FieldMeta
	Value      interface{}
	ColumnName string // TODO: add read from options
}

func ParseStruct

func ParseStruct(value interface{}) ([]*Field, error)

type FieldMeta

type FieldMeta struct {
	QueryType QueryType
	Name      string
	Options   map[string]string
	// contains filtered or unexported fields
}

type QueryType

type QueryType string
const (
	Empty             QueryType = ""
	Eq                QueryType = "eq"
	Neq               QueryType = "neq"
	Like              QueryType = "like"
	LLike             QueryType = "llike"
	RLike             QueryType = "rlike"
	In                QueryType = "in"
	NotIn             QueryType = "not_in"
	Gt                QueryType = "gt"
	Gte               QueryType = "gte"
	Lt                QueryType = "lt"
	Lte               QueryType = "lte"
	JSONExtractEq     QueryType = "json_extract_eq"
	JSONExtractLike   QueryType = "json_extract_like"
	MySQLJSONContains QueryType = "my_json_contains"
	UnsafeRawSQL      QueryType = "unsaferaw" // dangerous
)

type Queryer

type Queryer struct {
	Namer schema.Namer
	// contains filtered or unexported fields
}

func NewQueryer

func NewQueryer() *Queryer

func (*Queryer) And

func (q *Queryer) And(value interface{}) (clause.Expression, error)

func (*Queryer) Or

func (q *Queryer) Or(value interface{}) (clause.Expression, error)

func (*Queryer) Register

func (q *Queryer) Register(t QueryType, fn QueryerFunc)

func (*Queryer) Where

func (q *Queryer) Where(db *gorm.DB, value interface{}) (*gorm.DB, error)

type QueryerFunc

type QueryerFunc func(f Field) clause.Expression

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL