Skip to content
Snippets Groups Projects
Select Git revision
  • master default protected
  • wip/memdb-dbal
  • wip-old
  • old-history
  • testing
  • v0.10.6
  • v0.10.5
  • v0.10.4
  • v0.10.3
  • v0.10.2
  • v0.10.1
  • v0.10.0
  • v0.9.16
  • v0.9.15
  • v0.9.14
  • v0.9.13
  • v0.9.12
  • v0.9.11
  • v0.9.10
  • v0.9.9
  • v0.9.8
  • v0.9.7
  • v0.9.6
  • v0.9.5
  • v0.9.4
25 results

query.go

query.go 2.48 KiB
package postgres

import (
	"reflect"

	"gitlab.com/xdevs23/goqlorm/database/dbdefs"

	"github.com/joomcode/errorx"
	"gitlab.com/xdevs23/goqlorm/reflectutil"
)

func (db Database) Select(collectionName string, args interface{}) (interface{}, error) {
	if err := db.SelectInto(collectionName, args, args); err != nil {
		return nil, err
	}
	return args, nil
}

func (db Database) SelectInto(collectionName string, args interface{}, model interface{}) error {
	if err := db.tableModelQuery(collectionName, model, true).WherePK().Select(args); err != nil {
		return errorx.EnsureStackTrace(err)
	}
	return nil
}

func (db Database) SelectAdvanced(collectionName string, model interface{}, query *dbdefs.SelectQuery) error {
	actualModel := model
	if query.IgnoreMultiple {
		// Create a new slice first
		actualModel = reflectutil.Wrap(reflectutil.NewSlice(model))
	}
	// This will give us a model that is made out of a modified struct
	q, modifiedModel := tableModelQueryReturnModified(db.PgDB, collectionName, actualModel)
	actualModel = modifiedModel
	switch {
	case query.Equals != nil:
		q.Where(ToPgString(query.Where)+" = ?", query.Equals)
	}
	if err := q.Select(); err != nil {
		return errorx.EnsureStackTrace(err)
	}

	modelVal := reflectutil.UnwrapValue(reflect.ValueOf(modifiedModel))
	origType := reflectutil.PurifyType(reflect.TypeOf(model))
	origNewSlice := reflectutil.NewSliceOfTypeWithSize(origType, modelVal.Len(), modelVal.Len())
	origNewSliceVal := reflect.ValueOf(origNewSlice)
	for i := 0; i < modelVal.Len(); i++ {
		newVal := modelVal.Index(i)
		// Create a new model that has the same type as the original one
		origNewModel := reflectutil.NewFromType(origType)
		// Now copy all the struct fields from the modified model to the original one
		copyModel(
			reflectutil.UnwrapType(newVal.Type()),
			reflectutil.UnwrapValue(newVal),
			origNewModel)
		// And apply that to the slice
		origNewSliceVal.Index(i).Set(reflect.ValueOf(origNewModel).Elem())
	}
	finalValue := origNewSliceVal
	modelKind := reflectutil.UnwrapType(reflect.TypeOf(model)).Kind()
	unwrappedValue := reflect.ValueOf(model).Elem()
	if modelKind != reflect.Slice {
		if query.IgnoreMultiple {
			finalValue = origNewSliceVal.Index(0)
		} else {
			return errorx.IllegalArgument.New("SelectAdvanced: model is not a slice but IgnoreMultiple is false")
		}
	} else if !unwrappedValue.CanAddr() {
		return errorx.IllegalArgument.New("Non-addressable value passed to SelectAdvanced, pass a ptr instead.")
	}
	unwrappedValue.Set(finalValue)

	return nil
}