mirror of
https://gitea.invidious.io/iv-org/shard-crystal-db.git
synced 2024-08-15 00:53:32 +00:00
introduce unprepared statements
* rename QueryMethods#prepare to QueryMethods#build * rename Connection#build_statement to Connection#build_prepared_statement * add Connection#build_unprepared_statement * add Connection #prepared and #unprepared dsl methods
This commit is contained in:
parent
73108c169e
commit
fe0ed55ef9
8 changed files with 118 additions and 39 deletions
|
@ -11,7 +11,7 @@ module DB
|
|||
#
|
||||
# The connection must be initialized in `#initialize` and closed in `#do_close`.
|
||||
#
|
||||
# Override `#build_statement` method in order to return a prepared `Statement` to allow querying.
|
||||
# Override `#build_prepared_statement` method in order to return a prepared `Statement` to allow querying.
|
||||
# See also `Statement` to define how the statements are executed.
|
||||
#
|
||||
# If at any give moment the connection is lost a DB::ConnectionLost should be raised. This will
|
||||
|
@ -29,16 +29,69 @@ module DB
|
|||
end
|
||||
|
||||
# :nodoc:
|
||||
def prepare(query) : Statement
|
||||
@statements_cache.fetch(query) { build_statement(query) }
|
||||
def build(query) : Statement
|
||||
# TODO add flag for default statements kind.
|
||||
# configured in database overridable by connection
|
||||
fetch_or_build_prepared_statement(query)
|
||||
end
|
||||
|
||||
abstract def build_statement(query) : Statement
|
||||
# :nodoc:
|
||||
def fetch_or_build_prepared_statement(query)
|
||||
@statements_cache.fetch(query) { build_prepared_statement(query) }
|
||||
end
|
||||
|
||||
abstract def build_prepared_statement(query) : Statement
|
||||
|
||||
abstract def build_unprepared_statement(query) : Statement
|
||||
|
||||
protected def do_close
|
||||
@statements_cache.each_value &.close
|
||||
@statements_cache.clear
|
||||
@database.pool.delete self
|
||||
end
|
||||
|
||||
# dsl helper to build prepared statements
|
||||
# returns a value that includes `QueryMethods`
|
||||
def prepared
|
||||
PreparedQuery.new(self)
|
||||
end
|
||||
|
||||
# Returns a prepared `Statement` that has not been executed yet.
|
||||
def prepared(query)
|
||||
prepared.build(query)
|
||||
end
|
||||
|
||||
# dsl helper to build unprepared statements
|
||||
# returns a value that includes `QueryMethods`
|
||||
def unprepared
|
||||
UnpreparedQuery.new(self)
|
||||
end
|
||||
|
||||
# Returns an unprepared `Statement` that has not been executed yet.
|
||||
def unprepared(query)
|
||||
unprepared.build(query)
|
||||
end
|
||||
|
||||
struct PreparedQuery
|
||||
include QueryMethods
|
||||
|
||||
def initialize(@connection : Connection)
|
||||
end
|
||||
|
||||
def build(query)
|
||||
@connection.fetch_or_build_prepared_statement(query)
|
||||
end
|
||||
end
|
||||
|
||||
struct UnpreparedQuery
|
||||
include QueryMethods
|
||||
|
||||
def initialize(@connection : Connection)
|
||||
end
|
||||
|
||||
def build(query)
|
||||
@connection.build_unprepared_statement(query)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -59,7 +59,7 @@ module DB
|
|||
end
|
||||
|
||||
# :nodoc:
|
||||
def prepare(query)
|
||||
def build(query)
|
||||
@statements_cache.fetch(query) { PoolStatement.new(self, query) }
|
||||
end
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ module DB
|
|||
clean_connections
|
||||
conn, existing = @db.checkout_some(@connections)
|
||||
@connections << WeakRef.new(conn) unless existing
|
||||
conn.prepare(@query)
|
||||
conn.build(@query)
|
||||
end
|
||||
|
||||
private def clean_connections
|
||||
|
|
|
@ -15,11 +15,11 @@ module DB
|
|||
#
|
||||
# Convention of mapping how arguments are mapped to the query depends on each driver.
|
||||
#
|
||||
# Including `QueryMethods` requires a `prepare(query) : Statement` method that is not expected
|
||||
# Including `QueryMethods` requires a `build(query) : Statement` method that is not expected
|
||||
# to be called directly.
|
||||
module QueryMethods
|
||||
# :nodoc:
|
||||
abstract def prepare(query) : Statement
|
||||
abstract def build(query) : Statement
|
||||
|
||||
# Executes a *query* and returns a `ResultSet` with the results.
|
||||
# The `ResultSet` must be closed manually.
|
||||
|
@ -35,7 +35,7 @@ module DB
|
|||
# end
|
||||
# ```
|
||||
def query(query, *args)
|
||||
prepare(query).query(*args)
|
||||
build(query).query(*args)
|
||||
end
|
||||
|
||||
# Executes a *query* and yields a `ResultSet` with the results.
|
||||
|
@ -49,7 +49,7 @@ module DB
|
|||
# end
|
||||
# ```
|
||||
def query(query, *args)
|
||||
# CHECK prepare(query).query(*args, &block)
|
||||
# CHECK build(query).query(*args, &block)
|
||||
rs = query(query, *args)
|
||||
yield rs ensure rs.close
|
||||
end
|
||||
|
@ -200,13 +200,13 @@ module DB
|
|||
|
||||
# Performs the `query` and returns an `ExecResult`
|
||||
def exec(query, *args)
|
||||
prepare(query).exec(*args)
|
||||
build(query).exec(*args)
|
||||
end
|
||||
|
||||
# Performs the `query` and returns a single scalar value
|
||||
# puts db.scalar("SELECT MAX(name)").as(String) # => (a String)
|
||||
def scalar(query, *args)
|
||||
prepare(query).scalar(*args)
|
||||
build(query).scalar(*args)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue