// 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 }
// 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 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 }
// 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 }