mirror of
https://gitea.invidious.io/iv-org/shard-crystal-db.git
synced 2024-08-15 00:53:32 +00:00
add ResultSet#read_object
This commit is contained in:
parent
312609b722
commit
5b23114095
2 changed files with 45 additions and 11 deletions
|
@ -26,16 +26,30 @@ class GenericResultSet(T) < DB::ResultSet
|
||||||
{% for t in DB::TYPES %}
|
{% for t in DB::TYPES %}
|
||||||
# Reads the next column as a nillable {{t}}.
|
# Reads the next column as a nillable {{t}}.
|
||||||
def read?(t : {{t}}.class) : {{t}}?
|
def read?(t : {{t}}.class) : {{t}}?
|
||||||
@index += 1
|
read_object as {{t}}?
|
||||||
@row[@index - 1] as {{t}}?
|
|
||||||
end
|
end
|
||||||
{% end %}
|
{% end %}
|
||||||
|
|
||||||
|
def read_object
|
||||||
|
@index += 1
|
||||||
|
@row[@index - 1]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class FooValue
|
||||||
|
def initialize(@value : Int32)
|
||||||
|
end
|
||||||
|
|
||||||
|
def value
|
||||||
|
@value
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class FooDriver < DB::Driver
|
class FooDriver < DB::Driver
|
||||||
@@row = [] of DB::Any
|
alias Any = DB::Any | FooValue
|
||||||
|
@@row = [] of Any
|
||||||
|
|
||||||
def self.fake_row=(row : Array(DB::Any))
|
def self.fake_row=(row : Array(Any))
|
||||||
@@row = row
|
@@row = row
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -55,7 +69,7 @@ class FooDriver < DB::Driver
|
||||||
|
|
||||||
class FooStatement < DB::Statement
|
class FooStatement < DB::Statement
|
||||||
protected def perform_query(args : Slice(DB::Any)) : DB::ResultSet
|
protected def perform_query(args : Slice(DB::Any)) : DB::ResultSet
|
||||||
GenericResultSet(DB::Any).new(self, FooDriver.fake_row)
|
GenericResultSet(Any).new(self, FooDriver.fake_row)
|
||||||
end
|
end
|
||||||
|
|
||||||
protected def perform_exec(args : Slice(DB::Any)) : DB::ExecResult
|
protected def perform_exec(args : Slice(DB::Any)) : DB::ExecResult
|
||||||
|
@ -66,10 +80,18 @@ end
|
||||||
|
|
||||||
DB.register_driver "foo", FooDriver
|
DB.register_driver "foo", FooDriver
|
||||||
|
|
||||||
class BarDriver < DB::Driver
|
class BarValue
|
||||||
@@row = [] of DB::Any
|
getter value
|
||||||
|
|
||||||
def self.fake_row=(row : Array(DB::Any))
|
def initialize(@value : Int32)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class BarDriver < DB::Driver
|
||||||
|
alias Any = DB::Any | BarValue
|
||||||
|
@@row = [] of Any
|
||||||
|
|
||||||
|
def self.fake_row=(row : Array(Any))
|
||||||
@@row = row
|
@@row = row
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -89,7 +111,7 @@ class BarDriver < DB::Driver
|
||||||
|
|
||||||
class BarStatement < DB::Statement
|
class BarStatement < DB::Statement
|
||||||
protected def perform_query(args : Slice(DB::Any)) : DB::ResultSet
|
protected def perform_query(args : Slice(DB::Any)) : DB::ResultSet
|
||||||
GenericResultSet(DB::Any).new(self, BarDriver.fake_row)
|
GenericResultSet(Any).new(self, BarDriver.fake_row)
|
||||||
end
|
end
|
||||||
|
|
||||||
protected def perform_exec(args : Slice(DB::Any)) : DB::ExecResult
|
protected def perform_exec(args : Slice(DB::Any)) : DB::ExecResult
|
||||||
|
@ -109,22 +131,26 @@ describe DB do
|
||||||
it "Foo and Bar drivers should return fake_row" do
|
it "Foo and Bar drivers should return fake_row" do
|
||||||
with_witness do |w|
|
with_witness do |w|
|
||||||
DB.open("foo://host") do |db|
|
DB.open("foo://host") do |db|
|
||||||
FooDriver.fake_row = [1, "string"] of DB::Any
|
# TODO somehow FooValue.new(99) is needed otherwise the read_object assertion fail
|
||||||
|
FooDriver.fake_row = [1, "string", FooValue.new(3), FooValue.new(99)] of FooDriver::Any
|
||||||
db.query "query" do |rs|
|
db.query "query" do |rs|
|
||||||
w.check
|
w.check
|
||||||
rs.move_next
|
rs.move_next
|
||||||
rs.read?(Int32).should eq(1)
|
rs.read?(Int32).should eq(1)
|
||||||
rs.read?(String).should eq("string")
|
rs.read?(String).should eq("string")
|
||||||
|
(rs.read_object.as(FooValue)).value.should eq(3)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
with_witness do |w|
|
with_witness do |w|
|
||||||
DB.open("bar://host") do |db|
|
DB.open("bar://host") do |db|
|
||||||
BarDriver.fake_row = ["lorem", 1.0] of DB::Any
|
# TODO somehow BarValue.new(99) is needed otherwise the read_object assertion fail
|
||||||
|
BarDriver.fake_row = [BarValue.new(4), "lorem", 1.0, BarValue.new(99)] of BarDriver::Any
|
||||||
db.query "query" do |rs|
|
db.query "query" do |rs|
|
||||||
w.check
|
w.check
|
||||||
rs.move_next
|
rs.move_next
|
||||||
|
(rs.read_object.as(BarValue)).value.should eq(4)
|
||||||
rs.read?(String).should eq("lorem")
|
rs.read?(String).should eq("lorem")
|
||||||
rs.read?(Float64).should eq(1.0)
|
rs.read?(Float64).should eq(1.0)
|
||||||
end
|
end
|
||||||
|
|
|
@ -20,6 +20,10 @@ module DB
|
||||||
# 3. (Optional) Override `#read(t)` for all `t` in `DB::TYPES`.
|
# 3. (Optional) Override `#read(t)` for all `t` in `DB::TYPES`.
|
||||||
# 4. Override `#column_count`, `#column_name`.
|
# 4. Override `#column_count`, `#column_name`.
|
||||||
# 5. Override `#column_type`. It must return a type in `DB::TYPES`.
|
# 5. Override `#column_type`. It must return a type in `DB::TYPES`.
|
||||||
|
# 6. Override `#read_object` to return other data types not included in `DB::TYPES`. This
|
||||||
|
# will create a union type, so user will be forced to cast result type. Usually `#read`
|
||||||
|
# should be used to avoid unnecesary intermediate union type values. Calling `#read_object`
|
||||||
|
# should also move to the next column.
|
||||||
abstract class ResultSet
|
abstract class ResultSet
|
||||||
include Disposable
|
include Disposable
|
||||||
|
|
||||||
|
@ -77,6 +81,10 @@ module DB
|
||||||
read?(Nil)
|
read?(Nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def read_object
|
||||||
|
raise "Not implemented"
|
||||||
|
end
|
||||||
|
|
||||||
# def read_blob
|
# def read_blob
|
||||||
# yield ... io ....
|
# yield ... io ....
|
||||||
# end
|
# end
|
||||||
|
|
Loading…
Reference in a new issue