123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- package orm
- import (
- "fmt"
- "reflect"
- "strings"
- "github.com/huandu/go-sqlbuilder"
- )
- var SqlFlavor = sqlbuilder.MySQL
- type SqlType uint8
- const (
- Select SqlType = iota << 1
- Update
- Insert
- Delete
- )
- type cmethod uint8
- type ctype uint8
- const (
- And ctype = iota
- Or
- Between
- NotBetween
- EqualThan
- NotEqualThan
- GreaterThan
- GreatenThanEqual
- LessThan
- LessThanEqual
- Like
- NotLike
- In
- NotIn
- Null
- NotNull
- )
- const (
- Limit cmethod = iota
- Where
- )
- type Cond struct {
- Method cmethod
- Type ctype
- vars []interface{}
- }
- func (c Cond) SetVar(v ...interface{}) Cond {
- c.vars = append(c.vars, v...)
- return c
- }
- type selectBuilder struct {
- *sqlbuilder.SelectBuilder
- }
- func getSelectBuilder(tbl *table) *selectBuilder {
- return &selectBuilder{
- sqlbuilder.NewSelectBuilder().From(tbl.getNameAs(true)),
- }
- }
- func (sb *selectBuilder) getXint64(v reflect.Value, unsigned bool) interface{} {
- switch v.Kind() {
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- if !unsigned {
- return int(v.Uint())
- }
- return v.Uint()
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- if unsigned {
- return uint64(v.Int())
- }
- return v.Int()
- }
- return 0
- }
- func (sb *selectBuilder) _extra(tbl *table, extra ...Cond) *selectBuilder {
- for _, cond := range extra {
- if len(cond.vars) == 0 {
- continue
- }
- for i, v := range cond.vars {
- switch v.(type) {
- case string:
- if s := strings.SplitAfterN(v.(string), ".", 2); len(s) > 1 {
- fmt.Println(s, s[0][0:len(s[0])-1])
- for _, rels := range tbl.getRelations() {
- for _, rel := range rels {
- if rel.f.getFieldName() == s[0][0:len(s[0])-1] {
- cond.vars[i] = sqlbuilder.Raw(rel.getAlias(true) + "." + SqlFlavor.Quote(s[1]))
- }
- }
- }
- cond.vars[i] = v
- }
- }
- }
- switch cond.Method {
- case Limit:
- if len(cond.vars) > 0 {
- switch cond.vars[0].(type) {
- case int, uint:
- sb.Limit(cond.vars[0].(int))
- }
- }
- case Where:
- switch cond.Type {
- case Null:
- sb.Where(sb.IsNull(cond.vars[0].(string)))
- case NotNull:
- sb.Where(sb.IsNotNull(cond.vars[0].(string)))
- }
- }
- }
- //fmt.Println(sb)
- return sb
- }
- func (sb *selectBuilder) _select(tbls ...interface{}) *selectBuilder {
- cols := []string{}
- for _, tbl := range tbls {
- switch tbl.(type) {
- case relation:
- rtbl := tbl.(relation)
- for _, col := range rtbl.table.getColumns() {
- cols = append(cols, col.getName(true, rtbl))
- }
- case *table:
- rtbl := tbl.(*table)
- for _, col := range rtbl.getColumns() {
- cols = append(cols, col.getName(true, rtbl))
- }
- }
- }
- sb.Select(cols...)
- return sb
- }
- func (sb *selectBuilder) _where(tbl *table, i MappableInterface) *selectBuilder {
- tmp := tbl.Make()
- where := []string{}
- outerloop:
- for _, col := range tbl.getColumns() {
- fn := "Get" + strings.Title(col.getFieldName())
- val, err := tbl.CallMethod(i, fn)
- if err == nil {
- tmpv, _ := tbl.CallMethod(tmp, fn)
- for i, v := range val {
- if v == tmpv[i] {
- continue outerloop
- }
- }
- fmt.Println(fn, val)
- where = append(where, sb.Equal(col.getName(true, tbl), val[0]))
- } else {
- fmt.Println(err)
- }
- }
- sb.Where(where...)
- return sb
- }
- func (sb *selectBuilder) _wherePrimaryOrElse(tbl *table, i MappableInterface) *selectBuilder {
- if pk := tbl.getPrimaryKey(); pk != nil {
- val, err := tbl.CallMethod(i, "Get"+strings.Title(pk.getFieldName()))
- if err != nil {
- sb._where(tbl, i)
- } else {
- sb.Where(sb.Equal(pk.getName(true, tbl), val[0]))
- }
- } else {
- sb._where(tbl, i)
- }
- return sb
- }
- func (sb *selectBuilder) _join(tbl *table, rel relation, opt ...sqlbuilder.JoinOption) *selectBuilder {
- if len(opt) == 0 {
- sb.Join(rel.getNameAs(true), sb.Equal(rel.on.getName(true, rel), sqlbuilder.Raw(rel.key.getName(true, tbl))))
- } else {
- sb.JoinWithOption(opt[0], rel.getNameAs(true), sb.Equal(rel.on.getName(true, rel), sqlbuilder.Raw(rel.key.getName(true, tbl))))
- }
- return sb
- }
|