Commit 6bc819a9 authored by gwenn's avatar gwenn

Replace ConnError/StmtError pointer by simple value.

parent 3cb36f53
language: go language: go
go: go:
- 1.1
- tip - tip
before_install: before_install:
- echo "yes" | sudo add-apt-repository ppa:travis-ci/sqlite3 - echo "yes" | sudo add-apt-repository ppa:travis-ci/sqlite3
......
...@@ -31,7 +31,7 @@ func TestInterrupt(t *testing.T) { ...@@ -31,7 +31,7 @@ func TestInterrupt(t *testing.T) {
t.Fatalf("got %v; want interrupt", err) t.Fatalf("got %v; want interrupt", err)
} }
//println(err.Error()) //println(err.Error())
if se, ok := err.(*StmtError); !ok || se.Code() != ErrInterrupt { if se, ok := err.(StmtError); !ok || se.Code() != ErrInterrupt {
t.Errorf("got %#v; want interrupt", err) t.Errorf("got %#v; want interrupt", err)
} }
} }
...@@ -58,7 +58,7 @@ func TestDefaultBusy(t *testing.T) { ...@@ -58,7 +58,7 @@ func TestDefaultBusy(t *testing.T) {
if err == nil { if err == nil {
t.Fatalf("got %v; want lock", err) t.Fatalf("got %v; want lock", err)
} }
if se, ok := err.(*StmtError); !ok || se.Code() != ErrBusy { if se, ok := err.(StmtError); !ok || se.Code() != ErrBusy {
t.Fatalf("got %#v; want lock", err) t.Fatalf("got %#v; want lock", err)
} }
} }
......
...@@ -86,7 +86,7 @@ func (d *impl) Open(name string) (driver.Conn, error) { ...@@ -86,7 +86,7 @@ func (d *impl) Open(name string) (driver.Conn, error) {
// Unwrap gives access to underlying driver connection. // Unwrap gives access to underlying driver connection.
func Unwrap(db *sql.DB) *Conn { func Unwrap(db *sql.DB) *Conn {
_, err := db.Exec("unwrap") _, err := db.Exec("unwrap")
if cerr, ok := err.(*ConnError); ok { if cerr, ok := err.(ConnError); ok {
return cerr.c return cerr.c
} }
return nil return nil
...@@ -99,6 +99,9 @@ func (c *conn) Exec(query string, args []driver.Value) (driver.Result, error) { ...@@ -99,6 +99,9 @@ func (c *conn) Exec(query string, args []driver.Value) (driver.Result, error) {
return nil, driver.ErrBadConn return nil, driver.ErrBadConn
} }
if len(args) == 0 { if len(args) == 0 {
if query == "unwrap" {
return nil, ConnError{c: c.c}
}
if err := c.c.FastExec(query); err != nil { if err := c.c.FastExec(query); err != nil {
return nil, err return nil, err
} }
......
...@@ -32,23 +32,23 @@ type ConnError struct { ...@@ -32,23 +32,23 @@ type ConnError struct {
} }
// Code returns the original SQLite error code (or -1 for errors generated by the Go wrapper) // Code returns the original SQLite error code (or -1 for errors generated by the Go wrapper)
func (e *ConnError) Code() Errno { func (e ConnError) Code() Errno {
return e.code return e.code
} }
// ExtendedCode returns the SQLite extended error code. // ExtendedCode returns the SQLite extended error code.
// (See http://www.sqlite.org/c3ref/errcode.html) // (See http://www.sqlite.org/c3ref/errcode.html)
// FIXME it might be the case that a second error occurs on a separate thread in between the time of the first error and the call to this method. // FIXME it might be the case that a second error occurs on a separate thread in between the time of the first error and the call to this method.
func (e *ConnError) ExtendedCode() int { func (e ConnError) ExtendedCode() int {
return int(C.sqlite3_extended_errcode(e.c.db)) return int(C.sqlite3_extended_errcode(e.c.db))
} }
// Filename returns database file name from which the error comes from. // Filename returns database file name from which the error comes from.
func (e *ConnError) Filename() string { func (e ConnError) Filename() string {
return e.c.Filename("main") return e.c.Filename("main")
} }
func (e *ConnError) Error() string { // FIXME code.Error() & e.msg are often redundant... func (e ConnError) Error() string { // FIXME code.Error() & e.msg are often redundant...
if len(e.details) > 0 { if len(e.details) > 0 {
return fmt.Sprintf("%s (%s) (%s)", e.msg, e.details, e.code.Error()) return fmt.Sprintf("%s (%s) (%s)", e.msg, e.details, e.code.Error())
} else if len(e.msg) > 0 { } else if len(e.msg) > 0 {
...@@ -115,7 +115,7 @@ func (c *Conn) error(rv C.int, details ...string) error { ...@@ -115,7 +115,7 @@ func (c *Conn) error(rv C.int, details ...string) error {
if rv == C.SQLITE_OK { if rv == C.SQLITE_OK {
return nil return nil
} }
err := &ConnError{c: c, code: Errno(rv), msg: C.GoString(C.sqlite3_errmsg(c.db))} err := ConnError{c: c, code: Errno(rv), msg: C.GoString(C.sqlite3_errmsg(c.db))}
if len(details) > 0 { if len(details) > 0 {
err.details = details[0] err.details = details[0]
} }
...@@ -123,7 +123,7 @@ func (c *Conn) error(rv C.int, details ...string) error { ...@@ -123,7 +123,7 @@ func (c *Conn) error(rv C.int, details ...string) error {
} }
func (c *Conn) specificError(msg string, a ...interface{}) error { func (c *Conn) specificError(msg string, a ...interface{}) error {
return &ConnError{c: c, code: ErrSpecific, msg: fmt.Sprintf(msg, a...)} return ConnError{c: c, code: ErrSpecific, msg: fmt.Sprintf(msg, a...)}
} }
// LastError returns the error for the most recent failed sqlite3_* API call associated with a database connection. // LastError returns the error for the most recent failed sqlite3_* API call associated with a database connection.
...@@ -136,7 +136,7 @@ func (c *Conn) LastError() error { ...@@ -136,7 +136,7 @@ func (c *Conn) LastError() error {
if errorCode == C.SQLITE_OK { if errorCode == C.SQLITE_OK {
return nil return nil
} }
return &ConnError{c: c, code: Errno(errorCode), msg: C.GoString(C.sqlite3_errmsg(c.db))} return ConnError{c: c, code: Errno(errorCode), msg: C.GoString(C.sqlite3_errmsg(c.db))}
} }
// Conn represents a database connection handle. // Conn represents a database connection handle.
......
...@@ -193,7 +193,7 @@ func TestConnExecWithSelect(t *testing.T) { ...@@ -193,7 +193,7 @@ func TestConnExecWithSelect(t *testing.T) {
err := db.Exec("SELECT 1") err := db.Exec("SELECT 1")
assert.T(t, err != nil, "error expected") assert.T(t, err != nil, "error expected")
if serr, ok := err.(*StmtError); ok { if serr, ok := err.(StmtError); ok {
assert.Equal(t, ErrSpecific, serr.Code()) assert.Equal(t, ErrSpecific, serr.Code())
} else { } else {
t.Errorf("got %s; want StmtError", reflect.TypeOf(err)) t.Errorf("got %s; want StmtError", reflect.TypeOf(err))
...@@ -270,7 +270,7 @@ func TestCommitMisuse(t *testing.T) { ...@@ -270,7 +270,7 @@ func TestCommitMisuse(t *testing.T) {
err := db.Commit() err := db.Commit()
assert.T(t, err != nil, "error expected") assert.T(t, err != nil, "error expected")
if cerr, ok := err.(*ConnError); ok { if cerr, ok := err.(ConnError); ok {
assert.Equal(t, ErrError, cerr.Code()) assert.Equal(t, ErrError, cerr.Code())
assert.Equal(t, 1, cerr.ExtendedCode()) assert.Equal(t, 1, cerr.ExtendedCode())
} else { } else {
......
...@@ -48,7 +48,7 @@ type StmtError struct { ...@@ -48,7 +48,7 @@ type StmtError struct {
} }
// SQL returns the SQL associated with the prepared statement in error. // SQL returns the SQL associated with the prepared statement in error.
func (e *StmtError) SQL() string { func (e StmtError) SQL() string {
return e.s.SQL() return e.s.SQL()
} }
...@@ -63,11 +63,11 @@ func (s *Stmt) error(rv C.int, details ...string) error { ...@@ -63,11 +63,11 @@ func (s *Stmt) error(rv C.int, details ...string) error {
if len(details) > 0 { if len(details) > 0 {
err.details = details[0] err.details = details[0]
} }
return &StmtError{err, s} return StmtError{err, s}
} }
func (s *Stmt) specificError(msg string, a ...interface{}) error { func (s *Stmt) specificError(msg string, a ...interface{}) error {
return &StmtError{ConnError{c: s.c, code: ErrSpecific, msg: fmt.Sprintf(msg, a...)}, s} return StmtError{ConnError{c: s.c, code: ErrSpecific, msg: fmt.Sprintf(msg, a...)}, s}
} }
// CheckTypeMismatch enables type check in Scan methods (default true) // CheckTypeMismatch enables type check in Scan methods (default true)
......
...@@ -176,7 +176,7 @@ func TestScanCheck(t *testing.T) { ...@@ -176,7 +176,7 @@ func TestScanCheck(t *testing.T) {
assert.T(t, checkStep(t, s)) assert.T(t, checkStep(t, s))
var i int var i int
_, err = s.ScanByIndex(0, &i) _, err = s.ScanByIndex(0, &i)
if serr, ok := err.(*StmtError); ok { if serr, ok := err.(StmtError); ok {
assert.Equal(t, "", serr.Filename()) assert.Equal(t, "", serr.Filename())
assert.Equal(t, ErrSpecific, serr.Code()) assert.Equal(t, ErrSpecific, serr.Code())
assert.Equal(t, s.SQL(), serr.SQL()) assert.Equal(t, s.SQL(), serr.SQL())
...@@ -318,7 +318,6 @@ func TestStmtWithClosedDb(t *testing.T) { ...@@ -318,7 +318,6 @@ func TestStmtWithClosedDb(t *testing.T) {
s, err := db.Prepare("SELECT 1") s, err := db.Prepare("SELECT 1")
checkNoError(t, err, "prepare error: %s") checkNoError(t, err, "prepare error: %s")
assert.Equal(t, db, s.Conn(), "conn") assert.Equal(t, db, s.Conn(), "conn")
defer s.Finalize()
err = db.Close() err = db.Close()
checkNoError(t, err, "close error: %s") checkNoError(t, err, "close error: %s")
...@@ -339,7 +338,7 @@ func TestStmtExecWithSelect(t *testing.T) { ...@@ -339,7 +338,7 @@ func TestStmtExecWithSelect(t *testing.T) {
err = s.Exec() err = s.Exec()
assert.T(t, err != nil, "error expected") assert.T(t, err != nil, "error expected")
//println(err.Error()) //println(err.Error())
if serr, ok := err.(*StmtError); ok { if serr, ok := err.(StmtError); ok {
assert.Equal(t, ErrSpecific, serr.Code()) assert.Equal(t, ErrSpecific, serr.Code())
} else { } else {
t.Errorf("got %s; want StmtError", reflect.TypeOf(err)) t.Errorf("got %s; want StmtError", reflect.TypeOf(err))
...@@ -384,7 +383,7 @@ func TestStmtSelectWithInsert(t *testing.T) { ...@@ -384,7 +383,7 @@ func TestStmtSelectWithInsert(t *testing.T) {
exists, err := s.SelectOneRow() exists, err := s.SelectOneRow()
assert.T(t, err != nil, "error expected") assert.T(t, err != nil, "error expected")
//println(err.Error()) //println(err.Error())
if serr, ok := err.(*StmtError); ok { if serr, ok := err.(StmtError); ok {
assert.Equal(t, ErrSpecific, serr.Code()) assert.Equal(t, ErrSpecific, serr.Code())
} else { } else {
t.Errorf("got %s; want StmtError", reflect.TypeOf(err)) t.Errorf("got %s; want StmtError", reflect.TypeOf(err))
......
...@@ -391,6 +391,8 @@ func ConfigLog(f Logger, udp interface{}) error { ...@@ -391,6 +391,8 @@ func ConfigLog(f Logger, udp interface{}) error {
return Errno(rv) return Errno(rv)
} }
// ExplainQueryPlan outputs the corresponding EXPLAIN QUERY PLAN report to the specified writer
// (See http://sqlite.org/eqp.html)
func (s *Stmt) ExplainQueryPlan(w io.Writer) error { func (s *Stmt) ExplainQueryPlan(w io.Writer) error {
sql := s.SQL() sql := s.SQL()
if len(sql) == 0 { if len(sql) == 0 {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment