mirror of
https://gitea.invidious.io/iv-org/shard-crystal-db.git
synced 2024-08-15 00:53:32 +00:00
Require ResultSet to just implement read
, optionally implementing read(T.class)
. Fixes #5
This commit is contained in:
parent
038ffef33a
commit
9c88f718e8
8 changed files with 329 additions and 96 deletions
|
@ -16,18 +16,7 @@ module GenericResultSet
|
|||
index.to_s
|
||||
end
|
||||
|
||||
def column_type(index : Int32)
|
||||
@row[index].class
|
||||
end
|
||||
|
||||
{% for t in DB::TYPES %}
|
||||
# Reads the next column as a nillable {{t}}.
|
||||
def read?(t : {{t}}.class) : {{t}}?
|
||||
read_and_move_next_column as {{t}}?
|
||||
end
|
||||
{% end %}
|
||||
|
||||
def read_and_move_next_column
|
||||
def read
|
||||
@index += 1
|
||||
@row[@index - 1]
|
||||
end
|
||||
|
@ -89,10 +78,6 @@ class FooDriver < DB::Driver
|
|||
def initialize(statement, @row : Array(FooDriver::Any))
|
||||
super(statement)
|
||||
end
|
||||
|
||||
def read?(t : FooValue.class) : FooValue?
|
||||
read_and_move_next_column.as(FooValue?)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -152,10 +137,6 @@ class BarDriver < DB::Driver
|
|||
def initialize(statement, @row : Array(BarDriver::Any))
|
||||
super(statement)
|
||||
end
|
||||
|
||||
def read?(t : BarValue.class) : BarValue?
|
||||
read_and_move_next_column.as(BarValue?)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -174,8 +155,8 @@ describe DB do
|
|||
db.query "query" do |rs|
|
||||
w.check
|
||||
rs.move_next
|
||||
rs.read?(Int32).should eq(1)
|
||||
rs.read?(String).should eq("string")
|
||||
rs.read(Int32).should eq(1)
|
||||
rs.read(String).should eq("string")
|
||||
rs.read(FooValue).value.should eq(3)
|
||||
end
|
||||
end
|
||||
|
@ -188,8 +169,8 @@ describe DB do
|
|||
w.check
|
||||
rs.move_next
|
||||
rs.read(BarValue).value.should eq(4)
|
||||
rs.read?(String).should eq("lorem")
|
||||
rs.read?(Float64).should eq(1.0)
|
||||
rs.read(String).should eq("lorem")
|
||||
rs.read(Float64).should eq(1.0)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -208,7 +189,7 @@ describe DB do
|
|||
FooDriver.fake_row = [1] of FooDriver::Any
|
||||
db.query "query" do |rs|
|
||||
rs.move_next
|
||||
expect_raises Exception, "read?(t : BarValue) is not implemented in FooDriver::FooResultSet" do
|
||||
expect_raises(TypeCastError) do
|
||||
w.check
|
||||
rs.read(BarValue)
|
||||
end
|
||||
|
@ -221,7 +202,7 @@ describe DB do
|
|||
BarDriver.fake_row = [1] of BarDriver::Any
|
||||
db.query "query" do |rs|
|
||||
rs.move_next
|
||||
expect_raises Exception, "read?(t : FooValue) is not implemented in BarDriver::BarResultSet" do
|
||||
expect_raises(TypeCastError) do
|
||||
w.check
|
||||
rs.read(FooValue)
|
||||
end
|
||||
|
|
|
@ -73,12 +73,10 @@ class DummyDriver < DB::Driver
|
|||
end
|
||||
|
||||
class DummyResultSet < DB::ResultSet
|
||||
@@next_column_type = String
|
||||
@top_values : Array(Array(String))
|
||||
@values : Array(String)?
|
||||
|
||||
@@last_result_set : self?
|
||||
@@next_column_type : Nil.class | String.class | Int32.class | Int64.class | Float32.class | Float64.class | Bytes.class
|
||||
|
||||
def initialize(statement, query)
|
||||
super(statement)
|
||||
|
@ -108,15 +106,7 @@ class DummyDriver < DB::Driver
|
|||
"c#{index}"
|
||||
end
|
||||
|
||||
def column_type(index : Int32)
|
||||
@@next_column_type
|
||||
end
|
||||
|
||||
def self.next_column_type=(value)
|
||||
@@next_column_type = value
|
||||
end
|
||||
|
||||
private def read? : DB::Any?
|
||||
def read
|
||||
n = @values.not_nil!.shift?
|
||||
raise "end of row" if n.is_a?(Nil)
|
||||
return nil if n == "NULL"
|
||||
|
@ -128,38 +118,36 @@ class DummyDriver < DB::Driver
|
|||
return n
|
||||
end
|
||||
|
||||
def read?(t : Nil.class)
|
||||
read?.as(Nil)
|
||||
def read(t : String.class)
|
||||
read.to_s
|
||||
end
|
||||
|
||||
def read?(t : String.class)
|
||||
read?.try &.to_s
|
||||
def read(t : String?.class)
|
||||
read.try &.to_s
|
||||
end
|
||||
|
||||
def read?(t : Int32.class)
|
||||
read?(String).try &.to_i32
|
||||
def read(t : Int32.class)
|
||||
read(String).to_i32
|
||||
end
|
||||
|
||||
def read?(t : Int64.class)
|
||||
read?(String).try &.to_i64
|
||||
def read(t : Int64.class)
|
||||
read(String).to_i64
|
||||
end
|
||||
|
||||
def read?(t : Float32.class)
|
||||
read?(String).try &.to_f32
|
||||
def read(t : Float32.class)
|
||||
read(String).to_f32
|
||||
end
|
||||
|
||||
def read?(t : Float64.class)
|
||||
read?(String).try &.to_f64
|
||||
def read(t : Float64.class)
|
||||
read(String).to_f64
|
||||
end
|
||||
|
||||
def read?(t : Bytes.class)
|
||||
value = read?
|
||||
if value.is_a?(Nil)
|
||||
value
|
||||
elsif value.is_a?(String)
|
||||
def read(t : Bytes.class)
|
||||
case value = read
|
||||
when String
|
||||
ary = value.bytes
|
||||
Slice.new(ary.to_unsafe, ary.size)
|
||||
elsif value.is_a?(Bytes)
|
||||
when Bytes
|
||||
value
|
||||
else
|
||||
raise "#{value} is not convertible to Bytes"
|
||||
|
|
|
@ -74,11 +74,11 @@ describe DummyDriver do
|
|||
with_dummy do |db|
|
||||
db.query "a,NULL 1,NULL" do |rs|
|
||||
rs.move_next
|
||||
rs.read?(String).should eq("a")
|
||||
rs.read?(String).should be_nil
|
||||
rs.read(String).should eq("a")
|
||||
rs.read(String | Nil).should be_nil
|
||||
rs.move_next
|
||||
rs.read?(Int64).should eq(1)
|
||||
rs.read?(Int64).should be_nil
|
||||
rs.read(Int64).should eq(1)
|
||||
rs.read(Int64 | Nil).should be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -96,6 +96,116 @@ describe DummyDriver do
|
|||
end
|
||||
end
|
||||
|
||||
describe "query one" do
|
||||
it "queries" do
|
||||
with_dummy do |db|
|
||||
db.query_one("3,4", &.read(Int64, Int64)).should eq({3i64, 4i64})
|
||||
end
|
||||
end
|
||||
|
||||
it "raises if more than one row" do
|
||||
with_dummy do |db|
|
||||
expect_raises(DB::Error, "more than one row") do
|
||||
db.query_one("3,4 5,6") { }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "raises if no rows" do
|
||||
with_dummy do |db|
|
||||
expect_raises(DB::Error, "no rows") do
|
||||
db.query_one("") { }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "with as" do
|
||||
with_dummy do |db|
|
||||
db.query_one("3,4", as: {Int64, Int64}).should eq({3i64, 4i64})
|
||||
end
|
||||
end
|
||||
|
||||
it "with as, just one" do
|
||||
with_dummy do |db|
|
||||
db.query_one("3", as: Int64).should eq(3i64)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "query one?" do
|
||||
it "queries" do
|
||||
with_dummy do |db|
|
||||
value = db.query_one?("3,4", &.read(Int64, Int64))
|
||||
value.should eq({3i64, 4i64})
|
||||
value.should be_a(Tuple(Int64, Int64)?)
|
||||
end
|
||||
end
|
||||
|
||||
it "raises if more than one row" do
|
||||
with_dummy do |db|
|
||||
expect_raises(DB::Error, "more than one row") do
|
||||
db.query_one?("3,4 5,6") { }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "returns nil if no rows" do
|
||||
with_dummy do |db|
|
||||
db.query_one?("") { fail("block shouldn't be invoked") }.should be_nil
|
||||
end
|
||||
end
|
||||
|
||||
it "with as" do
|
||||
with_dummy do |db|
|
||||
value = db.query_one?("3,4", as: {Int64, Int64})
|
||||
value.should be_a(Tuple(Int64, Int64)?)
|
||||
value.should eq({3i64, 4i64})
|
||||
end
|
||||
end
|
||||
|
||||
it "with as, just one" do
|
||||
with_dummy do |db|
|
||||
value = db.query_one?("3", as: Int64)
|
||||
value.should be_a(Int64?)
|
||||
value.should eq(3i64)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "query all" do
|
||||
it "queries" do
|
||||
with_dummy do |db|
|
||||
ary = db.query_all "3,4 1,2", &.read(Int64, Int64)
|
||||
ary.should eq([{3, 4}, {1, 2}])
|
||||
end
|
||||
end
|
||||
|
||||
it "queries with as" do
|
||||
with_dummy do |db|
|
||||
ary = db.query_all "3,4 1,2", as: {Int64, Int64}
|
||||
ary.should eq([{3, 4}, {1, 2}])
|
||||
end
|
||||
end
|
||||
|
||||
it "queries with as, just one" do
|
||||
with_dummy do |db|
|
||||
ary = db.query_all "3 1", as: Int64
|
||||
ary.should eq([3, 1])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "reads multiple values" do
|
||||
with_dummy do |db|
|
||||
db.query "3,4 1,2" do |rs|
|
||||
rs.move_next
|
||||
rs.read(Int64, Int64).should eq({3i64, 4i64})
|
||||
rs.move_next
|
||||
rs.read(Int64, Int64).should eq({1i64, 2i64})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "should enumerate blob fields" do
|
||||
with_dummy do |db|
|
||||
db.query("az,AZ") do |rs|
|
||||
|
@ -110,22 +220,13 @@ describe DummyDriver do
|
|||
|
||||
it "should get Nil scalars" do
|
||||
with_dummy do |db|
|
||||
DummyDriver::DummyResultSet.next_column_type = Nil
|
||||
db.scalar("NULL").should be_nil
|
||||
end
|
||||
end
|
||||
|
||||
{% for value in [1, 1_i64, "hello", 1.5, 1.5_f32] %}
|
||||
it "numeric scalars of type of {{value.id}} should return value or nil" do
|
||||
with_dummy do |db|
|
||||
DummyDriver::DummyResultSet.next_column_type = typeof({{value}})
|
||||
db.scalar("#{{{value}}}").should eq({{value}})
|
||||
end
|
||||
end
|
||||
|
||||
it "should set positional arguments for {{value.id}}" do
|
||||
with_dummy do |db|
|
||||
DummyDriver::DummyResultSet.next_column_type = typeof({{value}})
|
||||
db.scalar("?", {{value}}).should eq({{value}})
|
||||
end
|
||||
end
|
||||
|
@ -135,7 +236,6 @@ describe DummyDriver do
|
|||
with_dummy do |db|
|
||||
ary = UInt8[0x53, 0x51, 0x4C]
|
||||
slice = Bytes.new(ary.to_unsafe, ary.size)
|
||||
DummyDriver::DummyResultSet.next_column_type = typeof(slice)
|
||||
(db.scalar("?", slice).as(Bytes)).to_a.should eq(ary)
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue