mirror of https://github.com/VinGarcia/ksql.git
Remove gorm dependency from Query() func
parent
13bd087cee
commit
1ea81bb8e0
79
kiss_orm.go
79
kiss_orm.go
|
@ -60,24 +60,57 @@ func (c Client) Query(
|
||||||
query string,
|
query string,
|
||||||
params ...interface{},
|
params ...interface{},
|
||||||
) error {
|
) error {
|
||||||
t := reflect.TypeOf(records)
|
slicePtr := reflect.ValueOf(records)
|
||||||
if t.Kind() != reflect.Ptr {
|
slicePtrType := slicePtr.Type()
|
||||||
|
if slicePtrType.Kind() != reflect.Ptr {
|
||||||
return fmt.Errorf("kissorm: expected to receive a pointer to slice of structs, but got: %T", records)
|
return fmt.Errorf("kissorm: expected to receive a pointer to slice of structs, but got: %T", records)
|
||||||
}
|
}
|
||||||
t = t.Elem()
|
sliceType := slicePtrType.Elem()
|
||||||
if t.Kind() != reflect.Slice {
|
slice := slicePtr.Elem()
|
||||||
return fmt.Errorf("kissorm: expected to receive a pointer to slice of structs, but got: %T", records)
|
structType, isSliceOfPtrs, err := decodeAsSliceOfStructs(sliceType)
|
||||||
}
|
if err != nil {
|
||||||
if t.Elem().Kind() != reflect.Struct {
|
return err
|
||||||
return fmt.Errorf("kissorm: expected to receive a pointer to slice of structs, but got: %T", records)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
it := c.db.Raw(query, params...)
|
if isSliceOfPtrs {
|
||||||
if it.Error != nil {
|
// Truncate the slice so there is no risk
|
||||||
return it.Error
|
// of overwritting records that were already saved
|
||||||
|
// on the slice:
|
||||||
|
slice = slice.Slice(0, 0)
|
||||||
}
|
}
|
||||||
it = it.Scan(records)
|
|
||||||
return it.Error
|
rows, err := c.db.DB().QueryContext(ctx, query, params...)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
for idx := 0; rows.Next(); idx++ {
|
||||||
|
// Allocate new slice elements
|
||||||
|
// only if they are not already allocated:
|
||||||
|
if slice.Len() <= idx {
|
||||||
|
var elemValue reflect.Value
|
||||||
|
elemValue = reflect.New(structType)
|
||||||
|
if !isSliceOfPtrs {
|
||||||
|
elemValue = elemValue.Elem()
|
||||||
|
}
|
||||||
|
slice = reflect.Append(slice, elemValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = scanRows(rows, slice.Index(idx).Addr().Interface())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if rows.Err() != nil {
|
||||||
|
return rows.Err()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the original slice passed by reference:
|
||||||
|
slicePtr.Elem().Set(slice)
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryOne queries one instance from the database,
|
// QueryOne queries one instance from the database,
|
||||||
|
@ -108,6 +141,9 @@ func (c Client) QueryOne(
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
if !rows.Next() {
|
if !rows.Next() {
|
||||||
|
if rows.Err() != nil {
|
||||||
|
return rows.Err()
|
||||||
|
}
|
||||||
return ErrRecordNotFound
|
return ErrRecordNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,12 +170,6 @@ func (c Client) QueryChunks(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
parser ChunkParser,
|
parser ChunkParser,
|
||||||
) error {
|
) error {
|
||||||
rows, err := c.db.DB().QueryContext(ctx, parser.Query, parser.Params...)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer rows.Close()
|
|
||||||
|
|
||||||
fnValue := reflect.ValueOf(parser.ForEachChunk)
|
fnValue := reflect.ValueOf(parser.ForEachChunk)
|
||||||
chunkType, err := parseInputFunc(parser.ForEachChunk)
|
chunkType, err := parseInputFunc(parser.ForEachChunk)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -153,6 +183,12 @@ func (c Client) QueryChunks(
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rows, err := c.db.DB().QueryContext(ctx, parser.Query, parser.Params...)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
var idx = 0
|
var idx = 0
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
// Allocate new slice elements
|
// Allocate new slice elements
|
||||||
|
@ -186,6 +222,11 @@ func (c Client) QueryChunks(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If Next() returned false because of an error:
|
||||||
|
if rows.Err() != nil {
|
||||||
|
return rows.Err()
|
||||||
|
}
|
||||||
|
|
||||||
// If no rows were found or idx was reset to 0
|
// If no rows were found or idx was reset to 0
|
||||||
// on the last iteration skip this last call to ForEachChunk:
|
// on the last iteration skip this last call to ForEachChunk:
|
||||||
if idx > 0 {
|
if idx > 0 {
|
||||||
|
|
|
@ -37,6 +37,11 @@ func TestQuery(t *testing.T) {
|
||||||
var users []User
|
var users []User
|
||||||
err := c.Query(ctx, &users, `SELECT * FROM users WHERE id=1;`)
|
err := c.Query(ctx, &users, `SELECT * FROM users WHERE id=1;`)
|
||||||
assert.Equal(t, nil, err)
|
assert.Equal(t, nil, err)
|
||||||
|
assert.Equal(t, []User(nil), users)
|
||||||
|
|
||||||
|
users = []User{}
|
||||||
|
err = c.Query(ctx, &users, `SELECT * FROM users WHERE id=1;`)
|
||||||
|
assert.Equal(t, nil, err)
|
||||||
assert.Equal(t, []User{}, users)
|
assert.Equal(t, []User{}, users)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue