commit
03cb0c0623
22
sqlite3.go
22
sqlite3.go
|
@ -990,6 +990,7 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
|
|||
authPass := ""
|
||||
authCrypt := ""
|
||||
authSalt := ""
|
||||
mutex := C.int(C.SQLITE_OPEN_FULLMUTEX)
|
||||
txlock := "BEGIN"
|
||||
|
||||
// PRAGMA's
|
||||
|
@ -1006,7 +1007,6 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
|
|||
secureDelete := "DEFAULT"
|
||||
synchronousMode := "NORMAL"
|
||||
writableSchema := -1
|
||||
flags := C.SQLITE_OPEN_READWRITE | C.SQLITE_OPEN_CREATE | C.SQLITE_OPEN_FULLMUTEX
|
||||
|
||||
pos := strings.IndexRune(dsn, '?')
|
||||
if pos >= 1 {
|
||||
|
@ -1015,17 +1015,6 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if val := params.Get("mode"); val != "" {
|
||||
switch val {
|
||||
case "ro":
|
||||
flags |= C.SQLITE_OPEN_READONLY
|
||||
case "rw":
|
||||
flags ^= C.SQLITE_OPEN_CREATE
|
||||
case "rwc":
|
||||
flags |= C.SQLITE_OPEN_CREATE
|
||||
}
|
||||
}
|
||||
|
||||
// Authentication
|
||||
if _, ok := params["_auth"]; ok {
|
||||
authCreate = true
|
||||
|
@ -1060,9 +1049,9 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
|
|||
if val := params.Get("_mutex"); val != "" {
|
||||
switch strings.ToLower(val) {
|
||||
case "no":
|
||||
flags |= C.SQLITE_OPEN_NOMUTEX
|
||||
mutex = C.SQLITE_OPEN_NOMUTEX
|
||||
case "full":
|
||||
flags |= C.SQLITE_OPEN_FULLMUTEX
|
||||
mutex = C.SQLITE_OPEN_FULLMUTEX
|
||||
default:
|
||||
return nil, fmt.Errorf("Invalid _mutex: %v", val)
|
||||
}
|
||||
|
@ -1349,8 +1338,9 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
|
|||
var db *C.sqlite3
|
||||
name := C.CString(dsn)
|
||||
defer C.free(unsafe.Pointer(name))
|
||||
|
||||
rv := C._sqlite3_open_v2(name, &db, C.int(flags), nil)
|
||||
rv := C._sqlite3_open_v2(name, &db,
|
||||
mutex|C.SQLITE_OPEN_READWRITE|C.SQLITE_OPEN_CREATE,
|
||||
nil)
|
||||
if rv != 0 {
|
||||
if db != nil {
|
||||
C.sqlite3_close_v2(db)
|
||||
|
|
|
@ -87,6 +87,64 @@ func TestOpen(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestOpenNoCreate(t *testing.T) {
|
||||
filename := t.Name() + ".sqlite"
|
||||
|
||||
if err := os.Remove(filename); err != nil && !os.IsNotExist(err) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.Remove(filename)
|
||||
|
||||
// https://golang.org/pkg/database/sql/#Open
|
||||
// "Open may just validate its arguments without creating a connection
|
||||
// to the database. To verify that the data source name is valid, call Ping."
|
||||
db, err := sql.Open("sqlite3", fmt.Sprintf("file:%s?mode=rw", filename))
|
||||
if err == nil {
|
||||
defer db.Close()
|
||||
|
||||
err = db.Ping()
|
||||
if err == nil {
|
||||
t.Fatal("expected error from Open or Ping")
|
||||
}
|
||||
}
|
||||
|
||||
sqlErr, ok := err.(Error)
|
||||
if !ok {
|
||||
t.Fatalf("expected sqlite3.Error, but got %T", err)
|
||||
}
|
||||
|
||||
if sqlErr.Code != ErrCantOpen {
|
||||
t.Fatalf("expected SQLITE_CANTOPEN, but got %v", sqlErr)
|
||||
}
|
||||
|
||||
// make sure database file truly was not created
|
||||
if _, err := os.Stat(filename); !os.IsNotExist(err) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Fatal("expected database file to not exist")
|
||||
}
|
||||
|
||||
// verify that it works if the mode is "rwc" instead
|
||||
db, err = sql.Open("sqlite3", fmt.Sprintf("file:%s?mode=rwc", filename))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
if err := db.Ping(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// make sure database file truly was created
|
||||
if _, err := os.Stat(filename); err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Fatal("expected database file to exist")
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadonly(t *testing.T) {
|
||||
tempFilename := TempFilename(t)
|
||||
defer os.Remove(tempFilename)
|
||||
|
|
Loading…
Reference in New Issue