543 lines
14 KiB
Ruby
543 lines
14 KiB
Ruby
require File.join(File.dirname(__FILE__), 'helper')
|
|
|
|
class TC_Database_Integration < Test::Unit::TestCase
|
|
def setup
|
|
@db = SQLite3::Database.new( "test.db" )
|
|
@db.transaction do
|
|
@db.execute "create table foo ( a integer primary key, b text )"
|
|
@db.execute "insert into foo ( b ) values ( 'foo' )"
|
|
@db.execute "insert into foo ( b ) values ( 'bar' )"
|
|
@db.execute "insert into foo ( b ) values ( 'baz' )"
|
|
end
|
|
end
|
|
|
|
def teardown
|
|
@db.close
|
|
File.delete( "test.db" )
|
|
end
|
|
|
|
def test_table_info_with_type_translation_active
|
|
@db.type_translation = true
|
|
assert_nothing_raised { @db.table_info("foo") }
|
|
end
|
|
|
|
def test_table_info_with_defaults_for_version_3_3_8_and_higher
|
|
@db.transaction do
|
|
@db.execute "create table defaults_test ( a string default NULL, b string default 'Hello' )"
|
|
data = @db.table_info( "defaults_test" )
|
|
assert_equal({"name" => "a", "type" => "string", "dflt_value" => nil, "notnull" => "0", "cid" => "0", "pk" => "0"},
|
|
data[0])
|
|
assert_equal({"name" => "b", "type" => "string", "dflt_value" => "Hello", "notnull" => "0", "cid" => "1", "pk" => "0"},
|
|
data[1])
|
|
end
|
|
end
|
|
|
|
def test_table_info_without_defaults_for_version_3_3_8_and_higher
|
|
@db.transaction do
|
|
@db.execute "create table no_defaults_test ( a integer default 1, b integer )"
|
|
data = @db.table_info( "no_defaults_test" )
|
|
assert_equal({"name" => "a", "type" => "integer", "dflt_value" => "1", "notnull" => "0", "cid" => "0", "pk" => "0"},
|
|
data[0])
|
|
assert_equal({"name" => "b", "type" => "integer", "dflt_value" => nil, "notnull" => "0", "cid" => "1", "pk" => "0"},
|
|
data[1])
|
|
end
|
|
end
|
|
|
|
def test_complete_fail
|
|
assert !@db.complete?( "select * from foo" )
|
|
end
|
|
def test_complete_success
|
|
assert @db.complete?( "select * from foo;" )
|
|
end
|
|
|
|
def test_complete_fail_utf16
|
|
assert !@db.complete?( "select * from foo".to_utf16(false), true )
|
|
end
|
|
|
|
def test_complete_success_utf16
|
|
assert @db.complete?( "select * from foo;".to_utf16(true), true )
|
|
end
|
|
|
|
def test_errmsg
|
|
assert_equal "not an error", @db.errmsg
|
|
end
|
|
|
|
def test_errmsg_utf16
|
|
assert_equal "not an error".to_utf16, @db.errmsg(true)
|
|
end
|
|
|
|
def test_errcode
|
|
assert_equal 0, @db.errcode
|
|
end
|
|
|
|
def test_trace
|
|
result = nil
|
|
@db.trace( "data" ) { |data,sql| result = [ data, sql ]; 0 }
|
|
@db.execute "select * from foo"
|
|
assert_equal ["data","select * from foo"], result
|
|
end
|
|
|
|
def test_authorizer_okay
|
|
@db.authorizer( "data" ) { |data,type,a,b,c,d| 0 }
|
|
rows = @db.execute "select * from foo"
|
|
assert_equal 3, rows.length
|
|
end
|
|
|
|
def test_authorizer_error
|
|
@db.authorizer( "data" ) { |data,type,a,b,c,d| 1 }
|
|
assert_raise( SQLite3::AuthorizationException ) do
|
|
@db.execute "select * from foo"
|
|
end
|
|
end
|
|
|
|
def test_authorizer_silent
|
|
@db.authorizer( "data" ) { |data,type,a,b,c,d| 2 }
|
|
rows = @db.execute "select * from foo"
|
|
assert rows.empty?
|
|
end
|
|
|
|
def test_prepare_invalid_syntax
|
|
assert_raise( SQLite3::SQLException ) do
|
|
@db.prepare "select from foo"
|
|
end
|
|
end
|
|
|
|
def test_prepare_invalid_column
|
|
assert_raise( SQLite3::SQLException ) do
|
|
@db.prepare "select k from foo"
|
|
end
|
|
end
|
|
|
|
def test_prepare_invalid_table
|
|
assert_raise( SQLite3::SQLException ) do
|
|
@db.prepare "select * from barf"
|
|
end
|
|
end
|
|
|
|
def test_prepare_no_block
|
|
stmt = @db.prepare "select * from foo"
|
|
assert stmt.respond_to?(:execute)
|
|
stmt.close
|
|
end
|
|
|
|
def test_prepare_with_block
|
|
called = false
|
|
@db.prepare "select * from foo" do |stmt|
|
|
called = true
|
|
assert stmt.respond_to?(:execute)
|
|
end
|
|
assert called
|
|
end
|
|
|
|
def test_execute_no_block_no_bind_no_match
|
|
rows = @db.execute( "select * from foo where a > 100" )
|
|
assert rows.empty?
|
|
end
|
|
|
|
def test_execute_with_block_no_bind_no_match
|
|
called = false
|
|
@db.execute( "select * from foo where a > 100" ) do |row|
|
|
called = true
|
|
end
|
|
assert !called
|
|
end
|
|
|
|
def test_execute_no_block_with_bind_no_match
|
|
rows = @db.execute( "select * from foo where a > ?", 100 )
|
|
assert rows.empty?
|
|
end
|
|
|
|
def test_execute_with_block_with_bind_no_match
|
|
called = false
|
|
@db.execute( "select * from foo where a > ?", 100 ) do |row|
|
|
called = true
|
|
end
|
|
assert !called
|
|
end
|
|
|
|
def test_execute_no_block_no_bind_with_match
|
|
rows = @db.execute( "select * from foo where a = 1" )
|
|
assert_equal 1, rows.length
|
|
end
|
|
|
|
def test_execute_with_block_no_bind_with_match
|
|
called = 0
|
|
@db.execute( "select * from foo where a = 1" ) do |row|
|
|
called += 1
|
|
end
|
|
assert_equal 1, called
|
|
end
|
|
|
|
def test_execute_no_block_with_bind_with_match
|
|
rows = @db.execute( "select * from foo where a = ?", 1 )
|
|
assert_equal 1, rows.length
|
|
end
|
|
|
|
def test_execute_with_block_with_bind_with_match
|
|
called = 0
|
|
@db.execute( "select * from foo where a = ?", 1 ) do |row|
|
|
called += 1
|
|
end
|
|
assert_equal 1, called
|
|
end
|
|
|
|
def test_execute2_no_block_no_bind_no_match
|
|
columns, *rows = @db.execute2( "select * from foo where a > 100" )
|
|
assert rows.empty?
|
|
assert [ "a", "b" ], columns
|
|
end
|
|
|
|
def test_execute2_with_block_no_bind_no_match
|
|
called = 0
|
|
@db.execute2( "select * from foo where a > 100" ) do |row|
|
|
assert [ "a", "b" ], row unless called == 0
|
|
called += 1
|
|
end
|
|
assert_equal 1, called
|
|
end
|
|
|
|
def test_execute2_no_block_with_bind_no_match
|
|
columns, *rows = @db.execute2( "select * from foo where a > ?", 100 )
|
|
assert rows.empty?
|
|
assert [ "a", "b" ], columns
|
|
end
|
|
|
|
def test_execute2_with_block_with_bind_no_match
|
|
called = 0
|
|
@db.execute2( "select * from foo where a > ?", 100 ) do |row|
|
|
assert [ "a", "b" ], row unless called == 0
|
|
called += 1
|
|
end
|
|
assert_equal 1, called
|
|
end
|
|
|
|
def test_execute2_no_block_no_bind_with_match
|
|
columns, *rows = @db.execute2( "select * from foo where a = 1" )
|
|
assert_equal 1, rows.length
|
|
assert [ "a", "b" ], columns
|
|
end
|
|
|
|
def test_execute2_with_block_no_bind_with_match
|
|
called = 0
|
|
@db.execute2( "select * from foo where a = 1" ) do |row|
|
|
assert [ "a", "b" ], row unless called == 0
|
|
called += 1
|
|
end
|
|
assert_equal 2, called
|
|
end
|
|
|
|
def test_execute2_no_block_with_bind_with_match
|
|
columns, *rows = @db.execute2( "select * from foo where a = ?", 1 )
|
|
assert_equal 1, rows.length
|
|
assert [ "a", "b" ], columns
|
|
end
|
|
|
|
def test_execute2_with_block_with_bind_with_match
|
|
called = 0
|
|
@db.execute2( "select * from foo where a = ?", 1 ) do |row|
|
|
called += 1
|
|
end
|
|
assert_equal 2, called
|
|
end
|
|
|
|
def test_execute_batch_empty
|
|
assert_nothing_raised { @db.execute_batch "" }
|
|
end
|
|
|
|
def test_execute_batch_no_bind
|
|
@db.transaction do
|
|
@db.execute_batch <<-SQL
|
|
create table bar ( a, b, c );
|
|
insert into bar values ( 'one', 2, 'three' );
|
|
insert into bar values ( 'four', 5, 'six' );
|
|
insert into bar values ( 'seven', 8, 'nine' );
|
|
SQL
|
|
end
|
|
rows = @db.execute( "select * from bar" )
|
|
assert_equal 3, rows.length
|
|
end
|
|
|
|
def test_execute_batch_with_bind
|
|
@db.execute_batch( <<-SQL, 1 )
|
|
create table bar ( a, b, c );
|
|
insert into bar values ( 'one', 2, ? );
|
|
insert into bar values ( 'four', 5, ? );
|
|
insert into bar values ( 'seven', 8, ? );
|
|
SQL
|
|
rows = @db.execute( "select * from bar" ).map { |a,b,c| c }
|
|
assert_equal %w{1 1 1}, rows
|
|
end
|
|
|
|
def test_query_no_block_no_bind_no_match
|
|
result = @db.query( "select * from foo where a > 100" )
|
|
assert_nil result.next
|
|
result.close
|
|
end
|
|
|
|
def test_query_with_block_no_bind_no_match
|
|
r = nil
|
|
@db.query( "select * from foo where a > 100" ) do |result|
|
|
assert_nil result.next
|
|
r = result
|
|
end
|
|
assert r.closed?
|
|
end
|
|
|
|
def test_query_no_block_with_bind_no_match
|
|
result = @db.query( "select * from foo where a > ?", 100 )
|
|
assert_nil result.next
|
|
result.close
|
|
end
|
|
|
|
def test_query_with_block_with_bind_no_match
|
|
r = nil
|
|
@db.query( "select * from foo where a > ?", 100 ) do |result|
|
|
assert_nil result.next
|
|
r = result
|
|
end
|
|
assert r.closed?
|
|
end
|
|
|
|
def test_query_no_block_no_bind_with_match
|
|
result = @db.query( "select * from foo where a = 1" )
|
|
assert_not_nil result.next
|
|
assert_nil result.next
|
|
result.close
|
|
end
|
|
|
|
def test_query_with_block_no_bind_with_match
|
|
r = nil
|
|
@db.query( "select * from foo where a = 1" ) do |result|
|
|
assert_not_nil result.next
|
|
assert_nil result.next
|
|
r = result
|
|
end
|
|
assert r.closed?
|
|
end
|
|
|
|
def test_query_no_block_with_bind_with_match
|
|
result = @db.query( "select * from foo where a = ?", 1 )
|
|
assert_not_nil result.next
|
|
assert_nil result.next
|
|
result.close
|
|
end
|
|
|
|
def test_query_with_block_with_bind_with_match
|
|
r = nil
|
|
@db.query( "select * from foo where a = ?", 1 ) do |result|
|
|
assert_not_nil result.next
|
|
assert_nil result.next
|
|
r = result
|
|
end
|
|
assert r.closed?
|
|
end
|
|
|
|
def test_get_first_row_no_bind_no_match
|
|
result = @db.get_first_row( "select * from foo where a=100" )
|
|
assert_nil result
|
|
end
|
|
|
|
def test_get_first_row_no_bind_with_match
|
|
result = @db.get_first_row( "select * from foo where a=1" )
|
|
assert_equal [ "1", "foo" ], result
|
|
end
|
|
|
|
def test_get_first_row_with_bind_no_match
|
|
result = @db.get_first_row( "select * from foo where a=?", 100 )
|
|
assert_nil result
|
|
end
|
|
|
|
def test_get_first_row_with_bind_with_match
|
|
result = @db.get_first_row( "select * from foo where a=?", 1 )
|
|
assert_equal [ "1", "foo" ], result
|
|
end
|
|
|
|
def test_get_first_value_no_bind_no_match
|
|
result = @db.get_first_value( "select b, a from foo where a=100" )
|
|
assert_nil result
|
|
end
|
|
|
|
def test_get_first_value_no_bind_with_match
|
|
result = @db.get_first_value( "select b, a from foo where a=1" )
|
|
assert_equal "foo", result
|
|
end
|
|
|
|
def test_get_first_value_with_bind_no_match
|
|
result = @db.get_first_value( "select b, a from foo where a=?", 100 )
|
|
assert_nil result
|
|
end
|
|
|
|
def test_get_first_value_with_bind_with_match
|
|
result = @db.get_first_value( "select b, a from foo where a=?", 1 )
|
|
assert_equal "foo", result
|
|
end
|
|
|
|
def test_last_insert_row_id
|
|
@db.execute "insert into foo ( b ) values ( 'test' )"
|
|
assert_equal 4, @db.last_insert_row_id
|
|
@db.execute "insert into foo ( b ) values ( 'again' )"
|
|
assert_equal 5, @db.last_insert_row_id
|
|
end
|
|
|
|
def test_changes
|
|
@db.execute "insert into foo ( b ) values ( 'test' )"
|
|
assert_equal 1, @db.changes
|
|
@db.execute "delete from foo where 1=1"
|
|
assert_equal 4, @db.changes
|
|
end
|
|
|
|
def test_total_changes
|
|
assert_equal 3, @db.total_changes
|
|
@db.execute "insert into foo ( b ) values ( 'test' )"
|
|
@db.execute "delete from foo where 1=1"
|
|
assert_equal 8, @db.total_changes
|
|
end
|
|
|
|
def test_transaction_nest
|
|
assert_raise( SQLite3::SQLException ) do
|
|
@db.transaction do
|
|
@db.transaction do
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def test_transaction_rollback
|
|
@db.transaction
|
|
@db.execute_batch <<-SQL
|
|
insert into foo (b) values ( 'test1' );
|
|
insert into foo (b) values ( 'test2' );
|
|
insert into foo (b) values ( 'test3' );
|
|
insert into foo (b) values ( 'test4' );
|
|
SQL
|
|
assert_equal 7, @db.get_first_value("select count(*) from foo").to_i
|
|
@db.rollback
|
|
assert_equal 3, @db.get_first_value("select count(*) from foo").to_i
|
|
end
|
|
|
|
def test_transaction_commit
|
|
@db.transaction
|
|
@db.execute_batch <<-SQL
|
|
insert into foo (b) values ( 'test1' );
|
|
insert into foo (b) values ( 'test2' );
|
|
insert into foo (b) values ( 'test3' );
|
|
insert into foo (b) values ( 'test4' );
|
|
SQL
|
|
assert_equal 7, @db.get_first_value("select count(*) from foo").to_i
|
|
@db.commit
|
|
assert_equal 7, @db.get_first_value("select count(*) from foo").to_i
|
|
end
|
|
|
|
def test_transaction_rollback_in_block
|
|
assert_raise( SQLite3::SQLException ) do
|
|
@db.transaction do
|
|
@db.rollback
|
|
end
|
|
end
|
|
end
|
|
|
|
def test_transaction_commit_in_block
|
|
assert_raise( SQLite3::SQLException ) do
|
|
@db.transaction do
|
|
@db.commit
|
|
end
|
|
end
|
|
end
|
|
|
|
def test_transaction_active
|
|
assert !@db.transaction_active?
|
|
@db.transaction
|
|
assert @db.transaction_active?
|
|
@db.commit
|
|
assert !@db.transaction_active?
|
|
end
|
|
|
|
def test_interrupt
|
|
@db.create_function( "abort", 1 ) do |func,x|
|
|
@db.interrupt
|
|
func.result = x
|
|
end
|
|
|
|
assert_raise( SQLite3::SQLException ) do
|
|
@db.execute "select abort(a) from foo"
|
|
end
|
|
end
|
|
|
|
def test_create_function
|
|
@db.create_function( "munge", 1 ) do |func,x|
|
|
func.result = ">>>#{x}<<<"
|
|
end
|
|
|
|
value = @db.get_first_value( "select munge(b) from foo where a=1" )
|
|
assert_match( />>>.*<<</, value )
|
|
end
|
|
|
|
def test_create_aggregate_without_block
|
|
step = proc do |ctx,a|
|
|
ctx[:sum] ||= 0
|
|
ctx[:sum] += a.to_i
|
|
end
|
|
|
|
final = proc { |ctx| ctx.result = ctx[:sum] }
|
|
|
|
@db.create_aggregate( "accumulate", 1, step, final )
|
|
|
|
value = @db.get_first_value( "select accumulate(a) from foo" )
|
|
assert_equal "6", value
|
|
end
|
|
|
|
def test_create_aggregate_with_block
|
|
@db.create_aggregate( "accumulate", 1 ) do
|
|
step do |ctx,a|
|
|
ctx[:sum] ||= 0
|
|
ctx[:sum] += a.to_i
|
|
end
|
|
|
|
finalize { |ctx| ctx.result = ctx[:sum] }
|
|
end
|
|
|
|
value = @db.get_first_value( "select accumulate(a) from foo" )
|
|
assert_equal "6", value
|
|
end
|
|
|
|
def test_create_aggregate_with_no_data
|
|
@db.create_aggregate( "accumulate", 1 ) do
|
|
step do |ctx,a|
|
|
ctx[:sum] ||= 0
|
|
ctx[:sum] += a.to_i
|
|
end
|
|
|
|
finalize { |ctx| ctx.result = ctx[:sum] || 0 }
|
|
end
|
|
|
|
value = @db.get_first_value(
|
|
"select accumulate(a) from foo where a = 100" )
|
|
assert_equal "0", value
|
|
end
|
|
|
|
def test_create_aggregate_handler
|
|
handler = Class.new do
|
|
class << self
|
|
def arity; 1; end
|
|
def text_rep; SQLite3::Constants::TextRep::ANY; end
|
|
def name; "multiply"; end
|
|
end
|
|
def step(ctx, a)
|
|
ctx[:buffer] ||= 1
|
|
ctx[:buffer] *= a.to_i
|
|
end
|
|
def finalize(ctx); ctx.result = ctx[:buffer]; end
|
|
end
|
|
|
|
@db.create_aggregate_handler( handler )
|
|
value = @db.get_first_value( "select multiply(a) from foo" )
|
|
assert_equal "6", value
|
|
end
|
|
|
|
def test_bind_array_parameter
|
|
result = @db.get_first_value( "select b from foo where a=? and b=?",
|
|
[ 1, "foo" ] )
|
|
assert_equal "foo", result
|
|
end
|
|
end
|