add insert/select per type specs

add last_insert_id
add Driver.quote
This commit is contained in:
Brian J. Cardiff 2016-01-31 14:03:05 -03:00
parent add75d86bf
commit 2e6e6ed7e5
3 changed files with 67 additions and 9 deletions

View file

@ -18,6 +18,16 @@ def sql(s)
"#{s}"
end
def sqlite_type_for(v)
case v
when String ; "text"
when Int32, Int64 ; "int"
when Float32, Float64; "float"
else
raise "not implemented for #{typeof(v)}"
end
end
def assert_single_read(rs, value_type, value)
rs.move_next.should be_true
rs.read(value_type).should eq(value)
@ -146,26 +156,64 @@ describe Driver do
end
end
# TODO get other value types from table
# TODO get many rows from table
# TODO get_last_row_id
# TODO gets column types
# TODO migrate quotes to std
it "gets values from table" do
it "gets last insert row id" do
with_mem_db do |db|
cnn = db.connection
cnn.exec "create table person (name string, age integer)"
cnn.last_insert_id.should eq(0)
cnn.exec %(insert into person values ("foo", 10))
cnn.last_insert_id.should eq(1)
end
end
{% for value in [1, 1_i64, "hello", 1.5, 1.5_f32] %}
it "insert/get value {{value.id}} from table" do
with_db do |db|
db.exec "create table table1 (col1 #{sqlite_type_for({{value}})})"
db.exec %(insert into table1 values (#{sql({{value}})}))
db.scalar(typeof({{value}}), "select col1 from table1").should eq({{value}})
end
end
{% end %}
it "insert/get blob value from table" do
with_db do |db|
ary = UInt8[0x53, 0x51, 0x4C, 0x69, 0x74, 0x65]
db.exec "create table table1 (col1 blob)"
db.exec %(insert into table1 values (?)), Slice.new(ary.to_unsafe, ary.size)
slice = db.scalar(Slice(UInt8), "select col1 from table1")
slice.to_a.should eq(ary)
end
end
it "gets many rows from table" do
with_mem_db do |db|
db.exec "create table person (name string, age integer)"
db.exec %(insert into person values ("foo", 10))
db.exec %(insert into person values ("bar", 20))
db.exec %(insert into person values ("baz", 30))
names = [] of String
ages = [] of Int32
db.query "select * from person" do |rs|
rs.move_next.should be_true
rs.read(String).should eq("foo")
rs.read(Int32).should eq(10)
rs.move_next.should be_false
rs.each do
names << rs.read(String)
ages << rs.read(Int32)
end
end
names.should eq(["foo", "bar", "baz"])
ages.should eq([10, 20, 30])
end
end
it "quotes" do
Driver.quote("'hello'").should eq("''hello''")
end
it "ensures statements are closed" do
begin
DB.open "sqlite3", {"database": DB_FILENAME} do |db|

View file

@ -13,6 +13,10 @@ class SQLite3::Connection < DB::Connection
LibSQLite3.close_v2(self)
end
def last_insert_id : Int64
LibSQLite3.last_insert_rowid(self)
end
def to_unsafe
@db
end

View file

@ -2,6 +2,12 @@ class SQLite3::Driver < DB::Driver
def build_connection
SQLite3::Connection.new(options)
end
# Quotes the given string, making it safe to use in an SQL statement.
# It replaces all instances of the single-quote character with two single-quote characters.
def self.quote(string)
string.gsub('\'', "''")
end
end
DB.register_driver "sqlite3", SQLite3::Driver