diff --git a/README.md b/README.md
index 82b43f8..6e6abe7 100644
--- a/README.md
+++ b/README.md
@@ -89,6 +89,7 @@ Boolean values can be one of:
| Recursive Triggers | `_recursive_triggers` \| `_rt` | `boolean` | For more information see [PRAGMA recursive_triggers](https://www.sqlite.org/pragma.html#pragma_recursive_triggers) |
| Secure Delete | `_secure_delete` | `boolean` \| `FAST` | For more information see [PRAGMA secure_delete](https://www.sqlite.org/pragma.html#pragma_secure_delete) |
| Shared-Cache Mode | `cache` |
| Set cache mode for more information see [sqlite.org](https://www.sqlite.org/sharedcache.html) |
+| Synchronous | `_synchronous` \| `_sync` | - 0 \| OFF
- 1 \| NORMAL
- 2 \| FULL
- 3 \| EXTRA
| For more information see [PRAGMA synchronous](https://www.sqlite.org/pragma.html#pragma_synchronous) |
| Time Zone Location | `_loc` | auto | Specify location of time format. |
| Transaction Lock | `_txlock` | - immediate
- deferred
- exclusive
| Specify locking behavior for transactions. |
diff --git a/sqlite3.go b/sqlite3.go
index 5783581..0ffdb8f 100644
--- a/sqlite3.go
+++ b/sqlite3.go
@@ -866,6 +866,10 @@ func errorString(err Error) string {
// 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
+//
// _vacuum=X
// 0 | none - Auto Vacuum disabled
// 1 | full - Auto Vacuum FULL
@@ -894,6 +898,7 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
queryOnly := -1
recursiveTriggers := -1
secureDelete := "DEFAULT"
+ synchronousMode := "NORMAL"
pos := strings.IndexRune(dsn, '?')
if pos >= 1 {
@@ -1057,8 +1062,14 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
//
if val := params.Get("_journal"); val != "" {
switch strings.ToUpper(val) {
- case "DELETE", "TRUNCATE", "PERSIST", "MEMORY", "WAL", "OFF":
+ case "DELETE", "TRUNCATE", "PERSIST", "MEMORY", "OFF":
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)
}
@@ -1131,6 +1142,26 @@ 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)
+ }
+ }
+
if !strings.HasPrefix(dsn, "file:") {
dsn = dsn[:pos]
}
@@ -1248,6 +1279,14 @@ 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
+ }
+
conn := &SQLiteConn{db: db, loc: loc, txlock: txlock}
if len(d.Extensions) > 0 {