Select(Value|Row) require exactly one found row
This commit is contained in:
+11
-9
@@ -29,11 +29,13 @@ type Connection struct {
|
|||||||
txStatus byte
|
txStatus byte
|
||||||
}
|
}
|
||||||
|
|
||||||
type NoRowsFoundError struct {
|
type NotSingleRowError struct {
|
||||||
msg string
|
RowCount int64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e NoRowsFoundError) Error() string { return e.msg }
|
func (e NotSingleRowError) Error() string {
|
||||||
|
return fmt.Sprintf("Expected to find 1 row exactly, instead found %d", e.RowCount)
|
||||||
|
}
|
||||||
|
|
||||||
func Connect(parameters ConnectionParameters) (c *Connection, err error) {
|
func Connect(parameters ConnectionParameters) (c *Connection, err error) {
|
||||||
c = new(Connection)
|
c = new(Connection)
|
||||||
@@ -147,6 +149,7 @@ func (c *Connection) SelectRows(sql string) (rows []map[string]interface{}, err
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns a NotSingleRowError if exactly one row is not found
|
||||||
func (c *Connection) SelectRow(sql string) (row map[string]interface{}, err error) {
|
func (c *Connection) SelectRow(sql string) (row map[string]interface{}, err error) {
|
||||||
var numRowsFound int64
|
var numRowsFound int64
|
||||||
|
|
||||||
@@ -156,14 +159,13 @@ func (c *Connection) SelectRow(sql string) (row map[string]interface{}, err erro
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
err = c.SelectFunc(sql, onDataRow)
|
err = c.SelectFunc(sql, onDataRow)
|
||||||
if err == nil {
|
if err == nil && numRowsFound != 1 {
|
||||||
if numRowsFound == 0 {
|
err = NotSingleRowError{RowCount: numRowsFound}
|
||||||
err = NoRowsFoundError{}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns a NotSingleRowError if exactly one row is not found
|
||||||
func (c *Connection) SelectValue(sql string) (v interface{}, err error) {
|
func (c *Connection) SelectValue(sql string) (v interface{}, err error) {
|
||||||
var numRowsFound int64
|
var numRowsFound int64
|
||||||
|
|
||||||
@@ -174,8 +176,8 @@ func (c *Connection) SelectValue(sql string) (v interface{}, err error) {
|
|||||||
}
|
}
|
||||||
err = c.SelectFunc(sql, onDataRow)
|
err = c.SelectFunc(sql, onDataRow)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if numRowsFound == 0 {
|
if numRowsFound != 1 {
|
||||||
err = NoRowsFoundError{}
|
err = NotSingleRowError{RowCount: numRowsFound}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
|||||||
+13
-3
@@ -194,8 +194,13 @@ func TestSelectRow(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_, err = conn.SelectRow("select 'Jack' as name where 1=2")
|
_, err = conn.SelectRow("select 'Jack' as name where 1=2")
|
||||||
if _, ok := err.(NoRowsFoundError); !ok {
|
if _, ok := err.(NotSingleRowError); !ok {
|
||||||
t.Error("No matching row should have returned NoRowsFoundError")
|
t.Error("No matching row should have returned NotSingleRowError")
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = conn.SelectRow("select * from (values ('Matthew'), ('Mark')) t")
|
||||||
|
if _, ok := err.(NotSingleRowError); !ok {
|
||||||
|
t.Error("Multiple matching rows should have returned NotSingleRowError")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,9 +228,14 @@ func TestConnectionSelectValue(t *testing.T) {
|
|||||||
test("select 1.23::float8", float64(1.23))
|
test("select 1.23::float8", float64(1.23))
|
||||||
|
|
||||||
_, err := conn.SelectValue("select 'Jack' as name where 1=2")
|
_, err := conn.SelectValue("select 'Jack' as name where 1=2")
|
||||||
if _, ok := err.(NoRowsFoundError); !ok {
|
if _, ok := err.(NotSingleRowError); !ok {
|
||||||
t.Error("No matching row should have returned NoRowsFoundError")
|
t.Error("No matching row should have returned NoRowsFoundError")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_, err = conn.SelectValue("select * from (values ('Matthew'), ('Mark')) t")
|
||||||
|
if _, ok := err.(NotSingleRowError); !ok {
|
||||||
|
t.Error("Multiple matching rows should have returned NotSingleRowError")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSelectValues(t *testing.T) {
|
func TestSelectValues(t *testing.T) {
|
||||||
|
|||||||
Reference in New Issue
Block a user