mirror of
https://gitea.invidious.io/iv-org/shard-crystal-sqlite3.git
synced 2024-08-15 00:53:26 +00:00
Compare commits
4 commits
af8311aae8
...
0876a7b4f9
Author | SHA1 | Date | |
---|---|---|---|
|
0876a7b4f9 | ||
|
c58cea290c | ||
|
1f2a1cd3cb | ||
|
c08fc2befc |
7 changed files with 78 additions and 54 deletions
10
CHANGELOG.md
10
CHANGELOG.md
|
@ -1,3 +1,13 @@
|
||||||
|
## v0.21.0 (2023-12-12)
|
||||||
|
|
||||||
|
* Update to crystal-db ~> 0.13.0. ([#94](https://github.com/crystal-lang/crystal-sqlite3/pull/94))
|
||||||
|
|
||||||
|
## v0.20.0 (2023-06-23)
|
||||||
|
|
||||||
|
* Update to crystal-db ~> 0.12.0. ([#91](https://github.com/crystal-lang/crystal-sqlite3/pull/91))
|
||||||
|
* Fix result set & connection release lifecycle. ([#90](https://github.com/crystal-lang/crystal-sqlite3/pull/90))
|
||||||
|
* Automatically set PRAGMAs using connection query params. ([#85](https://github.com/crystal-lang/crystal-sqlite3/pull/85), thanks @luislavena)
|
||||||
|
|
||||||
## v0.19.0 (2022-01-28)
|
## v0.19.0 (2022-01-28)
|
||||||
|
|
||||||
* Update to crystal-db ~> 0.11.0. ([#77](https://github.com/crystal-lang/crystal-sqlite3/pull/77))
|
* Update to crystal-db ~> 0.11.0. ([#77](https://github.com/crystal-lang/crystal-sqlite3/pull/77))
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
name: sqlite3
|
name: sqlite3
|
||||||
version: 0.19.0
|
version: 0.21.0
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
db:
|
db:
|
||||||
github: crystal-lang/crystal-db
|
github: crystal-lang/crystal-db
|
||||||
version: ~> 0.11.0
|
version: ~> 0.13.0
|
||||||
|
|
||||||
authors:
|
authors:
|
||||||
- Ary Borenszweig <aborenszweig@manas.tech>
|
- Ary Borenszweig <aborenszweig@manas.tech>
|
||||||
- Brian J. Cardiff <bcardiff@manas.tech>
|
- Brian J. Cardiff <bcardiff@gmail.com>
|
||||||
|
|
||||||
crystal: ">= 1.0.0, < 2.0.0"
|
crystal: ">= 1.0.0, < 2.0.0"
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ private def cast_if_blob(expr, sql_type)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
DB::DriverSpecs(DB::Any).run do
|
DB::DriverSpecs(DB::Any).run do |ctx|
|
||||||
support_unprepared false
|
support_unprepared false
|
||||||
|
|
||||||
before do
|
before do
|
||||||
|
@ -104,7 +104,7 @@ DB::DriverSpecs(DB::Any).run do
|
||||||
db.exec %(insert into a (i, str) values (23, "bai bai");)
|
db.exec %(insert into a (i, str) values (23, "bai bai");)
|
||||||
|
|
||||||
2.times do |i|
|
2.times do |i|
|
||||||
DB.open db.uri do |db|
|
DB.open ctx.connection_string do |db|
|
||||||
begin
|
begin
|
||||||
db.query("SELECT i, str FROM a WHERE i = ?", 23) do |rs|
|
db.query("SELECT i, str FROM a WHERE i = ?", 23) do |rs|
|
||||||
rs.move_next
|
rs.move_next
|
||||||
|
|
|
@ -27,7 +27,7 @@ describe Driver do
|
||||||
|
|
||||||
it "should use database option as file to open" do
|
it "should use database option as file to open" do
|
||||||
with_db do |db|
|
with_db do |db|
|
||||||
db.driver.should be_a(SQLite3::Driver)
|
db.checkout.should be_a(SQLite3::Connection)
|
||||||
File.exists?(DB_FILENAME).should be_true
|
File.exists?(DB_FILENAME).should be_true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,12 +1,56 @@
|
||||||
class SQLite3::Connection < DB::Connection
|
class SQLite3::Connection < DB::Connection
|
||||||
def initialize(database)
|
record Options,
|
||||||
super
|
filename : String = ":memory:",
|
||||||
filename = self.class.filename(database.uri)
|
# pragmas
|
||||||
check LibSQLite3.open_v2(filename, out @db, (Flag::READWRITE | Flag::CREATE), nil)
|
busy_timeout : String? = nil,
|
||||||
|
cache_size : String? = nil,
|
||||||
|
foreign_keys : String? = nil,
|
||||||
|
journal_mode : String? = nil,
|
||||||
|
synchronous : String? = nil,
|
||||||
|
wal_autocheckpoint : String? = nil do
|
||||||
|
def self.from_uri(uri : URI, default = Options.new)
|
||||||
|
params = HTTP::Params.parse(uri.query || "")
|
||||||
|
|
||||||
|
Options.new(
|
||||||
|
filename: URI.decode_www_form((uri.host || "") + uri.path),
|
||||||
|
# pragmas
|
||||||
|
busy_timeout: params.fetch("busy_timeout", default.busy_timeout),
|
||||||
|
cache_size: params.fetch("cache_size", default.cache_size),
|
||||||
|
foreign_keys: params.fetch("foreign_keys", default.foreign_keys),
|
||||||
|
journal_mode: params.fetch("journal_mode", default.journal_mode),
|
||||||
|
synchronous: params.fetch("synchronous", default.synchronous),
|
||||||
|
wal_autocheckpoint: params.fetch("wal_autocheckpoint", default.wal_autocheckpoint),
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def pragma_statement
|
||||||
|
res = String.build do |str|
|
||||||
|
pragma_append(str, "busy_timeout", busy_timeout)
|
||||||
|
pragma_append(str, "cache_size", cache_size)
|
||||||
|
pragma_append(str, "foreign_keys", foreign_keys)
|
||||||
|
pragma_append(str, "journal_mode", journal_mode)
|
||||||
|
pragma_append(str, "synchronous", synchronous)
|
||||||
|
pragma_append(str, "wal_autocheckpoint", wal_autocheckpoint)
|
||||||
|
end
|
||||||
|
|
||||||
|
res.empty? ? nil : res
|
||||||
|
end
|
||||||
|
|
||||||
|
private def pragma_append(io, key, value)
|
||||||
|
return unless value
|
||||||
|
io << "PRAGMA #{key}=#{value};"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize(options : ::DB::Connection::Options, sqlite3_options : Options)
|
||||||
|
super(options)
|
||||||
|
check LibSQLite3.open_v2(sqlite3_options.filename, out @db, (Flag::READWRITE | Flag::CREATE), nil)
|
||||||
# 2 means 2 arguments; 1 is the code for UTF-8
|
# 2 means 2 arguments; 1 is the code for UTF-8
|
||||||
check LibSQLite3.create_function(@db, "regexp", 2, 1, nil, SQLite3::REGEXP_FN, nil, nil)
|
check LibSQLite3.create_function(@db, "regexp", 2, 1, nil, SQLite3::REGEXP_FN, nil, nil)
|
||||||
|
|
||||||
process_query_params(database.uri)
|
if pragma_statement = sqlite3_options.pragma_statement
|
||||||
|
check LibSQLite3.exec(@db, pragma_statement, nil, nil, nil)
|
||||||
|
end
|
||||||
rescue
|
rescue
|
||||||
raise DB::ConnectionRefused.new
|
raise DB::ConnectionRefused.new
|
||||||
end
|
end
|
||||||
|
@ -89,44 +133,4 @@ class SQLite3::Connection < DB::Connection
|
||||||
private def check(code)
|
private def check(code)
|
||||||
raise Exception.new(self) unless code == 0
|
raise Exception.new(self) unless code == 0
|
||||||
end
|
end
|
||||||
|
|
||||||
private def process_query_params(uri : URI)
|
|
||||||
return unless query = uri.query
|
|
||||||
|
|
||||||
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|
|
|
||||||
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
|
end
|
||||||
|
|
|
@ -1,6 +1,16 @@
|
||||||
class SQLite3::Driver < DB::Driver
|
class SQLite3::Driver < DB::Driver
|
||||||
def build_connection(context : DB::ConnectionContext) : SQLite3::Connection
|
class ConnectionBuilder < ::DB::ConnectionBuilder
|
||||||
SQLite3::Connection.new(context)
|
def initialize(@options : ::DB::Connection::Options, @sqlite3_options : SQLite3::Connection::Options)
|
||||||
|
end
|
||||||
|
|
||||||
|
def build : ::DB::Connection
|
||||||
|
SQLite3::Connection.new(@options, @sqlite3_options)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def connection_builder(uri : URI) : ::DB::ConnectionBuilder
|
||||||
|
params = HTTP::Params.parse(uri.query || "")
|
||||||
|
ConnectionBuilder.new(connection_options(params), SQLite3::Connection::Options.from_uri(uri))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
module SQLite3
|
module SQLite3
|
||||||
VERSION = "0.19.0"
|
VERSION = "0.21.0"
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue