Merge pull request #18 from scylladb/mmt/select_err_not_found
iterx: ErrNotFound for Get only
This commit is contained in:
@@ -319,8 +319,8 @@ func TestNotFound(t *testing.T) {
|
|||||||
t.Run("select", func(t *testing.T) {
|
t.Run("select", func(t *testing.T) {
|
||||||
var v []NotFoundTable
|
var v []NotFoundTable
|
||||||
i := gocqlx.Iter(session.Query(`SELECT * FROM not_found_table`))
|
i := gocqlx.Iter(session.Query(`SELECT * FROM not_found_table`))
|
||||||
if err := i.Select(&v); err != gocql.ErrNotFound {
|
if err := i.Select(&v); err != nil {
|
||||||
t.Fatal("expected ErrNotFound", "got", err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if cap(v) > 0 {
|
if cap(v) > 0 {
|
||||||
t.Fatal("side effect alloc")
|
t.Fatal("side effect alloc")
|
||||||
|
|||||||
40
iterx.go
40
iterx.go
@@ -13,12 +13,12 @@ import (
|
|||||||
"github.com/jmoiron/sqlx/reflectx"
|
"github.com/jmoiron/sqlx/reflectx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Get is a convenience function for creating iterator and calling Get on it.
|
// Get is a convenience function for creating iterator and calling Get.
|
||||||
func Get(dest interface{}, q *gocql.Query) error {
|
func Get(dest interface{}, q *gocql.Query) error {
|
||||||
return Iter(q).Get(dest)
|
return Iter(q).Get(dest)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Select is a convenience function for creating iterator and calling Select on it.
|
// Select is a convenience function for creating iterator and calling Select.
|
||||||
func Select(dest interface{}, q *gocql.Query) error {
|
func Select(dest interface{}, q *gocql.Query) error {
|
||||||
return Iter(q).Select(dest)
|
return Iter(q).Select(dest)
|
||||||
}
|
}
|
||||||
@@ -67,7 +67,7 @@ func (iter *Iterx) Get(dest interface{}) error {
|
|||||||
iter.Close()
|
iter.Close()
|
||||||
iter.ReleaseQuery()
|
iter.ReleaseQuery()
|
||||||
|
|
||||||
return iter.err
|
return iter.checkErrAndNotFound()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (iter *Iterx) scanAny(dest interface{}, structOnly bool) bool {
|
func (iter *Iterx) scanAny(dest interface{}, structOnly bool) bool {
|
||||||
@@ -80,8 +80,9 @@ func (iter *Iterx) scanAny(dest interface{}, structOnly bool) bool {
|
|||||||
iter.err = errors.New("nil pointer passed to StructScan destination")
|
iter.err = errors.New("nil pointer passed to StructScan destination")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// no results or query error
|
||||||
if iter.Iter.NumRows() == 0 {
|
if iter.Iter.NumRows() == 0 {
|
||||||
// no results or query error
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,8 +135,9 @@ func (iter *Iterx) scanAll(dest interface{}, structOnly bool) bool {
|
|||||||
iter.err = errors.New("nil pointer passed to StructScan destination")
|
iter.err = errors.New("nil pointer passed to StructScan destination")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// no results or query error
|
||||||
if iter.Iter.NumRows() == 0 {
|
if iter.Iter.NumRows() == 0 {
|
||||||
// no results or query error
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,12 +203,12 @@ func (iter *Iterx) scanAll(dest interface{}, structOnly bool) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// StructScan is like gocql.Scan, but scans a single row into a single Struct.
|
// StructScan is like gocql.Iter.Scan, but scans a single row into a single
|
||||||
// Use this and iterate manually when the memory load of Select() might be
|
// Struct. Use this and iterate manually when the memory load of Select() might
|
||||||
// prohibitive. StructScan caches the reflect work of matching up column
|
// be prohibitive. StructScan caches the reflect work of matching up column
|
||||||
// positions to fields to avoid that overhead per scan, which means it is not
|
// positions to fields to avoid that overhead per scan, which means it is not
|
||||||
// safe to run StructScan on the same Iterx instance with different struct
|
// safe to run StructScan on the same Iterx instance with different struct
|
||||||
// types. If no rows were selected, ErrNotFound is returned.
|
// types.
|
||||||
func (iter *Iterx) StructScan(dest interface{}) bool {
|
func (iter *Iterx) StructScan(dest interface{}) bool {
|
||||||
if iter.query == nil {
|
if iter.query == nil {
|
||||||
iter.err = errors.New("using released query")
|
iter.err = errors.New("using released query")
|
||||||
@@ -219,8 +221,8 @@ func (iter *Iterx) StructScan(dest interface{}) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// no results or query error
|
||||||
if iter.Iter.NumRows() == 0 {
|
if iter.Iter.NumRows() == 0 {
|
||||||
// no results or query error
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,15 +263,9 @@ func columnNames(ci []gocql.ColumnInfo) []string {
|
|||||||
// the query or the iteration.
|
// the query or the iteration.
|
||||||
func (iter *Iterx) Close() error {
|
func (iter *Iterx) Close() error {
|
||||||
err := iter.Iter.Close()
|
err := iter.Iter.Close()
|
||||||
|
|
||||||
if iter.err == nil {
|
if iter.err == nil {
|
||||||
if err != nil {
|
iter.err = err
|
||||||
iter.err = err
|
|
||||||
} else if iter.Iter.NumRows() == 0 {
|
|
||||||
iter.err = gocql.ErrNotFound
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return iter.err
|
return iter.err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,3 +277,13 @@ func (iter *Iterx) ReleaseQuery() {
|
|||||||
iter.query = nil
|
iter.query = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// checkErrAndNotFound handle error and NotFound in one method.
|
||||||
|
func (iter *Iterx) checkErrAndNotFound() error {
|
||||||
|
if iter.err != nil {
|
||||||
|
return iter.err
|
||||||
|
} else if iter.Iter.NumRows() == 0 {
|
||||||
|
return gocql.ErrNotFound
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user