From 1ea89987f6b0d607300081b80869ccde6845236d Mon Sep 17 00:00:00 2001 From: Frank Braun Date: Mon, 8 May 2017 18:54:00 +0000 Subject: [PATCH] add missing pragmas --- MAINTENANCE | 2 +- sqlite3.go | 31 ++++++++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/MAINTENANCE b/MAINTENANCE index 380d675..972ce0a 100644 --- a/MAINTENANCE +++ b/MAINTENANCE @@ -15,7 +15,7 @@ Track files: error.go error_test.go -sqlite3.go (dead code and extension loading coding removed) +sqlite3.go (dead code and extension loading removed, sqlcipher pragmas added) sqlite3_other.go sqlite3_test.go (adjust path) sqlite3_windows.go diff --git a/sqlite3.go b/sqlite3.go index eb076c6..da501aa 100644 --- a/sqlite3.go +++ b/sqlite3.go @@ -330,6 +330,11 @@ func errorString(err Error) string { // "deferred", "exclusive". // _foreign_keys=X // Enable or disable enforcement of foreign keys. X can be 1 or 0. +// 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. 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") @@ -340,8 +345,10 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) { busyTimeout := 5000 foreignKeys := -1 pos := strings.IndexRune(dsn, '?') + var params url.Values if pos >= 1 { - params, err := url.ParseQuery(dsn[pos+1:]) + var err error + params, err = url.ParseQuery(dsn[pos+1:]) if err != nil { return nil, err } @@ -440,6 +447,28 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) { } } + // 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 := exec(query); 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 := exec(query); err != nil { + return nil, err + } + } + } + conn := &SQLiteConn{db: db, loc: loc, txlock: txlock} if d.ConnectHook != nil {