qry

package module
v0.0.5 Latest Latest
Warning

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

Go to latest
Published: Jan 16, 2023 License: MIT Imports: 17 Imported by: 3

Documentation

Index

Constants

This section is empty.

Variables

View Source
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

func CreatePeggedAssocFields(db *gorm.DB, modelObj mdl.IModel) (err error)

CreatePeggedAssocFields :-

func DeleteModelFixManyToManyAndPegAndPegAssoc

func DeleteModelFixManyToManyAndPegAndPegAssoc(db *gorm.DB, modelObj mdl.IModel) error

func DesignatorContainsDot

func DesignatorContainsDot(rel *PredicateRelation) bool

func FindFieldNameToStructAndStructFieldNameIfAny

func FindFieldNameToStructAndStructFieldNameIfAny(rel *PredicateRelation) (*string, *string)

hacky...

func GetOuterTableName

func GetOuterTableName(modelObj mdl.IModel, fieldNameDesignator string) (string, error)

func NowFunc

func NowFunc() time.Time

func PrintFileAndLine

func PrintFileAndLine(err error)

func RemoveIDForNonPegOrPeggedFieldsBeforeCreate

func RemoveIDForNonPegOrPeggedFieldsBeforeCreate(db *gorm.DB, modelObj mdl.IModel) 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

func DB

func DB(db *gorm.DB) IQuery

Instead of Q() directly, we can use DB().Q() This is so it's easier to stubb out when testing

func Q

func Q(db *gorm.DB, args ...interface{}) IQuery

It would be Q(db, C(...), C(...)...).First() or Q(db).First() with empty PredicateRelationBuilder Use multiple C() when working on inner fields (one C() per struct field)

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

func NewLogger

func NewLogger(source string) *Logger

func (*Logger) Print

func (l *Logger) Print(values ...interface{})

Print format & print log

func (*Logger) Println

func (l *Logger) Println(values ...interface{})

Print format & print log

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 Order

type Order string
const (
	OrderAsc  Order = "ASC"
	OrderDesc Order = "DESC"
)

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

func NewPredicateFromStringAndVal(s string, value interface{}) (*Predicate, error)

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

func (p *Predicate) BuildQueryStringAndValues(modelObj mdl.IModel) (string, []interface{}, error)

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 (p *Predicate) GetAllUnqueStructFieldDesignator() map[string]interface{}

func (*Predicate) GetDesignatedField

func (p *Predicate) GetDesignatedField(modelObj mdl.IModel) string

func (*Predicate) GetDesignatedModel

func (p *Predicate) GetDesignatedModel(modelObj mdl.IModel) (mdl.IModel, error)

func (*Predicate) GetNestedLevel

func (p *Predicate) GetNestedLevel() int

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 (pr *PredicateRelation) GetDesignatedModel(modelObj mdl.IModel) (mdl.IModel, error)

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

func (q *Query) BuildQuery(modelObj mdl.IModel) (*gorm.DB, error)

This is a passover for building query, we're just building the where clause

func (*Query) Count

func (q *Query) Count(modelObj mdl.IModel, no *int) IQuery

func (*Query) Create

func (q *Query) Create(modelObj mdl.IModel) IQuery

func (*Query) CreateMany

func (q *Query) CreateMany(modelObjs []mdl.IModel) IQuery

func (*Query) Delete

func (q *Query) Delete(modelObj mdl.IModel) IQuery

Delete can be with criteria, or can just delete the mdl directly

func (*Query) DeleteMany

func (q *Query) DeleteMany(modelObjs []mdl.IModel) IQuery

func (*Query) Error

func (q *Query) Error() error

func (*Query) Find

func (q *Query) Find(modelObjs interface{}) IQuery

func (*Query) First

func (q *Query) First(modelObj mdl.IModel) IQuery

func (*Query) GetDB

func (q *Query) GetDB() *gorm.DB

func (*Query) InnerJoin

func (q *Query) InnerJoin(modelObj mdl.IModel, foreignObj mdl.IModel, args ...interface{}) IQuery

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.

func (*Query) Limit

func (q *Query) Limit(limit int) IQuery

func (*Query) Offset

func (q *Query) Offset(offset int) IQuery

func (*Query) Order

func (q *Query) Order(field string, order Order) IQuery

func (*Query) Q

func (q *Query) Q(args ...interface{}) IQuery

Q takes in PredicateRelationBuilder here.

func (*Query) Reset

func (q *Query) Reset() IQuery

func (*Query) Save

func (q *Query) Save(modelObj mdl.IModel) IQuery

func (*Query) Take

func (q *Query) Take(modelObj mdl.IModel) IQuery

func (*Query) Update

func (q *Query) Update(modelObj mdl.IModel, p *PredicateRelationBuilder) IQuery

Update only allow one level of builder

type QueryType

type QueryType int

-----------------------------

const (
	QueryTypeFirst QueryType = iota
	QueryTypeFind
)

type TableAndArgs

type TableAndArgs struct {
	TblName string // The table the predicate relation applies to, at this level (non-nested)
	Args    []interface{}
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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