chore(compatibilityMode): Enable DB open in sqlcipher 3 compatibility mode

This commit is contained in:
Lukáš Tinkl 2023-05-15 16:23:54 +02:00 committed by Alex Jbanca
parent 1b0aff9ce3
commit 16cfded319
No known key found for this signature in database
GPG Key ID: 6004079575C21C5D
2 changed files with 75 additions and 154 deletions

View File

@ -913,103 +913,104 @@ func (c *SQLiteConn) begin(ctx context.Context) (driver.Tx, error) {
// The argument is may be either in parentheses or it may be separated from
// the pragma name by an equal sign. The two syntaxes yield identical results.
// In many pragmas, the argument is a boolean. The boolean can be one of:
// 1 yes true on
// 0 no false off
//
// 1 yes true on
// 0 no false off
//
// You can specify a DSN string using a URI as the filename.
// test.db
// file:test.db?cache=shared&mode=memory
// :memory:
// file::memory:
//
// mode
// Access mode of the database.
// https://www.sqlite.org/c3ref/open.html
// Values:
// - ro
// - rw
// - rwc
// - memory
// test.db
// file:test.db?cache=shared&mode=memory
// :memory:
// file::memory:
//
// cache
// SQLite Shared-Cache Mode
// https://www.sqlite.org/sharedcache.html
// Values:
// - shared
// - private
// mode
// Access mode of the database.
// https://www.sqlite.org/c3ref/open.html
// Values:
// - ro
// - rw
// - rwc
// - memory
//
// immutable=Boolean
// The immutable parameter is a boolean query parameter that indicates
// that the database file is stored on read-only media. When immutable is set,
// SQLite assumes that the database file cannot be changed,
// even by a process with higher privilege,
// and so the database is opened read-only and all locking and change detection is disabled.
// Caution: Setting the immutable property on a database file that
// does in fact change can result in incorrect query results and/or SQLITE_CORRUPT errors.
// cache
// SQLite Shared-Cache Mode
// https://www.sqlite.org/sharedcache.html
// Values:
// - shared
// - private
//
// immutable=Boolean
// The immutable parameter is a boolean query parameter that indicates
// that the database file is stored on read-only media. When immutable is set,
// SQLite assumes that the database file cannot be changed,
// even by a process with higher privilege,
// and so the database is opened read-only and all locking and change detection is disabled.
// Caution: Setting the immutable property on a database file that
// does in fact change can result in incorrect query results and/or SQLITE_CORRUPT errors.
//
// 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".
//
// _mutex=XXX
// Specify mutex mode. XXX can be "no", "full".
// _loc=XXX
// Specify location of time format. It's possible to specify "auto".
//
// _txlock=XXX
// Specify locking behavior for transactions. XXX can be "immediate",
// "deferred", "exclusive".
// _mutex=XXX
// Specify mutex mode. XXX can be "no", "full".
//
// _auto_vacuum=X | _vacuum=X
// 0 | none - Auto Vacuum disabled
// 1 | full - Auto Vacuum FULL
// 2 | incremental - Auto Vacuum Incremental
// _txlock=XXX
// Specify locking behavior for transactions. XXX can be "immediate",
// "deferred", "exclusive".
//
// _busy_timeout=XXX"| _timeout=XXX
// Specify value for sqlite3_busy_timeout.
// _auto_vacuum=X | _vacuum=X
// 0 | none - Auto Vacuum disabled
// 1 | full - Auto Vacuum FULL
// 2 | incremental - Auto Vacuum Incremental
//
// _case_sensitive_like=Boolean | _cslike=Boolean
// https://www.sqlite.org/pragma.html#pragma_case_sensitive_like
// Default or disabled the LIKE operation is case-insensitive.
// When enabling this options behaviour of LIKE will become case-sensitive.
// _busy_timeout=XXX"| _timeout=XXX
// Specify value for sqlite3_busy_timeout.
//
// _defer_foreign_keys=Boolean | _defer_fk=Boolean
// Defer Foreign Keys until outermost transaction is committed.
// _case_sensitive_like=Boolean | _cslike=Boolean
// https://www.sqlite.org/pragma.html#pragma_case_sensitive_like
// Default or disabled the LIKE operation is case-insensitive.
// When enabling this options behaviour of LIKE will become case-sensitive.
//
// _foreign_keys=Boolean | _fk=Boolean
// Enable or disable enforcement of foreign keys.
// _defer_foreign_keys=Boolean | _defer_fk=Boolean
// Defer Foreign Keys until outermost transaction is committed.
//
// _ignore_check_constraints=Boolean
// This pragma enables or disables the enforcement of CHECK constraints.
// The default setting is off, meaning that CHECK constraints are enforced by default.
// _foreign_keys=Boolean | _fk=Boolean
// Enable or disable enforcement of foreign keys.
//
// _journal_mode=MODE | _journal=MODE
// Set journal mode for the databases associated with the current connection.
// https://www.sqlite.org/pragma.html#pragma_journal_mode
// _ignore_check_constraints=Boolean
// This pragma enables or disables the enforcement of CHECK constraints.
// The default setting is off, meaning that CHECK constraints are enforced by default.
//
// _locking_mode=X | _locking=X
// Sets the database connection locking-mode.
// The locking-mode is either NORMAL or EXCLUSIVE.
// https://www.sqlite.org/pragma.html#pragma_locking_mode
// _journal_mode=MODE | _journal=MODE
// Set journal mode for the databases associated with the current connection.
// https://www.sqlite.org/pragma.html#pragma_journal_mode
//
// _query_only=Boolean
// The query_only pragma prevents all changes to database files when enabled.
// _locking_mode=X | _locking=X
// Sets the database connection locking-mode.
// The locking-mode is either NORMAL or EXCLUSIVE.
// https://www.sqlite.org/pragma.html#pragma_locking_mode
//
// _recursive_triggers=Boolean | _rt=Boolean
// Enable or disable recursive triggers.
// _query_only=Boolean
// The query_only pragma prevents all changes to database files when enabled.
//
// _secure_delete=Boolean|FAST
// When secure_delete is on, SQLite overwrites deleted content with zeros.
// https://www.sqlite.org/pragma.html#pragma_secure_delete
// _recursive_triggers=Boolean | _rt=Boolean
// Enable or disable recursive triggers.
//
// _synchronous=X | _sync=X
// Change the setting of the "synchronous" flag.
// https://www.sqlite.org/pragma.html#pragma_synchronous
//
// _writable_schema=Boolean
// When this pragma is on, the SQLITE_MASTER tables in which database
// can be changed using ordinary UPDATE, INSERT, and DELETE statements.
// Warning: misuse of this pragma can easily result in a corrupt database file.
// _secure_delete=Boolean|FAST
// When secure_delete is on, SQLite overwrites deleted content with zeros.
// https://www.sqlite.org/pragma.html#pragma_secure_delete
//
// _synchronous=X | _sync=X
// Change the setting of the "synchronous" flag.
// https://www.sqlite.org/pragma.html#pragma_synchronous
//
// _writable_schema=Boolean
// When this pragma is on, the SQLITE_MASTER tables in which database
// can be changed using ordinary UPDATE, INSERT, and DELETE statements.
// Warning: misuse of this pragma can easily result in a corrupt database file.
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")
@ -1035,11 +1036,9 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
foreignKeys := -1
ignoreCheckConstraints := -1
var journalMode string
lockingMode := "NORMAL"
queryOnly := -1
recursiveTriggers := -1
secureDelete := "DEFAULT"
synchronousMode := "NORMAL"
writableSchema := -1
vfsName := ""
@ -1251,35 +1250,11 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
journalMode = strings.ToUpper(val)
case "WAL":
journalMode = strings.ToUpper(val)
// For WAL Mode set Synchronous Mode to 'NORMAL'
// See https://www.sqlite.org/pragma.html#pragma_synchronous
synchronousMode = "NORMAL"
default:
return nil, fmt.Errorf("Invalid _journal: %v, expecting value of 'DELETE TRUNCATE PERSIST MEMORY WAL OFF'", val)
}
}
// Locking Mode (_locking)
//
// https://www.sqlite.org/pragma.html#pragma_locking_mode
//
pkey = "" // Reset pkey
if _, ok := params["_locking_mode"]; ok {
pkey = "_locking_mode"
}
if _, ok := params["_locking"]; ok {
pkey = "_locking"
}
if val := params.Get(pkey); val != "" {
switch strings.ToUpper(val) {
case "NORMAL", "EXCLUSIVE":
lockingMode = strings.ToUpper(val)
default:
return nil, fmt.Errorf("Invalid _locking_mode: %v, expecting value of 'NORMAL EXCLUSIVE", val)
}
}
// Query Only (_query_only)
//
// https://www.sqlite.org/pragma.html#pragma_query_only
@ -1334,26 +1309,6 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
}
}
// Synchronous Mode (_synchronous | _sync)
//
// https://www.sqlite.org/pragma.html#pragma_synchronous
//
pkey = "" // Reset pkey
if _, ok := params["_synchronous"]; ok {
pkey = "_synchronous"
}
if _, ok := params["_sync"]; ok {
pkey = "_sync"
}
if val := params.Get(pkey); val != "" {
switch strings.ToUpper(val) {
case "0", "OFF", "1", "NORMAL", "2", "FULL", "3", "EXTRA":
synchronousMode = strings.ToUpper(val)
default:
return nil, fmt.Errorf("Invalid _synchronous: %v, expecting value of '0 OFF 1 NORMAL 2 FULL 3 EXTRA'", val)
}
}
// Writable Schema (_writeable_schema)
//
// https://www.sqlite.org/pragma.html#pragma_writeable_schema
@ -1662,14 +1617,6 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
}
}
// Locking Mode
// Because the default is NORMAL and this is not changed in this package
// by using the compile time SQLITE_DEFAULT_LOCKING_MODE this PRAGMA can always be executed
if err := exec(fmt.Sprintf("PRAGMA locking_mode = %s;", lockingMode)); err != nil {
C.sqlite3_close_v2(db)
return nil, err
}
// Query Only
if queryOnly > -1 {
if err := exec(fmt.Sprintf("PRAGMA query_only = %d;", queryOnly)); err != nil {
@ -1698,14 +1645,6 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
}
}
// Synchronous Mode
//
// Because default is NORMAL this statement is always executed
if err := exec(fmt.Sprintf("PRAGMA synchronous = %s;", synchronousMode)); err != nil {
C.sqlite3_close_v2(db)
return nil, err
}
// Writable Schema
if writableSchema > -1 {
if err := exec(fmt.Sprintf("PRAGMA writable_schema = %d;", writableSchema)); err != nil {

View File

@ -1,21 +1,3 @@
/* fix for MSVC ...evil! */
#ifdef _MSC_VER
#define CONST64(n) n ## ui64
typedef unsigned __int64 ulong64;
#else
#define CONST64(n) n ## ULL
typedef unsigned long long ulong64;
#endif
/* this is the "32-bit at least" data type
* Re-define it to suit your platform but it must be at least 32-bits
*/
#if defined(__x86_64__) || (defined(__sparc__) && defined(__arch64__)) || defined(__arm64__) || defined(__aarch64__)
typedef unsigned ulong32;
#else
typedef unsigned long ulong32;
#endif
/* ---- HELPER MACROS ---- */
#ifdef ENDIAN_NEUTRAL