mirror of https://github.com/perkeep/perkeep.git
camli/db: typecheck & convert pre-bound statement parameters
Change-Id: Ic9b6dfa7b1fef0c6046c2e0454e996e2d5a8dfa6
This commit is contained in:
parent
7095174178
commit
7f2f506132
|
@ -45,6 +45,19 @@ func TestQuery(t *testing.T) {
|
|||
|
||||
}
|
||||
|
||||
// just a test of fakedb itself
|
||||
func TestBogusPreboundParameters(t *testing.T) {
|
||||
db := newTestDB(t, "foo")
|
||||
exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
|
||||
_, err := db.Prepare("INSERT|t1|name=?,age=bogusconversion")
|
||||
if err == nil {
|
||||
t.Fatalf("expected error")
|
||||
}
|
||||
if err.String() != `fakedb: invalid conversion to int32 from "bogusconversion"` {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDb(t *testing.T) {
|
||||
db := newTestDB(t, "foo")
|
||||
exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
|
@ -94,7 +95,7 @@ type fakeStmt struct {
|
|||
|
||||
colName []string // used by CREATE, INSERT
|
||||
colType []string // used by CREATE
|
||||
colValue []string // used by INSERT (mix of strings and "?" for bound params)
|
||||
colValue []interface{} // used by INSERT (mix of strings and "?" for bound params)
|
||||
placeholders int // number of ? params
|
||||
|
||||
placeholderConverter []dbimpl.ValueConverter // used by INSERT
|
||||
|
@ -240,16 +241,27 @@ func (c *fakeConn) Prepare(query string) (dbimpl.Stmt, os.Error) {
|
|||
if !ok {
|
||||
return nil, errf("INSERT table %q references non-existent column %q", stmt.table, column)
|
||||
}
|
||||
var subsetVal interface{}
|
||||
if value != "?" {
|
||||
// TODO(bradfitz): check that
|
||||
// pre-bound value type conversion is
|
||||
// valid for this column type
|
||||
// Convert to dbimpl subset type
|
||||
switch ctype {
|
||||
case "string":
|
||||
subsetVal = []byte(value)
|
||||
case "int32":
|
||||
i, err := strconv.Atoi(value)
|
||||
if err != nil {
|
||||
return nil, errf("invalid conversion to int32 from %q", value)
|
||||
}
|
||||
subsetVal = int64(i) // int64 is a subset type, but not int32
|
||||
default:
|
||||
return nil, errf("unsupported conversion for pre-bound parameter %q to type %q", value, ctype)
|
||||
}
|
||||
} else {
|
||||
stmt.placeholders++
|
||||
stmt.placeholderConverter = append(stmt.placeholderConverter, converterForType(ctype))
|
||||
}
|
||||
stmt.colName = append(stmt.colName, column)
|
||||
stmt.colValue = append(stmt.colValue, value)
|
||||
stmt.colValue = append(stmt.colValue, subsetVal)
|
||||
}
|
||||
default:
|
||||
return nil, errf("unsupported command type %q", cmd)
|
||||
|
@ -306,7 +318,7 @@ func (s *fakeStmt) execInsert(args []interface{}) (dbimpl.Result, os.Error) {
|
|||
return nil, fmt.Errorf("fakedb: column %q doesn't exist or dropped since prepared statement was created", colname)
|
||||
}
|
||||
var val interface{}
|
||||
if s.colValue[n] == "?" {
|
||||
if strvalue, ok := s.colValue[n].(string); ok && strvalue == "?" {
|
||||
val = args[argPos]
|
||||
argPos++
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue