diff --git a/README.md b/README.md index 6086f06..99c9b41 100644 --- a/README.md +++ b/README.md @@ -67,12 +67,12 @@ The following is the list of supported options: | Name | Connection key | |---------------------------|-----------------| -| [Busy Timeout][pragma-to] | `_busy_timeout` | -| [Cache Size][pragma-cs] | `_cache_size` | -| [Foreign Keys][pragma-fk] | `_foreign_keys` | -| [Journal Mode][pragma-jm] | `_journal_mode` | -| [Synchronous][pragma-sync] | `_synchronous` | -| [WAL autocheckoint][pragma-walck] | `_wal_autocheckpoint` | +| [Busy Timeout][pragma-to] | `busy_timeout` | +| [Cache Size][pragma-cs] | `cache_size` | +| [Foreign Keys][pragma-fk] | `foreign_keys` | +| [Journal Mode][pragma-jm] | `journal_mode` | +| [Synchronous][pragma-sync] | `synchronous` | +| [WAL autocheckoint][pragma-walck] | `wal_autocheckpoint` | Please note there values passed using these connection keys are passed directly to SQLite3 without check or evaluation. Using incorrect values result diff --git a/spec/connection_spec.cr b/spec/connection_spec.cr index 0eabc13..84e9759 100644 --- a/spec/connection_spec.cr +++ b/spec/connection_spec.cr @@ -10,9 +10,9 @@ private def dump(source, target) end end -private def it_sets_pragma_on_connection(pragma : String, option : String, value : String, expected, file = __FILE__, line = __LINE__) - it "sets pragma '#{pragma}' to #{expected} using '#{option}'", file, line do - with_db("#{DB_FILENAME}?#{option}=#{value}") do |db| +private def it_sets_pragma_on_connection(pragma : String, value : String, expected, file = __FILE__, line = __LINE__) + it "sets pragma '#{pragma}' to #{expected}", file, line do + with_db("#{DB_FILENAME}?#{pragma}=#{value}") do |db| db.scalar("PRAGMA #{pragma}").should eq(expected) end end @@ -78,32 +78,32 @@ describe Connection do end # adjust busy_timeout pragma (default is 0) - it_sets_pragma_on_connection "busy_timeout", "_busy_timeout", "1000", 1000 + it_sets_pragma_on_connection "busy_timeout", "1000", 1000 # adjust cache_size pragma (default is -2000, 2MB) - it_sets_pragma_on_connection "cache_size", "_cache_size", "-4000", -4000 + it_sets_pragma_on_connection "cache_size", "-4000", -4000 # enable foreign_keys, no need to test off (is the default) - it_sets_pragma_on_connection "foreign_keys", "_foreign_keys", "1", 1 - it_sets_pragma_on_connection "foreign_keys", "_foreign_keys", "yes", 1 - it_sets_pragma_on_connection "foreign_keys", "_foreign_keys", "true", 1 - it_sets_pragma_on_connection "foreign_keys", "_foreign_keys", "on", 1 + it_sets_pragma_on_connection "foreign_keys", "1", 1 + it_sets_pragma_on_connection "foreign_keys", "yes", 1 + it_sets_pragma_on_connection "foreign_keys", "true", 1 + it_sets_pragma_on_connection "foreign_keys", "on", 1 # change journal_mode (default is delete) - it_sets_pragma_on_connection "journal_mode", "_journal_mode", "delete", "delete" - it_sets_pragma_on_connection "journal_mode", "_journal_mode", "truncate", "truncate" - it_sets_pragma_on_connection "journal_mode", "_journal_mode", "persist", "persist" + it_sets_pragma_on_connection "journal_mode", "delete", "delete" + it_sets_pragma_on_connection "journal_mode", "truncate", "truncate" + it_sets_pragma_on_connection "journal_mode", "persist", "persist" # change synchronous mode (default is 2, FULL) - it_sets_pragma_on_connection "synchronous", "_synchronous", "0", 0 - it_sets_pragma_on_connection "synchronous", "_synchronous", "off", 0 - it_sets_pragma_on_connection "synchronous", "_synchronous", "1", 1 - it_sets_pragma_on_connection "synchronous", "_synchronous", "normal", 1 - it_sets_pragma_on_connection "synchronous", "_synchronous", "2", 2 - it_sets_pragma_on_connection "synchronous", "_synchronous", "full", 2 - it_sets_pragma_on_connection "synchronous", "_synchronous", "3", 3 - it_sets_pragma_on_connection "synchronous", "_synchronous", "extra", 3 + it_sets_pragma_on_connection "synchronous", "0", 0 + it_sets_pragma_on_connection "synchronous", "off", 0 + it_sets_pragma_on_connection "synchronous", "1", 1 + it_sets_pragma_on_connection "synchronous", "normal", 1 + it_sets_pragma_on_connection "synchronous", "2", 2 + it_sets_pragma_on_connection "synchronous", "full", 2 + it_sets_pragma_on_connection "synchronous", "3", 3 + it_sets_pragma_on_connection "synchronous", "extra", 3 # change wal_autocheckpoint (default is 1000) - it_sets_pragma_on_connection "wal_autocheckpoint", "_wal_autocheckpoint", "0", 0 + it_sets_pragma_on_connection "wal_autocheckpoint", "0", 0 end diff --git a/src/sqlite3/connection.cr b/src/sqlite3/connection.cr index ec07224..3979120 100644 --- a/src/sqlite3/connection.cr +++ b/src/sqlite3/connection.cr @@ -93,32 +93,40 @@ class SQLite3::Connection < DB::Connection private def process_query_params(uri : URI) return unless query = uri.query - pragmas = Hash(String, String).new - - URI::Params.parse(query) do |key, value| - case key - when "_busy_timeout" - pragmas["busy_timeout"] = value - when "_cache_size" - pragmas["cache_size"] = value - when "_foreign_keys" - pragmas["foreign_keys"] = value - when "_journal_mode" - pragmas["journal_mode"] = value - when "_synchronous" - pragmas["synchronous"] = value - when "_wal_autocheckpoint" - pragmas["wal_autocheckpoint"] = value - end - end + detected_pragmas = extract_params(query, + busy_timeout: nil, + cache_size: nil, + foreign_keys: nil, + journal_mode: nil, + synchronous: nil, + wal_autocheckpoint: nil, + ) # concatenate all into a single SQL string sql = String.build do |str| - pragmas.each do |key, value| + detected_pragmas.each do |key, value| + next unless value str << "PRAGMA #{key}=#{value};" end end check LibSQLite3.exec(@db, sql, nil, nil, nil) end + + private def extract_params(query : String, **default : **T) forall T + res = default + + URI::Params.parse(query) do |key, value| + {% begin %} + case key + {% for key in T %} + when {{ key.stringify }} + res = res.merge({{key.id}}: value) + {% end %} + end + {% end %} + end + + res + end end