// OpenVfs opens a new database with a specified virtual file system. func OpenVfs(filename string, vfsname string, flags ...OpenFlag) (*Conn, error) { if C.sqlite3_threadsafe() == 0 { return nil, errors.New("sqlite library was not compiled for thread-safe operation") } var openFlags int if len(flags) > 0 { for _, flag := range flags { openFlags |= int(flag) } } else { openFlags = C.SQLITE_OPEN_FULLMUTEX | C.SQLITE_OPEN_READWRITE | C.SQLITE_OPEN_CREATE } var db *C.sqlite3 name := C.CString(filename) defer C.free(unsafe.Pointer(name)) var vfs *C.char if len(vfsname) > 0 { vfs = C.CString(vfsname) defer C.free(unsafe.Pointer(vfs)) } rv := C.sqlite3_open_v2(name, &db, C.int(openFlags), vfs) if rv != C.SQLITE_OK { if db != nil { C.sqlite3_close(db) } return nil, Errno(rv) } if db == nil { return nil, errors.New("sqlite succeeded without returning a database") } return &Conn{db: db, stmtCache: newCache()}, nil }
// Open database and return a new connection. // You can specify DSN string with URI filename. // test.db // file:test.db?cache=shared&mode=memory // :memory: // file::memory: func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) { if C.sqlite3_threadsafe() == 0 { return nil, errors.New("sqlite library was not compiled for thread-safe operation") } var db *C.sqlite3 name := C.CString(dsn) defer C.free(unsafe.Pointer(name)) rv := C._sqlite3_open_v2(name, &db, C.SQLITE_OPEN_FULLMUTEX| C.SQLITE_OPEN_READWRITE| C.SQLITE_OPEN_CREATE, nil) if rv != 0 { return nil, errors.New(C.GoString(C.sqlite3_errmsg(db))) } if db == nil { return nil, errors.New("sqlite succeeded without returning a database") } rv = C.sqlite3_busy_timeout(db, 5000) if rv != C.SQLITE_OK { return nil, errors.New(C.GoString(C.sqlite3_errmsg(db))) } return &SQLiteConn{db}, nil }
// Open database and return a new connection. // You can specify DSN string with URI filename. // test.db // file:test.db?cache=shared&mode=memory // :memory: // file::memory: func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) { if C.sqlite3_threadsafe() == 0 { return nil, errors.New("sqlite library was not compiled for thread-safe operation") } var db *C.sqlite3 name := C.CString(dsn) defer C.free(unsafe.Pointer(name)) rv := C._sqlite3_open_v2(name, &db, C.SQLITE_OPEN_FULLMUTEX| C.SQLITE_OPEN_READWRITE| C.SQLITE_OPEN_CREATE, nil) if rv != 0 { return nil, Error{Code: ErrNo(rv)} } if db == nil { return nil, errors.New("sqlite succeeded without returning a database") } rv = C.sqlite3_busy_timeout(db, 5000) if rv != C.SQLITE_OK { return nil, Error{Code: ErrNo(rv)} } conn := &SQLiteConn{db} if len(d.Extensions) > 0 { rv = C.sqlite3_enable_load_extension(db, 1) if rv != C.SQLITE_OK { return nil, errors.New(C.GoString(C.sqlite3_errmsg(db))) } for _, extension := range d.Extensions { cext := C.CString(extension) defer C.free(unsafe.Pointer(cext)) rv = C.sqlite3_load_extension(db, cext, nil, nil) if rv != C.SQLITE_OK { return nil, errors.New(C.GoString(C.sqlite3_errmsg(db))) } } rv = C.sqlite3_enable_load_extension(db, 0) if rv != C.SQLITE_OK { return nil, errors.New(C.GoString(C.sqlite3_errmsg(db))) } } if d.ConnectHook != nil { if err := d.ConnectHook(conn); err != nil { return nil, err } } runtime.SetFinalizer(conn, (*SQLiteConn).Close) return conn, nil }
// OpenVfs opens a new database with a specified virtual file system. func OpenVfs(filename string, vfsname string, flags ...OpenFlag) (*Conn, error) { if C.sqlite3_threadsafe() == 0 { return nil, errors.New("sqlite library was not compiled for thread-safe operation") } var openFlags int if len(flags) > 0 { for _, flag := range flags { openFlags |= int(flag) } } else { openFlags = C.SQLITE_OPEN_FULLMUTEX | C.SQLITE_OPEN_READWRITE | C.SQLITE_OPEN_CREATE } var db *C.sqlite3 cname := C.CString(filename) defer C.free(unsafe.Pointer(cname)) var vfs *C.char if len(vfsname) > 0 { vfs = C.CString(vfsname) defer C.free(unsafe.Pointer(vfs)) } rv := C.sqlite3_open_v2(cname, &db, C.int(openFlags), vfs) if rv != C.SQLITE_OK { if db != nil { // try to extract futher details from db... err := OpenError{Code: Errno(rv), ExtendedCode: int(C.sqlite3_extended_errcode(db)), Msg: C.GoString(C.sqlite3_errmsg(db)), Filename: filename, } C.sqlite3_close(db) return nil, err } return nil, Errno(rv) } if db == nil { return nil, errors.New("sqlite succeeded without returning a database") } c := &Conn{db: db, stmtCache: newCache(), DefaultTimeLayout: "2006-01-02 15:04:05.000Z07:00"} if os.Getenv("SQLITE_DEBUG") != "" { //c.SetAuthorizer(authorizer, c.db) c.Trace(trace, "TRACE") //c.SetCacheSize(0) } return c, nil }
func (db *Database) Open(flags ...int) (e error) { if C.sqlite3_threadsafe() == 0 { panic("sqlite library is not thread-safe") } if db.handle != nil { e = CANTOPEN } else { db.Flags = 0 for _, v := range flags { db.Flags = db.Flags | C.int(v) } if err := Errno(C.sqlite3_open_v2(C.CString(db.Filename), &db.handle, db.Flags, nil)); err != OK { e = err } else if db.handle == nil { e = CANTOPEN } } return }
func OpenV2(filename string, flags int) (*Conn, error) { if C.sqlite3_threadsafe() == 0 { return nil, errors.New("sqlite library was not compiled for thread-safe operation") } var db *C.sqlite3 name := C.CString(filename) defer C.free(unsafe.Pointer(name)) rv := C.sqlite3_open_v2(name, &db, C.int(flags), nil) if rv != 0 { return nil, Errno(rv) } if db == nil { return nil, errors.New("sqlite succeeded without returning a database") } return &Conn{db}, nil }
func Open(filename string) (*Conn, error) { if C.sqlite3_threadsafe() == 0 { return nil, errors.New("sqlite library was not compiled for thread-safe operation") } var db *C.sqlite3 name := C.CString(filename) defer C.free(unsafe.Pointer(name)) rv := C.sqlite3_open_v2(name, &db, C.SQLITE_OPEN_FULLMUTEX| C.SQLITE_OPEN_READWRITE| C.SQLITE_OPEN_CREATE, nil) if rv != 0 { return nil, Errno(rv) } if db == nil { return nil, errors.New("sqlite succeeded without returning a database") } return &Conn{db}, nil }
// Open database and return a new connection. // You can specify DSN string with URI filename. // test.db // file:test.db?cache=shared&mode=memory // :memory: // file::memory: func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) { if C.sqlite3_threadsafe() == 0 { return nil, errors.New("sqlite library was not compiled for thread-safe operation") } //encrypt dsn type "file.db@123456" isp := strings.Index(dsn, "@") var fileName string var pKey string if isp > 0 { fileName = dsn[:isp] pKey = dsn[isp+1:] } else { fileName = dsn } var db *C.sqlite3 name := C.CString(fileName) defer C.free(unsafe.Pointer(name)) rv := C._sqlite3_open_v2(name, &db, C.SQLITE_OPEN_FULLMUTEX| C.SQLITE_OPEN_READWRITE| C.SQLITE_OPEN_CREATE, nil) if rv != 0 { return nil, errors.New(C.GoString(C.sqlite3_errmsg(db))) } if db == nil { return nil, errors.New("sqlite succeeded without returning a database") } rv = C.sqlite3_busy_timeout(db, 5000) if rv != C.SQLITE_OK { return nil, errors.New(C.GoString(C.sqlite3_errmsg(db))) } //encrypt db key(db, pKey) return &SQLiteConn{db}, nil }
// Open initializes and opens the database. func (db *Database) Open(flags ...DBFlag) (e error) { if C.sqlite3_threadsafe() == 0 { panic("sqlite library is not thread-safe") } if db.handle != nil { e = CANTOPEN } else { db.DBFlag = 0 for _, v := range flags { db.DBFlag |= v } cs := C.CString(db.Filename) defer C.free(unsafe.Pointer(cs)) e = SQLiteError(C.sqlite3_open_v2(cs, &db.handle, C.int(db.DBFlag), nil)) if e == nil && db.handle == nil { e = CANTOPEN } } return }
// Open database and return a new connection. // You can specify DSN string with URI filename. // test.db // file:test.db?cache=shared&mode=memory // :memory: // file::memory: // go-sqlite handle especially query parameters. // _loc=XXX // Specify location of time format. It's possible to specify "auto". // _busy_timeout=XXX // Specify value for sqlite3_busy_timeout. // _txlock=XXX // Specify locking behavior for transactions. XXX can be "immediate", // "deferred", "exclusive". func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) { if C.sqlite3_threadsafe() == 0 { return nil, errors.New("sqlite library was not compiled for thread-safe operation") } var loc *time.Location txlock := "BEGIN" busy_timeout := 5000 pos := strings.IndexRune(dsn, '?') if pos >= 1 { params, err := url.ParseQuery(dsn[pos+1:]) if err != nil { return nil, err } // _loc if val := params.Get("_loc"); val != "" { if val == "auto" { loc = time.Local } else { loc, err = time.LoadLocation(val) if err != nil { return nil, fmt.Errorf("Invalid _loc: %v: %v", val, err) } } } // _busy_timeout if val := params.Get("_busy_timeout"); val != "" { iv, err := strconv.ParseInt(val, 10, 64) if err != nil { return nil, fmt.Errorf("Invalid _busy_timeout: %v: %v", val, err) } busy_timeout = int(iv) } // _txlock if val := params.Get("_txlock"); val != "" { switch val { case "immediate": txlock = "BEGIN IMMEDIATE" case "exclusive": txlock = "BEGIN EXCLUSIVE" case "deferred": txlock = "BEGIN" default: return nil, fmt.Errorf("Invalid _txlock: %v", val) } } if !strings.HasPrefix(dsn, "file:") { dsn = dsn[:pos] } } var db *C.sqlite3 name := C.CString(dsn) defer C.free(unsafe.Pointer(name)) rv := C._sqlite3_open_v2(name, &db, C.SQLITE_OPEN_FULLMUTEX| C.SQLITE_OPEN_READWRITE| C.SQLITE_OPEN_CREATE, nil) if rv != 0 { return nil, Error{Code: ErrNo(rv)} } if db == nil { return nil, errors.New("sqlite succeeded without returning a database") } rv = C.sqlite3_busy_timeout(db, C.int(busy_timeout)) if rv != C.SQLITE_OK { return nil, Error{Code: ErrNo(rv)} } conn := &SQLiteConn{db: db, loc: loc, txlock: txlock} if len(d.Extensions) > 0 { rv = C.sqlite3_enable_load_extension(db, 1) if rv != C.SQLITE_OK { return nil, errors.New(C.GoString(C.sqlite3_errmsg(db))) } for _, extension := range d.Extensions { cext := C.CString(extension) defer C.free(unsafe.Pointer(cext)) rv = C.sqlite3_load_extension(db, cext, nil, nil) if rv != C.SQLITE_OK { return nil, errors.New(C.GoString(C.sqlite3_errmsg(db))) } } rv = C.sqlite3_enable_load_extension(db, 0) if rv != C.SQLITE_OK { return nil, errors.New(C.GoString(C.sqlite3_errmsg(db))) } } if d.ConnectHook != nil { if err := d.ConnectHook(conn); err != nil { return nil, err } } runtime.SetFinalizer(conn, (*SQLiteConn).Close) return conn, nil }
// SingleThread returns true if the SQLite library was compiled with // -DSQLITE_THREADSAFE=0. In this threading mode all mutex code is omitted and // the package becomes unsafe for concurrent access, even to separate database // connections. // // The SQLite source that's part of this package is compiled with // -DSQLITE_THREADSAFE=2, so this function should always return false. It is // kept for backward compatibility when dynamic linking was supported in Go 1.0. // [http://www.sqlite.org/threadsafe.html] func SingleThread() bool { return initErr == nil && C.sqlite3_threadsafe() == 0 }
// Open database and return a new connection. // You can specify DSN string with URI filename. // test.db // file:test.db?cache=shared&mode=memory // :memory: // file::memory: // go-sqlite3 adds the following query parameters to those used by SQLite: // _loc=XXX // Specify location of time format. It's possible to specify "auto". // _busy_timeout=XXX // Specify value for sqlite3_busy_timeout. // _txlock=XXX // Specify locking behavior for transactions. XXX can be "immediate", // "deferred", "exclusive". // go-sqlcipher adds the following query parameters to those used by SQLite: // _pragma_key=XXX // Specify PRAGMA key. // _pragma_cipher_page_size=XXX // Set the PRAGMA cipher_page_size to adjust the page size. // _pragma_foreign_keys=XXX. // Set the PRAGMA foreign_keys. XXX must be a boolean. func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) { if C.sqlite3_threadsafe() == 0 { return nil, errors.New("sqlite library was not compiled for thread-safe operation") } var loc *time.Location txlock := "BEGIN" busy_timeout := 5000 pos := strings.IndexRune(dsn, '?') var params url.Values if pos >= 1 { var err error params, err = url.ParseQuery(dsn[pos+1:]) if err != nil { return nil, err } // _loc if val := params.Get("_loc"); val != "" { if val == "auto" { loc = time.Local } else { loc, err = time.LoadLocation(val) if err != nil { return nil, fmt.Errorf("Invalid _loc: %v: %v", val, err) } } } // _busy_timeout if val := params.Get("_busy_timeout"); val != "" { iv, err := strconv.ParseInt(val, 10, 64) if err != nil { return nil, fmt.Errorf("Invalid _busy_timeout: %v: %v", val, err) } busy_timeout = int(iv) } // _txlock if val := params.Get("_txlock"); val != "" { switch val { case "immediate": txlock = "BEGIN IMMEDIATE" case "exclusive": txlock = "BEGIN EXCLUSIVE" case "deferred": txlock = "BEGIN" default: return nil, fmt.Errorf("Invalid _txlock: %v", val) } } if !strings.HasPrefix(dsn, "file:") { dsn = dsn[:pos] } } var db *C.sqlite3 name := C.CString(dsn) defer C.free(unsafe.Pointer(name)) rv := C._sqlite3_open_v2(name, &db, C.SQLITE_OPEN_NOMUTEX| C.SQLITE_OPEN_READWRITE| C.SQLITE_OPEN_CREATE, nil) if rv != 0 { return nil, Error{Code: ErrNo(rv)} } if db == nil { return nil, errors.New("sqlite succeeded without returning a database") } rv = C.sqlite3_busy_timeout(db, C.int(busy_timeout)) if rv != C.SQLITE_OK { return nil, Error{Code: ErrNo(rv)} } conn := &SQLiteConn{db: db, loc: loc, txlock: txlock} // process SQLCipher pragmas encoded in dsn, if necessary if params != nil { // _pragma_key if val := params.Get("_pragma_key"); val != "" { query := fmt.Sprintf("PRAGMA key = \"%s\";", val) if _, err := conn.Exec(query, nil); err != nil { return nil, err } } // _pragma_cipher_page_size if val := params.Get("_pragma_cipher_page_size"); val != "" { pageSize, err := strconv.Atoi(val) if err != nil { return nil, fmt.Errorf("sqlite3: _pragma_cipher_page_size cannot be parsed: %s", err) } query := fmt.Sprintf("PRAGMA cipher_page_size = %d;", pageSize) if _, err := conn.Exec(query, nil); err != nil { return nil, err } } // _pragma_foreign_keys if val := params.Get("_pragma_foreign_keys"); val != "" { query := fmt.Sprintf("PRAGMA foreign_keys = %s;", val) if _, err := conn.Exec(query, nil); err != nil { return nil, err } } } if d.ConnectHook != nil { if err := d.ConnectHook(conn); err != nil { return nil, err } } runtime.SetFinalizer(conn, (*SQLiteConn).Close) return conn, nil }
// Open database and return a new connection. // You can specify DSN string with URI filename. // test.db // file:test.db?cache=shared&mode=memory // :memory: // file::memory: func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) { if C.sqlite3_threadsafe() == 0 { return nil, errors.New("sqlite library was not compiled for thread-safe operation") } var db *C.sqlite3 name := C.CString(dsn) defer C.free(unsafe.Pointer(name)) rv := C._sqlite3_open_v2(name, &db, C.SQLITE_OPEN_FULLMUTEX| C.SQLITE_OPEN_READWRITE| C.SQLITE_OPEN_CREATE, nil) if rv != 0 { return nil, ErrNo(rv) } if db == nil { return nil, errors.New("sqlite succeeded without returning a database") } rv = C.sqlite3_busy_timeout(db, 5000) if rv != C.SQLITE_OK { return nil, ErrNo(rv) } conn := &SQLiteConn{db} if len(d.Extensions) > 0 { rv = C.sqlite3_enable_load_extension(db, 1) if rv != C.SQLITE_OK { return nil, errors.New(C.GoString(C.sqlite3_errmsg(db))) } stmt, err := conn.Prepare("SELECT load_extension(?);") if err != nil { return nil, err } for _, extension := range d.Extensions { if _, err = stmt.Exec([]driver.Value{extension}); err != nil { return nil, err } } if err = stmt.Close(); err != nil { return nil, err } rv = C.sqlite3_enable_load_extension(db, 0) if rv != C.SQLITE_OK { return nil, errors.New(C.GoString(C.sqlite3_errmsg(db))) } } if d.ConnectHook != nil { if err := d.ConnectHook(conn); err != nil { return nil, err } } return conn, nil }