forked from mirror/go-sqlite3
commit
03cb0c0623
22
sqlite3.go
22
sqlite3.go
|
@ -990,6 +990,7 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
|
||||||
authPass := ""
|
authPass := ""
|
||||||
authCrypt := ""
|
authCrypt := ""
|
||||||
authSalt := ""
|
authSalt := ""
|
||||||
|
mutex := C.int(C.SQLITE_OPEN_FULLMUTEX)
|
||||||
txlock := "BEGIN"
|
txlock := "BEGIN"
|
||||||
|
|
||||||
// PRAGMA's
|
// PRAGMA's
|
||||||
|
@ -1006,7 +1007,6 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
|
||||||
secureDelete := "DEFAULT"
|
secureDelete := "DEFAULT"
|
||||||
synchronousMode := "NORMAL"
|
synchronousMode := "NORMAL"
|
||||||
writableSchema := -1
|
writableSchema := -1
|
||||||
flags := C.SQLITE_OPEN_READWRITE | C.SQLITE_OPEN_CREATE | C.SQLITE_OPEN_FULLMUTEX
|
|
||||||
|
|
||||||
pos := strings.IndexRune(dsn, '?')
|
pos := strings.IndexRune(dsn, '?')
|
||||||
if pos >= 1 {
|
if pos >= 1 {
|
||||||
|
@ -1015,17 +1015,6 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
|
||||||
return nil, err
|
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
|
// Authentication
|
||||||
if _, ok := params["_auth"]; ok {
|
if _, ok := params["_auth"]; ok {
|
||||||
authCreate = true
|
authCreate = true
|
||||||
|
@ -1060,9 +1049,9 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
|
||||||
if val := params.Get("_mutex"); val != "" {
|
if val := params.Get("_mutex"); val != "" {
|
||||||
switch strings.ToLower(val) {
|
switch strings.ToLower(val) {
|
||||||
case "no":
|
case "no":
|
||||||
flags |= C.SQLITE_OPEN_NOMUTEX
|
mutex = C.SQLITE_OPEN_NOMUTEX
|
||||||
case "full":
|
case "full":
|
||||||
flags |= C.SQLITE_OPEN_FULLMUTEX
|
mutex = C.SQLITE_OPEN_FULLMUTEX
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("Invalid _mutex: %v", val)
|
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
|
var db *C.sqlite3
|
||||||
name := C.CString(dsn)
|
name := C.CString(dsn)
|
||||||
defer C.free(unsafe.Pointer(name))
|
defer C.free(unsafe.Pointer(name))
|
||||||
|
rv := C._sqlite3_open_v2(name, &db,
|
||||||
rv := C._sqlite3_open_v2(name, &db, C.int(flags), nil)
|
mutex|C.SQLITE_OPEN_READWRITE|C.SQLITE_OPEN_CREATE,
|
||||||
|
nil)
|
||||||
if rv != 0 {
|
if rv != 0 {
|
||||||
if db != nil {
|
if db != nil {
|
||||||
C.sqlite3_close_v2(db)
|
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) {
|
func TestReadonly(t *testing.T) {
|
||||||
tempFilename := TempFilename(t)
|
tempFilename := TempFilename(t)
|
||||||
defer os.Remove(tempFilename)
|
defer os.Remove(tempFilename)
|
||||||
|
|
Loading…
Reference in New Issue