search.go

Summary

Maintainability
A
1 hr
Test Coverage
package gorm

import (
    "fmt"
)

type search struct {
    db               *DB
    whereConditions  []map[string]interface{}
    orConditions     []map[string]interface{}
    notConditions    []map[string]interface{}
    havingConditions []map[string]interface{}
    joinConditions   []map[string]interface{}
    initAttrs        []interface{}
    assignAttrs      []interface{}
    selects          map[string]interface{}
    omits            []string
    orders           []interface{}
    preload          []searchPreload
    offset           interface{}
    limit            interface{}
    group            string
    tableName        string
    raw              bool
    Unscoped         bool
    ignoreOrderQuery bool
}

type searchPreload struct {
    schema     string
    conditions []interface{}
}

func (s *search) clone() *search {
    clone := search{
        db:               s.db,
        whereConditions:  make([]map[string]interface{}, len(s.whereConditions)),
        orConditions:     make([]map[string]interface{}, len(s.orConditions)),
        notConditions:    make([]map[string]interface{}, len(s.notConditions)),
        havingConditions: make([]map[string]interface{}, len(s.havingConditions)),
        joinConditions:   make([]map[string]interface{}, len(s.joinConditions)),
        initAttrs:        make([]interface{}, len(s.initAttrs)),
        assignAttrs:      make([]interface{}, len(s.assignAttrs)),
        selects:          s.selects,
        omits:            make([]string, len(s.omits)),
        orders:           make([]interface{}, len(s.orders)),
        preload:          make([]searchPreload, len(s.preload)),
        offset:           s.offset,
        limit:            s.limit,
        group:            s.group,
        tableName:        s.tableName,
        raw:              s.raw,
        Unscoped:         s.Unscoped,
        ignoreOrderQuery: s.ignoreOrderQuery,
    }
    for i, value := range s.whereConditions {
        clone.whereConditions[i] = value
    }
    for i, value := range s.orConditions {
        clone.orConditions[i] = value
    }
    for i, value := range s.notConditions {
        clone.notConditions[i] = value
    }
    for i, value := range s.havingConditions {
        clone.havingConditions[i] = value
    }
    for i, value := range s.joinConditions {
        clone.joinConditions[i] = value
    }
    for i, value := range s.initAttrs {
        clone.initAttrs[i] = value
    }
    for i, value := range s.assignAttrs {
        clone.assignAttrs[i] = value
    }
    for i, value := range s.omits {
        clone.omits[i] = value
    }
    for i, value := range s.orders {
        clone.orders[i] = value
    }
    for i, value := range s.preload {
        clone.preload[i] = value
    }
    return &clone
}

func (s *search) Where(query interface{}, values ...interface{}) *search {
    s.whereConditions = append(s.whereConditions, map[string]interface{}{"query": query, "args": values})
    return s
}

func (s *search) Not(query interface{}, values ...interface{}) *search {
    s.notConditions = append(s.notConditions, map[string]interface{}{"query": query, "args": values})
    return s
}

func (s *search) Or(query interface{}, values ...interface{}) *search {
    s.orConditions = append(s.orConditions, map[string]interface{}{"query": query, "args": values})
    return s
}

func (s *search) Attrs(attrs ...interface{}) *search {
    s.initAttrs = append(s.initAttrs, toSearchableMap(attrs...))
    return s
}

func (s *search) Assign(attrs ...interface{}) *search {
    s.assignAttrs = append(s.assignAttrs, toSearchableMap(attrs...))
    return s
}

func (s *search) Order(value interface{}, reorder ...bool) *search {
    if len(reorder) > 0 && reorder[0] {
        s.orders = []interface{}{}
    }

    if value != nil && value != "" {
        s.orders = append(s.orders, value)
    }
    return s
}

func (s *search) Select(query interface{}, args ...interface{}) *search {
    s.selects = map[string]interface{}{"query": query, "args": args}
    return s
}

func (s *search) Omit(columns ...string) *search {
    s.omits = columns
    return s
}

func (s *search) Limit(limit interface{}) *search {
    s.limit = limit
    return s
}

func (s *search) Offset(offset interface{}) *search {
    s.offset = offset
    return s
}

func (s *search) Group(query string) *search {
    s.group = s.getInterfaceAsSQL(query)
    return s
}

func (s *search) Having(query interface{}, values ...interface{}) *search {
    if val, ok := query.(*SqlExpr); ok {
        s.havingConditions = append(s.havingConditions, map[string]interface{}{"query": val.expr, "args": val.args})
    } else {
        s.havingConditions = append(s.havingConditions, map[string]interface{}{"query": query, "args": values})
    }
    return s
}

func (s *search) Joins(query string, values ...interface{}) *search {
    s.joinConditions = append(s.joinConditions, map[string]interface{}{"query": query, "args": values})
    return s
}

func (s *search) Preload(schema string, values ...interface{}) *search {
    var preloads []searchPreload
    for _, preload := range s.preload {
        if preload.schema != schema {
            preloads = append(preloads, preload)
        }
    }
    preloads = append(preloads, searchPreload{schema, values})
    s.preload = preloads
    return s
}

func (s *search) Raw(b bool) *search {
    s.raw = b
    return s
}

func (s *search) unscoped() *search {
    s.Unscoped = true
    return s
}

func (s *search) Table(name string) *search {
    s.tableName = name
    return s
}

func (s *search) getInterfaceAsSQL(value interface{}) (str string) {
    switch value.(type) {
    case string, int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
        str = fmt.Sprintf("%v", value)
    default:
        s.db.AddError(ErrInvalidSQL)
    }

    if str == "-1" {
        return ""
    }
    return
}