@@ -334,7 +334,12 @@ func (j JournalMode) String() string {
334
334
}
335
335
336
336
const (
337
- // JournalModeDelete is the normal behavior.
337
+ // JournalModeAuto is the journal mode in which the Journal is not explicitly set.
338
+ // This means that if any other program or connection already has set the journal mode
339
+ // the journal mode is automatically read from the database and not forcibly set.
340
+ JournalModeAuto = JournalMode ("AUTO" )
341
+
342
+ // JournalModeDelete is the normal behavior.
338
343
// In the DELETE mode, the rollback journal is deleted at the conclusion
339
344
// of each transaction.
340
345
// Indeed, the delete operation is the action that causes the transaction to commit.
@@ -585,7 +590,7 @@ func NewConfig() *Config {
585
590
DeferForeignKeys : false ,
586
591
ForeignKeyConstraints : false ,
587
592
IgnoreCheckConstraints : false ,
588
- JournalMode : JournalModeDelete ,
593
+ JournalMode : JournalModeAuto ,
589
594
QueryOnly : false ,
590
595
RecursiveTriggers : false ,
591
596
SecureDelete : SecureDeleteOff ,
@@ -597,121 +602,6 @@ func NewConfig() *Config {
597
602
}
598
603
}
599
604
600
- // FormatDSN formats the given Config into a DSN string which can be passed to
601
- // the driver.
602
- func (cfg * Config ) FormatDSN () string {
603
- var buf bytes.Buffer
604
-
605
- params := url.Values {}
606
- if len (cfg .Cache .String ()) > 0 {
607
- params .Set ("cache" , cfg .Cache .String ())
608
- }
609
-
610
- if len (cfg .Mode .String ()) > 0 {
611
- params .Set ("mode" , cfg .Mode .String ())
612
- }
613
-
614
- if len (cfg .Mutex .String ()) > 0 {
615
- params .Set ("mutex" , cfg .Mutex .String ())
616
- }
617
-
618
- if cfg .Immutable {
619
- params .Set ("immutable" , "true" )
620
- }
621
-
622
- if cfg .TimeZone != nil {
623
- if cfg .TimeZone == time .Local {
624
- params .Set ("tz" , "auto" )
625
- } else {
626
- params .Set ("tz" , cfg .TimeZone .String ())
627
- }
628
- }
629
-
630
- if cfg .BusyTimeout > 0 {
631
- params .Set ("timeout" , cfg .BusyTimeout .String ())
632
- }
633
-
634
- if len (cfg .TransactionLock .String ()) > 0 && cfg .TransactionLock != TxLockDeferred {
635
- params .Set ("txlock" , cfg .TransactionLock .String ())
636
- }
637
-
638
- if len (cfg .LockingMode ) > 0 && cfg .LockingMode != LockingModeNormal {
639
- params .Set ("lock" , cfg .LockingMode .String ())
640
- }
641
-
642
- if len (cfg .AutoVacuum ) > 0 && cfg .AutoVacuum != AutoVacuumNone {
643
- params .Set ("vacuum" , cfg .AutoVacuum .String ())
644
- }
645
-
646
- if cfg .CaseSensitiveLike {
647
- params .Set ("cslike" , "true" )
648
- }
649
-
650
- if cfg .DeferForeignKeys {
651
- params .Set ("defer_fk" , "true" )
652
- }
653
-
654
- if cfg .ForeignKeyConstraints {
655
- params .Set ("fk" , "true" )
656
- }
657
-
658
- if cfg .IgnoreCheckConstraints {
659
- params .Set ("ignore_check_contraints" , "true" )
660
- }
661
-
662
- if len (cfg .JournalMode ) > 0 && cfg .JournalMode != JournalModeDelete {
663
- params .Set ("journal" , cfg .JournalMode .String ())
664
- }
665
-
666
- if cfg .QueryOnly {
667
- params .Set ("query_only" , "true" )
668
- }
669
-
670
- if cfg .RecursiveTriggers {
671
- params .Set ("recursive_triggers" , "true" )
672
- }
673
-
674
- if len (cfg .SecureDelete ) > 0 && cfg .SecureDelete != SecureDeleteOff {
675
- params .Set ("secure_delete" , cfg .SecureDelete .String ())
676
- }
677
-
678
- if len (cfg .Synchronous ) > 0 && cfg .Synchronous != SynchronousNormal {
679
- params .Set ("sync" , cfg .Synchronous .String ())
680
- }
681
-
682
- if cfg .WriteableSchema {
683
- params .Set ("writable_schema" , "true" )
684
- }
685
-
686
- if cfg .Authentication != nil {
687
- if len (cfg .Authentication .Username ) > 0 && len (cfg .Authentication .Password ) > 0 {
688
- params .Set ("user" , cfg .Authentication .Username )
689
- params .Set ("pass" , cfg .Authentication .Password )
690
-
691
- if len (cfg .Authentication .Salt ) > 0 {
692
- params .Set ("salt" , cfg .Authentication .Salt )
693
- }
694
-
695
- if cfg .Authentication .Encoder != nil {
696
- params .Set ("crypt" , cfg .Authentication .Encoder .String ())
697
- }
698
- }
699
- }
700
-
701
- if ! strings .HasPrefix (cfg .Database , "file:" ) {
702
- buf .WriteString ("file:" )
703
- }
704
- buf .WriteString (cfg .Database )
705
-
706
- // Append Options
707
- if len (params ) > 0 {
708
- buf .WriteRune ('?' )
709
- buf .WriteString (params .Encode ())
710
- }
711
-
712
- return buf .String ()
713
- }
714
-
715
605
// Create connection from Configuration
716
606
func (cfg * Config ) createConnection () (driver.Conn , error ) {
717
607
if C .sqlite3_threadsafe () == 0 {
@@ -933,9 +823,11 @@ func (cfg *Config) createConnection() (driver.Conn, error) {
933
823
}
934
824
935
825
// Journal Mode
936
- if err := conn .PRAGMA (PRAGMA_JOURNAL_MODE , cfg .JournalMode .String ()); err != nil {
937
- C .sqlite3_close_v2 (db )
938
- return nil , err
826
+ if cfg .JournalMode != JournalModeAuto {
827
+ if err := conn .PRAGMA (PRAGMA_JOURNAL_MODE , cfg .JournalMode .String ()); err != nil {
828
+ C .sqlite3_close_v2 (db )
829
+ return nil , err
830
+ }
939
831
}
940
832
941
833
// Locking Mode
@@ -1242,6 +1134,8 @@ func ParseDSN(dsn string) (cfg *Config, err error) {
1242
1134
// For WAL Mode set Synchronous Mode to 'NORMAL'
1243
1135
// See https://www.sqlite.org/pragma.html#pragma_synchronous
1244
1136
cfg .Synchronous = SynchronousNormal
1137
+ case "AUTO" :
1138
+ cfg .JournalMode = JournalModeAuto
1245
1139
default :
1246
1140
return nil , fmt .Errorf ("invalid journal: %v, expecting value of 'DELETE TRUNCATE PERSIST MEMORY WAL OFF'" , val )
1247
1141
}
@@ -1318,6 +1212,125 @@ func ParseDSN(dsn string) (cfg *Config, err error) {
1318
1212
return cfg , nil
1319
1213
}
1320
1214
1215
+ // FormatDSN formats the given Config into a DSN string which can be passed to
1216
+ // the driver.
1217
+ func (cfg * Config ) FormatDSN () string {
1218
+ var buf bytes.Buffer
1219
+
1220
+ params := url.Values {}
1221
+ if len (cfg .Key ) > 0 {
1222
+ params .Set ("key" , cfg .Key )
1223
+ }
1224
+
1225
+ if len (cfg .Cache .String ()) > 0 {
1226
+ params .Set ("cache" , cfg .Cache .String ())
1227
+ }
1228
+
1229
+ if len (cfg .Mode .String ()) > 0 {
1230
+ params .Set ("mode" , cfg .Mode .String ())
1231
+ }
1232
+
1233
+ if len (cfg .Mutex .String ()) > 0 {
1234
+ params .Set ("mutex" , cfg .Mutex .String ())
1235
+ }
1236
+
1237
+ if cfg .Immutable {
1238
+ params .Set ("immutable" , "true" )
1239
+ }
1240
+
1241
+ if cfg .TimeZone != nil {
1242
+ if cfg .TimeZone == time .Local {
1243
+ params .Set ("tz" , "auto" )
1244
+ } else {
1245
+ params .Set ("tz" , cfg .TimeZone .String ())
1246
+ }
1247
+ }
1248
+
1249
+ if cfg .BusyTimeout > 0 {
1250
+ params .Set ("timeout" , cfg .BusyTimeout .String ())
1251
+ }
1252
+
1253
+ if len (cfg .TransactionLock .String ()) > 0 && cfg .TransactionLock != TxLockDeferred {
1254
+ params .Set ("txlock" , cfg .TransactionLock .String ())
1255
+ }
1256
+
1257
+ if len (cfg .LockingMode ) > 0 && cfg .LockingMode != LockingModeNormal {
1258
+ params .Set ("lock" , cfg .LockingMode .String ())
1259
+ }
1260
+
1261
+ if len (cfg .AutoVacuum ) > 0 && cfg .AutoVacuum != AutoVacuumNone {
1262
+ params .Set ("vacuum" , cfg .AutoVacuum .String ())
1263
+ }
1264
+
1265
+ if cfg .CaseSensitiveLike {
1266
+ params .Set ("cslike" , "true" )
1267
+ }
1268
+
1269
+ if cfg .DeferForeignKeys {
1270
+ params .Set ("defer_fk" , "true" )
1271
+ }
1272
+
1273
+ if cfg .ForeignKeyConstraints {
1274
+ params .Set ("fk" , "true" )
1275
+ }
1276
+
1277
+ if cfg .IgnoreCheckConstraints {
1278
+ params .Set ("ignore_check_contraints" , "true" )
1279
+ }
1280
+
1281
+ if len (cfg .JournalMode ) > 0 && cfg .JournalMode != JournalModeDelete {
1282
+ params .Set ("journal" , cfg .JournalMode .String ())
1283
+ }
1284
+
1285
+ if cfg .QueryOnly {
1286
+ params .Set ("query_only" , "true" )
1287
+ }
1288
+
1289
+ if cfg .RecursiveTriggers {
1290
+ params .Set ("recursive_triggers" , "true" )
1291
+ }
1292
+
1293
+ if len (cfg .SecureDelete ) > 0 && cfg .SecureDelete != SecureDeleteOff {
1294
+ params .Set ("secure_delete" , cfg .SecureDelete .String ())
1295
+ }
1296
+
1297
+ if len (cfg .Synchronous ) > 0 && cfg .Synchronous != SynchronousNormal {
1298
+ params .Set ("sync" , cfg .Synchronous .String ())
1299
+ }
1300
+
1301
+ if cfg .WriteableSchema {
1302
+ params .Set ("writable_schema" , "true" )
1303
+ }
1304
+
1305
+ if cfg .Authentication != nil {
1306
+ if len (cfg .Authentication .Username ) > 0 && len (cfg .Authentication .Password ) > 0 {
1307
+ params .Set ("user" , cfg .Authentication .Username )
1308
+ params .Set ("pass" , cfg .Authentication .Password )
1309
+
1310
+ if len (cfg .Authentication .Salt ) > 0 {
1311
+ params .Set ("salt" , cfg .Authentication .Salt )
1312
+ }
1313
+
1314
+ if cfg .Authentication .Encoder != nil {
1315
+ params .Set ("crypt" , cfg .Authentication .Encoder .String ())
1316
+ }
1317
+ }
1318
+ }
1319
+
1320
+ if ! strings .HasPrefix (cfg .Database , "file:" ) {
1321
+ buf .WriteString ("file:" )
1322
+ }
1323
+ buf .WriteString (cfg .Database )
1324
+
1325
+ // Append Options
1326
+ if len (params ) > 0 {
1327
+ buf .WriteRune ('?' )
1328
+ buf .WriteString (params .Encode ())
1329
+ }
1330
+
1331
+ return buf .String ()
1332
+ }
1333
+
1321
1334
func normalizeParams (params url.Values ) {
1322
1335
for k , v := range params {
1323
1336
params [strings .ToLower (k )] = v
0 commit comments