Add force index query mod for select query.

Fix eager loading casting for nested levels.
This commit is contained in:
Mark Beamer Jr 2019-06-29 11:30:23 -04:00
parent f892107dad
commit 4e1b83ab39
No known key found for this signature in database
GPG key ID: 1C314FB89AD76973
4 changed files with 32 additions and 3 deletions

View file

@ -206,9 +206,16 @@ func (l loadRelationshipState) loadRelationshipsRecurse(depth int, obj reflect.V
}
bkind := kindStruct
if reflect.Indirect(loadedObject).Kind() != reflect.Struct {
if derefed := reflect.Indirect(loadedObject); derefed.Kind() != reflect.Struct {
bkind = kindPtrSliceStruct
loadedObject = loadedObject.Addr()
// Convert away any helper slice types
// elemType is *elem (from []*elem or helperSliceType)
// sliceType is *[]*elem
elemType := derefed.Type().Elem()
sliceType := reflect.PtrTo(reflect.SliceOf(elemType))
loadedObject = loadedObject.Addr().Convert(sliceType)
}
return l.loadRelationships(depth+1, loadedObject.Interface(), bkind)
}
@ -241,6 +248,9 @@ func collectLoaded(key string, loadingFrom reflect.Value) (reflect.Value, bindKi
if loadedType.Elem().Kind() == reflect.Struct {
bkind = kindStruct
loadedType = reflect.SliceOf(loadedType)
} else {
// Ensure that we get rid of all the helper "XSlice" types
loadedType = reflect.SliceOf(loadedType.Elem())
}
collection := reflect.MakeSlice(loadedType, 0, 0)

View file

@ -123,6 +123,13 @@ func From(from string) QueryMod {
}
}
func ForceIndex( index string) QueryMod {
return func(q *queries.Query) {
queries.SetForceIndex(q, index)
}
}
// Limit the number of returned rows
func Limit(limit int) QueryMod {
return func(q *queries.Query) {

View file

@ -30,6 +30,7 @@ type Query struct {
selectCols []string
count bool
from []string
forceindex string
joins []join
where []where
in []in
@ -263,6 +264,11 @@ func SetLastWhereAsOr(q *Query) {
q.where[len(q.where)-1].orSeparator = true
}
// SetForceIndex sets the index to be used by the query
func SetForceIndex(q *Query, index string){
q.forceindex = index
}
// SetLastInAsOr sets the or separator for the tail "IN" in the slice
func SetLastInAsOr(q *Query) {
if len(q.in) == 0 {

View file

@ -76,8 +76,14 @@ func buildSelectQuery(q *Query) (*bytes.Buffer, []interface{}) {
buf.WriteByte(')')
}
if len(q.forceindex) > 0 {
fmt.Fprintf(buf, " FROM %s FORCE INDEX (%s)", strings.Join(strmangle.IdentQuoteSlice(q.dialect.LQ, q.dialect.RQ, q.from), ", "),q.forceindex)
}else{
fmt.Fprintf(buf, " FROM %s", strings.Join(strmangle.IdentQuoteSlice(q.dialect.LQ, q.dialect.RQ, q.from), ", "))
}
if len(q.joins) > 0 {
argsLen := len(args)
joinBuf := strmangle.GetBuffer()