Documentation ¶
Index ¶
- Variables
- func CreatePeggedAssocFields(db *gorm.DB, modelObj mdl.IModel) (err error)
- func DeleteModelFixManyToManyAndPegAndPegAssoc(db *gorm.DB, modelObj mdl.IModel) error
- func DesignatorContainsDot(rel *PredicateRelation) bool
- func FindFieldNameToStructAndStructFieldNameIfAny(rel *PredicateRelation) (*string, *string)
- func GetOuterTableName(modelObj mdl.IModel, fieldNameDesignator string) (string, error)
- func NowFunc() time.Time
- func PrintFileAndLine(err error)
- func RemoveIDForNonPegOrPeggedFieldsBeforeCreate(db *gorm.DB, modelObj mdl.IModel) error
- type BatchCreateData
- type BuilderInfo
- type Criteria
- type Escape
- type IQuery
- type LogWriter
- type Logger
- type ModelAndBuilder
- type Order
- type Predicate
- func (p *Predicate) BuildQueryStringAndValues(modelObj mdl.IModel) (string, []interface{}, error)
- func (p *Predicate) GetAllUnqueStructFieldDesignator() map[string]interface{}
- func (p *Predicate) GetDesignatedField(modelObj mdl.IModel) string
- func (p *Predicate) GetDesignatedModel(modelObj mdl.IModel) (mdl.IModel, error)
- func (p *Predicate) GetNestedLevel() int
- type PredicateCond
- type PredicateLogic
- type PredicateRelation
- func (pr *PredicateRelation) BuildQueryStringAndValues(modelObj mdl.IModel) (string, []interface{}, error)
- func (pr *PredicateRelation) GetAllUnqueStructFieldDesignator() map[string]interface{}
- func (pr *PredicateRelation) GetDesignatedField(modelObj mdl.IModel) string
- func (pr *PredicateRelation) GetDesignatedModel(modelObj mdl.IModel) (mdl.IModel, error)
- func (pr *PredicateRelation) GetNestedLevel() int
- type PredicateRelationBuilder
- func (p *PredicateRelationBuilder) And(args ...interface{}) *PredicateRelationBuilder
- func (p *PredicateRelationBuilder) C(args ...interface{}) *PredicateRelationBuilder
- func (p *PredicateRelationBuilder) GetPredicateRelation() (*PredicateRelation, error)
- func (p *PredicateRelationBuilder) Or(args ...interface{}) *PredicateRelationBuilder
- type Query
- func (q *Query) BuildQuery(modelObj mdl.IModel) (*gorm.DB, error)
- func (q *Query) Count(modelObj mdl.IModel, no *int) IQuery
- func (q *Query) Create(modelObj mdl.IModel) IQuery
- func (q *Query) CreateMany(modelObjs []mdl.IModel) IQuery
- func (q *Query) Delete(modelObj mdl.IModel) IQuery
- func (q *Query) DeleteMany(modelObjs []mdl.IModel) IQuery
- func (q *Query) Error() error
- func (q *Query) Find(modelObjs interface{}) IQuery
- func (q *Query) First(modelObj mdl.IModel) IQuery
- func (q *Query) GetDB() *gorm.DB
- func (q *Query) InnerJoin(modelObj mdl.IModel, foreignObj mdl.IModel, args ...interface{}) IQuery
- func (q *Query) Limit(limit int) IQuery
- func (q *Query) Offset(offset int) IQuery
- func (q *Query) Order(field string, order Order) IQuery
- func (q *Query) Q(args ...interface{}) IQuery
- func (q *Query) Reset() IQuery
- func (q *Query) Save(modelObj mdl.IModel) IQuery
- func (q *Query) Take(modelObj mdl.IModel) IQuery
- func (q *Query) Update(modelObj mdl.IModel, p *PredicateRelationBuilder) IQuery
- type QueryType
- type TableAndArgs
Constants ¶
This section is empty.
Variables ¶
var LogFormatter = func(values ...interface{}) (messages []interface{}) { if len(values) > 1 { var ( sql string formattedValues []string level = values[0] currentTime = "\n\033[33m[" + NowFunc().Format("2006-01-02 15:04:05") + "]\033[0m" source = fmt.Sprintf("\033[35m(%v)\033[0m", values[1]) ) messages = []interface{}{source, currentTime} if len(values) == 2 { currentTime = currentTime[1:] source = fmt.Sprintf("\033[35m%v\033[0m", values[1]) messages = []interface{}{currentTime, source} } if level == "sql" { messages = append(messages, fmt.Sprintf(" \033[36;1m[%.2fms]\033[0m ", float64(values[2].(time.Duration).Nanoseconds()/1e4)/100.0)) for _, value := range values[4].([]interface{}) { indirectValue := reflect.Indirect(reflect.ValueOf(value)) if indirectValue.IsValid() { value = indirectValue.Interface() if t, ok := value.(time.Time); ok { if t.IsZero() { formattedValues = append(formattedValues, fmt.Sprintf("'%v'", "0000-00-00 00:00:00")) } else { formattedValues = append(formattedValues, fmt.Sprintf("'%v'", t.Format("2006-01-02 15:04:05"))) } } else if b, ok := value.([]byte); ok { if str := string(b); isPrintable(str) { formattedValues = append(formattedValues, fmt.Sprintf("'%v'", str)) } else { formattedValues = append(formattedValues, "'<binary>'") } } else if r, ok := value.(driver.Valuer); ok { if value, err := r.Value(); err == nil && value != nil { formattedValues = append(formattedValues, fmt.Sprintf("'%v'", value)) } else { formattedValues = append(formattedValues, "NULL") } } else { switch value.(type) { case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64, bool: formattedValues = append(formattedValues, fmt.Sprintf("%v", value)) default: formattedValues = append(formattedValues, fmt.Sprintf("'%v'", value)) } } } else { formattedValues = append(formattedValues, "NULL") } } if numericPlaceHolderRegexp.MatchString(values[3].(string)) { sql = values[3].(string) for index, value := range formattedValues { placeholder := fmt.Sprintf(`\$%d([^\d]|$)`, index+1) sql = regexp.MustCompile(placeholder).ReplaceAllString(sql, value+"$1") } } else { formattedValuesLength := len(formattedValues) for index, value := range sqlRegexp.Split(values[3].(string), -1) { sql += value if index < formattedValuesLength { sql += formattedValues[index] } } } messages = append(messages, sql) messages = append(messages, fmt.Sprintf(" \n\033[36;31m[%v]\033[0m ", strconv.FormatInt(values[5].(int64), 10)+" rows affected or returned ")) } else { messages = append(messages, "\033[31;1m") messages = append(messages, values[2:]...) messages = append(messages, "\033[0m") } } return }
Functions ¶
func CreatePeggedAssocFields ¶
CreatePeggedAssocFields :-
func DesignatorContainsDot ¶
func DesignatorContainsDot(rel *PredicateRelation) bool
func FindFieldNameToStructAndStructFieldNameIfAny ¶
func FindFieldNameToStructAndStructFieldNameIfAny(rel *PredicateRelation) (*string, *string)
hacky...
func GetOuterTableName ¶
func PrintFileAndLine ¶
func PrintFileAndLine(err error)
Types ¶
type BatchCreateData ¶
type BatchCreateData struct {
// contains filtered or unexported fields
}
type BuilderInfo ¶
type BuilderInfo struct {
// contains filtered or unexported fields
}
type Criteria ¶
type Criteria interface { BuildQueryStringAndValues(modelObj mdl.IModel) (string, []interface{}, error) // GetDesignatedModel gets the inner mdl within this modelObj designated by the criteria // If it's on the first-level, modelObj itself is returned GetDesignatedModel(modelObj mdl.IModel) (mdl.IModel, error) // GetDesignatedField gets the name of the current Field designator for the inner mdl // or empty string if it is modelObj itself GetDesignatedField(modelObj mdl.IModel) string // GetAllUnqueStructFieldDesignator returns the struct fields designators (used for buliding joins within // nested table). For example, A.B.C returns A.B. and A. // Returns map because what we really want is a unique set. The value of the map is not important. GetAllUnqueStructFieldDesignator() map[string]interface{} // GetNestedLevel is the level the criteria designates // The top-most level is 1 GetNestedLevel() int }
type Escape ¶
type Escape struct {
Value string
}
If a predicte value is wrapped within an Escape class Assume it has a Stringer interface, and the result of the string is not wrapped in quotes as Postgres values, and also SQL injection is not checked So this should only be used internally
type IQuery ¶
type IQuery interface { Q(args ...interface{}) IQuery Order(field string, order Order) IQuery Limit(limit int) IQuery Offset(offset int) IQuery InnerJoin(modelObj mdl.IModel, foreignObj mdl.IModel, args ...interface{}) IQuery BuildQuery(modelObj mdl.IModel) (*gorm.DB, error) Take(modelObj mdl.IModel) IQuery First(modelObj mdl.IModel) IQuery Find(modelObjs interface{}) IQuery Count(modelObj mdl.IModel, no *int) IQuery Create(modelObj mdl.IModel) IQuery CreateMany(modelObjs []mdl.IModel) IQuery Delete(modelObj mdl.IModel) IQuery DeleteMany(modelObjs []mdl.IModel) IQuery Save(modelObj mdl.IModel) IQuery // Update(modelObjs interface{}, attrs ...interface{}) IQuery Update(modelObj mdl.IModel, p *PredicateRelationBuilder) IQuery GetDB() *gorm.DB Reset() IQuery Error() error }
IQuery so we can stubb out the DB
type LogWriter ¶
type LogWriter interface {
Println(v ...interface{})
}
LogWriter log writer interface
type Logger ¶
type Logger struct { LogWriter // contains filtered or unexported fields }
Logger default logger
type ModelAndBuilder ¶
type ModelAndBuilder struct {
// contains filtered or unexported fields
}
func (*ModelAndBuilder) GetAllPotentialJoinStructDesignators ¶
func (mb *ModelAndBuilder) GetAllPotentialJoinStructDesignators() ([]string, error)
func (*ModelAndBuilder) SortBuilderInfosByLevel ¶
func (mb *ModelAndBuilder) SortBuilderInfosByLevel()
top level table has to be joined before more-nested table are joined
type Predicate ¶
type Predicate struct { Field string // e.g. Age Cond PredicateCond // e.g. <, or IN Value interface{} // e.g. 20 or an array of values }
Predicate is used to represent something like Age < 20
func NewPredicateFromStringAndVal ¶
NewPredicateFromStringAndVal, turn string like "age <" and value into proper predicate This is for convenience I cannot get "age < 20" directly because I'd have to know in advance the type of object (unless of course I just send it as a string, wonder if SQL can take it)
func (*Predicate) BuildQueryStringAndValues ¶
BuildQuryStringAndValues output proper query conditionals and the correponding values which field those fields Because this then is given to the database, the output needs to match the column names
func (*Predicate) GetAllUnqueStructFieldDesignator ¶
func (*Predicate) GetDesignatedField ¶
func (*Predicate) GetDesignatedModel ¶
func (*Predicate) GetNestedLevel ¶
type PredicateCond ¶
type PredicateCond string
const ( // PredicateCondEQ is equals PredicateCondEQ PredicateCond = "=" // PredicateCondLT is less than PredicateCondLT PredicateCond = "<" // PredicateCondLTEQ is less than or equal to PredicateCondLTEQ PredicateCond = "<=" // PredicateCondGT is equal to PredicateCondGT PredicateCond = ">" // PredicateCondGTEQ is greater than or equal to PredicateCondGTEQ PredicateCond = ">=" // PredicateCondGTEQ is greater than or equal to PredicateCondIN PredicateCond = "IN" // PredicateCondBETWEEN is between two values PredicateCondBETWEEN PredicateCond = "BETWEEN" )
func StringToPredicateCond ¶
func StringToPredicateCond(s string) (PredicateCond, error)
type PredicateLogic ¶
type PredicateLogic string
const ( PredicateLogicAND PredicateLogic = "AND" PredicateLogicOR PredicateLogic = "OR" )
type PredicateRelation ¶
type PredicateRelation struct { // PredOrRel contains either be a *Predicate or *PredicateRelation // If PredicateRelation than it is nested comparison PredOrRels []Criteria Logics []PredicateLogic // AND or OR. The number of Logic operators is one less than the number of predicates }
PredicateRelation represents things like (age < 20 OR age > 70 OR age = 30) A Criteria is a Predicate or Predicate relation Every nested PredicateRelation is meant to work on one mdl.IModel. It can also designate criteria for nested class. But it cannot be used for another unrelated Model where there is no nesting relationships.
func NewPredicateRelation ¶
func NewPredicateRelation() *PredicateRelation
func (*PredicateRelation) BuildQueryStringAndValues ¶
func (pr *PredicateRelation) BuildQueryStringAndValues(modelObj mdl.IModel) (string, []interface{}, error)
func (*PredicateRelation) GetAllUnqueStructFieldDesignator ¶
func (pr *PredicateRelation) GetAllUnqueStructFieldDesignator() map[string]interface{}
GetAllUnqueStructFieldDesignator returns all unique designators which are struct field Example: Dogs.DogToy.Name, Dogs.DogToy.Color, Name, furniture.Type will return Dogs.DogToy, Furniture This function is needed to figure out the join statement we need to issue
func (*PredicateRelation) GetDesignatedField ¶
func (pr *PredicateRelation) GetDesignatedField(modelObj mdl.IModel) string
func (*PredicateRelation) GetDesignatedModel ¶
func (*PredicateRelation) GetNestedLevel ¶
func (pr *PredicateRelation) GetNestedLevel() int
type PredicateRelationBuilder ¶
type PredicateRelationBuilder struct { Rel *PredicateRelation Error error // This allow us to chain and eventually discover any error by querying for Error }
func C ¶
func C(args ...interface{}) *PredicateRelationBuilder
args is either two arguments: "Name =" "Christy", or another predicate builder C()
func NewPredicateRelationBuilder ¶
func NewPredicateRelationBuilder() *PredicateRelationBuilder
func (*PredicateRelationBuilder) And ¶
func (p *PredicateRelationBuilder) And(args ...interface{}) *PredicateRelationBuilder
s is Name =?, v is value
func (*PredicateRelationBuilder) C ¶
func (p *PredicateRelationBuilder) C(args ...interface{}) *PredicateRelationBuilder
func (*PredicateRelationBuilder) GetPredicateRelation ¶
func (p *PredicateRelationBuilder) GetPredicateRelation() (*PredicateRelation, error)
func (*PredicateRelationBuilder) Or ¶
func (p *PredicateRelationBuilder) Or(args ...interface{}) *PredicateRelationBuilder
s is Name =?, v is value
type Query ¶
type Query struct { // args []interface{} Err error // contains filtered or unexported fields }
Q is the query struct Q(db).By("Name IN", []strings{name1, name2}, "Age >=", 18).Find(&mdl).Error This is a wrapper over Gorm's. Query by field name, and prevent SQL injection by making sure that fields are part of the mdl
func (*Query) BuildQuery ¶
This is a passover for building query, we're just building the where clause
func (*Query) InnerJoin ¶
args can be multiple C(), each C() works on one-level of modelObj The args are to select the query of modelObj designated, it could work on nested level inside the modelObj assuming first is top-level, if given.
type TableAndArgs ¶
type TableAndArgs struct { TblName string // The table the predicate relation applies to, at this level (non-nested) Args []interface{} }