mirror of
https://github.com/ncruces/go-sqlite3.git
synced 2026-01-11 21:49:13 +00:00
Refactor.
This commit is contained in:
@@ -274,6 +274,7 @@ func (n *connector) Connect(ctx context.Context) (res driver.Conn, err error) {
|
|||||||
// if err != nil {
|
// if err != nil {
|
||||||
// log.Fatal(err)
|
// log.Fatal(err)
|
||||||
// }
|
// }
|
||||||
|
// defer conn.Close()
|
||||||
//
|
//
|
||||||
// err = conn.Raw(func(driverConn any) error {
|
// err = conn.Raw(func(driverConn any) error {
|
||||||
// conn := driverConn.(driver.Conn)
|
// conn := driverConn.(driver.Conn)
|
||||||
|
|||||||
@@ -12,3 +12,63 @@ func namedValues(args []driver.Value) []driver.NamedValue {
|
|||||||
}
|
}
|
||||||
return named
|
return named
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func notWhitespace(sql string) bool {
|
||||||
|
const (
|
||||||
|
code = iota
|
||||||
|
slash
|
||||||
|
minus
|
||||||
|
ccomment
|
||||||
|
sqlcomment
|
||||||
|
endcomment
|
||||||
|
)
|
||||||
|
|
||||||
|
state := code
|
||||||
|
for _, b := range ([]byte)(sql) {
|
||||||
|
if b == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
switch state {
|
||||||
|
case code:
|
||||||
|
switch b {
|
||||||
|
case '/':
|
||||||
|
state = slash
|
||||||
|
case '-':
|
||||||
|
state = minus
|
||||||
|
case ' ', ';', '\t', '\n', '\v', '\f', '\r':
|
||||||
|
continue
|
||||||
|
default:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
case slash:
|
||||||
|
if b != '*' {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
state = ccomment
|
||||||
|
case minus:
|
||||||
|
if b != '-' {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
state = sqlcomment
|
||||||
|
case ccomment:
|
||||||
|
if b == '*' {
|
||||||
|
state = endcomment
|
||||||
|
}
|
||||||
|
case sqlcomment:
|
||||||
|
if b == '\n' {
|
||||||
|
state = code
|
||||||
|
}
|
||||||
|
case endcomment:
|
||||||
|
switch b {
|
||||||
|
case '/':
|
||||||
|
state = code
|
||||||
|
case '*':
|
||||||
|
state = endcomment
|
||||||
|
default:
|
||||||
|
state = ccomment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return state == slash || state == minus
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
package driver
|
package driver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"database/sql/driver"
|
"database/sql/driver"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
_ "github.com/ncruces/go-sqlite3/embed"
|
||||||
|
_ "github.com/ncruces/go-sqlite3/internal/testcfg"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_namedValues(t *testing.T) {
|
func Test_namedValues(t *testing.T) {
|
||||||
@@ -16,3 +20,67 @@ func Test_namedValues(t *testing.T) {
|
|||||||
t.Errorf("got %v, want %v", got, want)
|
t.Errorf("got %v, want %v", got, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Fuzz_notWhitespace(f *testing.F) {
|
||||||
|
f.Add("")
|
||||||
|
f.Add(" ")
|
||||||
|
f.Add(";")
|
||||||
|
f.Add("0")
|
||||||
|
f.Add("-")
|
||||||
|
f.Add("-0")
|
||||||
|
f.Add("--")
|
||||||
|
f.Add("--0")
|
||||||
|
f.Add("--\n")
|
||||||
|
f.Add("--0\n")
|
||||||
|
f.Add("/0")
|
||||||
|
f.Add("/*")
|
||||||
|
f.Add("/*/")
|
||||||
|
f.Add("/**")
|
||||||
|
f.Add("/*0")
|
||||||
|
f.Add("/**/")
|
||||||
|
f.Add("/***/")
|
||||||
|
f.Add("/**0/")
|
||||||
|
f.Add("\v")
|
||||||
|
f.Add(" \v")
|
||||||
|
f.Add("\xf0")
|
||||||
|
f.Add("\000")
|
||||||
|
|
||||||
|
db, err := Open(":memory:")
|
||||||
|
if err != nil {
|
||||||
|
f.Fatal(err)
|
||||||
|
}
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
f.Fuzz(func(t *testing.T, str string) {
|
||||||
|
if len(str) > 128 {
|
||||||
|
t.SkipNow()
|
||||||
|
}
|
||||||
|
|
||||||
|
c, err := db.Conn(context.Background())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer c.Close()
|
||||||
|
|
||||||
|
c.Raw(func(driverConn any) error {
|
||||||
|
conn := driverConn.(*conn).Conn
|
||||||
|
stmt, tail, err := conn.Prepare(str)
|
||||||
|
stmt.Close()
|
||||||
|
|
||||||
|
// It's hard to be bug for bug compatible with SQLite.
|
||||||
|
// We settle for somewhat less:
|
||||||
|
// - if SQLite reports whitespace, we must too
|
||||||
|
// - if we report whitespace, SQLite must not parse a statement
|
||||||
|
if notWhitespace(str) {
|
||||||
|
if stmt == nil && tail == "" && err == nil {
|
||||||
|
t.Errorf("was whitespace: %q", str)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if stmt != nil {
|
||||||
|
t.Errorf("was not whitespace: %q (%v)", str, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,61 +0,0 @@
|
|||||||
package driver
|
|
||||||
|
|
||||||
func notWhitespace(sql string) bool {
|
|
||||||
const (
|
|
||||||
code = iota
|
|
||||||
slash
|
|
||||||
minus
|
|
||||||
ccomment
|
|
||||||
sqlcomment
|
|
||||||
endcomment
|
|
||||||
)
|
|
||||||
|
|
||||||
state := code
|
|
||||||
for _, b := range ([]byte)(sql) {
|
|
||||||
if b == 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
switch state {
|
|
||||||
case code:
|
|
||||||
switch b {
|
|
||||||
case '/':
|
|
||||||
state = slash
|
|
||||||
case '-':
|
|
||||||
state = minus
|
|
||||||
case ' ', ';', '\t', '\n', '\v', '\f', '\r':
|
|
||||||
continue
|
|
||||||
default:
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
case slash:
|
|
||||||
if b != '*' {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
state = ccomment
|
|
||||||
case minus:
|
|
||||||
if b != '-' {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
state = sqlcomment
|
|
||||||
case ccomment:
|
|
||||||
if b == '*' {
|
|
||||||
state = endcomment
|
|
||||||
}
|
|
||||||
case sqlcomment:
|
|
||||||
if b == '\n' {
|
|
||||||
state = code
|
|
||||||
}
|
|
||||||
case endcomment:
|
|
||||||
switch b {
|
|
||||||
case '/':
|
|
||||||
state = code
|
|
||||||
case '*':
|
|
||||||
state = endcomment
|
|
||||||
default:
|
|
||||||
state = ccomment
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return state == slash || state == minus
|
|
||||||
}
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
package driver
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
_ "github.com/ncruces/go-sqlite3/embed"
|
|
||||||
_ "github.com/ncruces/go-sqlite3/internal/testcfg"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Fuzz_notWhitespace(f *testing.F) {
|
|
||||||
f.Add("")
|
|
||||||
f.Add(" ")
|
|
||||||
f.Add(";")
|
|
||||||
f.Add("0")
|
|
||||||
f.Add("-")
|
|
||||||
f.Add("-0")
|
|
||||||
f.Add("--")
|
|
||||||
f.Add("--0")
|
|
||||||
f.Add("--\n")
|
|
||||||
f.Add("--0\n")
|
|
||||||
f.Add("/0")
|
|
||||||
f.Add("/*")
|
|
||||||
f.Add("/*/")
|
|
||||||
f.Add("/**")
|
|
||||||
f.Add("/*0")
|
|
||||||
f.Add("/**/")
|
|
||||||
f.Add("/***/")
|
|
||||||
f.Add("/**0/")
|
|
||||||
f.Add("\v")
|
|
||||||
f.Add(" \v")
|
|
||||||
f.Add("\xf0")
|
|
||||||
f.Add("\000")
|
|
||||||
|
|
||||||
db, err := Open(":memory:")
|
|
||||||
if err != nil {
|
|
||||||
f.Fatal(err)
|
|
||||||
}
|
|
||||||
defer db.Close()
|
|
||||||
|
|
||||||
f.Fuzz(func(t *testing.T, str string) {
|
|
||||||
if len(str) > 128 {
|
|
||||||
t.SkipNow()
|
|
||||||
}
|
|
||||||
|
|
||||||
c, err := db.Conn(context.Background())
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer c.Close()
|
|
||||||
|
|
||||||
c.Raw(func(driverConn any) error {
|
|
||||||
conn := driverConn.(*conn).Conn
|
|
||||||
stmt, tail, err := conn.Prepare(str)
|
|
||||||
stmt.Close()
|
|
||||||
|
|
||||||
// It's hard to be bug for bug compatible with SQLite.
|
|
||||||
// We settle for somewhat less:
|
|
||||||
// - if SQLite reports whitespace, we must too
|
|
||||||
// - if we report whitespace, SQLite must not parse a statement
|
|
||||||
if notWhitespace(str) {
|
|
||||||
if stmt == nil && tail == "" && err == nil {
|
|
||||||
t.Errorf("was whitespace: %q", str)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if stmt != nil {
|
|
||||||
t.Errorf("was not whitespace: %q (%v)", str, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user