Updated to Crystal 0.18.0

This commit is contained in:
Ary Borenszweig 2016-06-15 12:05:12 -03:00
parent b1c6c32ae5
commit 135f33d9ea
5 changed files with 96 additions and 18 deletions

View File

@ -1,5 +1,5 @@
name: sqlite3
version: 0.3.0
version: 0.4.0
authors:
- Ary Borenszweig <aborenszweig@manas.com.ar>

View File

@ -72,23 +72,31 @@ describe Database do
it "executes and selects blob" do
rows = with_db(&.execute(%(select X'53514C697465')))
row = rows[0]
cell = row[0] as Slice(UInt8)
cell = row[0].as(Slice(UInt8))
cell.to_a.should eq([0x53, 0x51, 0x4C, 0x69, 0x74, 0x65])
end
it "executes with named bind using symbol" do
with_db(&.execute(%(select :value), {value: "hello"})).should eq([["hello"]])
with_db(&.execute(%(select :value), {:value => "hello"})).should eq([["hello"]])
end
it "executes with named bind using string" do
with_db(&.execute(%(select :value), {"value": "hello"})).should eq([["hello"]])
with_db(&.execute(%(select :value), {"value" => "hello"})).should eq([["hello"]])
end
it "executes with named bind using named argument" do
with_db(&.execute(%(select :value), {value: "hello"})).should eq([["hello"]])
end
it "executes with named bind using named arguments" do
with_db(&.execute(%(select :value), value: "hello")).should eq([["hello"]])
end
it "executes with bind blob" do
ary = UInt8[0x53, 0x51, 0x4C, 0x69, 0x74, 0x65]
rows = with_db(&.execute(%(select cast(? as BLOB)), Slice.new(ary.to_unsafe, ary.size)))
row = rows[0]
cell = row[0] as Slice(UInt8)
cell = row[0].as(Slice(UInt8))
cell.to_a.should eq(ary)
end
@ -113,6 +121,20 @@ describe Database do
end
end
it "uses named arguments in statement execute" do
Database.new(":memory:") do |db|
db.execute "create table person (name string, age integer)"
db.execute %(insert into person values ("foo", 10))
db.execute %(insert into person values ("bar", 2))
stmt = db.prepare("select * from person where age > :age")
stmt.execute age: 5
stmt.step
stmt["age"].should eq(10)
stmt.types.should eq([Type::TEXT, Type::INTEGER])
stmt.close
end
end
it "gets column by name" do
Database.new(":memory:") do |db|
db.execute "create table person (name string, age integer)"
@ -126,6 +148,20 @@ describe Database do
end
end
it "uses named argument in query" do
Database.new(":memory:") do |db|
db.execute "create table person (name string, age integer)"
db.execute %(insert into person values ("foo", 10))
db.execute %(insert into person values ("bar", 2))
db.query("select * from person where age > :age", age: 5) do |result_set|
result_set.next.should be_true
result_set["name"].should eq("foo")
result_set["age"].should eq(10)
expect_raises { result_set["lala"] }
end
end
end
it "gets last insert row id" do
Database.new(":memory:") do |db|
db.execute "create table person (name string, age integer)"

View File

@ -84,6 +84,10 @@ class SQLite3::Database
execute(sql, binds)
end
def execute(sql, **binds)
execute(sql, binds)
end
# Executes the given SQL statement. If additional parameters are given, they are treated as bind variables,
# and are bound to the placeholders in the query.
#
@ -97,6 +101,12 @@ class SQLite3::Database
end
end
def execute(sql, **binds, &block)
execute(sql, binds) do |row|
yield row
end
end
# Executes the given SQL statement. If additional parameters are given, they are treated as bind variables,
# and are bound to the placeholders in the query.
#
@ -104,7 +114,7 @@ class SQLite3::Database
# with the key being used as the name of the placeholder to bind the value to.
#
# Returns an `Array(Array(Value))`.
def execute(sql, binds : Enumerable)
def execute(sql, binds : Enumerable | NamedTuple)
rows = [] of Array(Value)
execute(sql, binds) do |row|
rows << row
@ -119,7 +129,7 @@ class SQLite3::Database
# with the key being used as the name of the placeholder to bind the value to.
#
# Yields one `Array(Value)` for each result.
def execute(sql, binds : Enumerable, &block)
def execute(sql, binds : Enumerable | NamedTuple, &block)
query(sql, binds) do |result_set|
while result_set.next
yield result_set.to_a
@ -149,7 +159,7 @@ class SQLite3::Database
end
# A convenience method that returns the first value of the first row of a query result.
def get_first_value(sql, binds : Enumerable)
def get_first_value(sql, binds : Enumerable | NamedTuple)
query(sql, binds) do |result_set|
if result_set.next
return result_set[0]
@ -172,17 +182,27 @@ class SQLite3::Database
end
# Executes a query and gives back a `ResultSet`.
def query(sql, binds : Enumerable)
def query(sql, binds : Enumerable | NamedTuple)
prepare(sql).execute(binds)
end
# Executes a query and yields a `ResultSet` that will be closed at the end of the given block.
def query(sql, binds : Enumerable, &block)
def query(sql, binds : Enumerable | NamedTuple, &block)
prepare(sql).execute(binds) do |result_set|
yield result_set
end
end
def query(sql, **binds)
query(sql, binds)
end
def query(sql, **binds, &block)
query(sql, binds) do |rs|
yield rs
end
end
# Prepares an sql statement. Returns a `Statement`.
def prepare(sql)
Statement.new(self, sql)

View File

@ -61,22 +61,40 @@ class SQLite3::Statement
# Executes this statement with the given binds and returns a `ResultSet`.
def execute(binds : Enumerable)
reset
# TODO use offset after Crystal 0.6.2
binds.each_with_index do |bind_value, index|
self[index + 1] = bind_value
binds.each_with_index(1) do |bind_value, index|
self[index] = bind_value
end
ResultSet.new self
end
# Executes this statement with the given binds and returns a `ResultSet`.
def execute(binds : NamedTuple)
reset
binds.each do |name, bind_value|
self[name] = bind_value
end
ResultSet.new self
end
# Executes this statement with the given binds and yields a `ResultSet` that
# will be closed at the end of the block.
def execute(binds : Enumerable | Slice(UInt8), &block)
def execute(binds : Enumerable | NamedTuple | Slice(UInt8), &block)
result_set = execute(binds)
yield result_set
ensure
close
end
def execute(**binds)
execute(binds)
end
def execute(**binds, &block)
execute(binds) do |rs|
yield rs
end
end
# Returns the value of the given column by index (1-based).
def [](index : Int)
case type = column_type(index)
@ -156,6 +174,10 @@ class SQLite3::Statement
end
end
def []=(index : Int, tuple : Tuple(String | Symbol, U))
self[tuple[0]] = tuple[1]
end
# Returns the column names of this statement.
def columns
Array.new(column_count) { |i| column_name(i) }

View File

@ -1,8 +1,8 @@
# Each of the possible types of an SQLite3 column.
enum SQLite3::Type
INTEGER = 1
FLOAT = 2
BLOB = 4
NULL = 5
TEXT = 3
FLOAT = 2
BLOB = 4
NULL = 5
TEXT = 3
end