require 'helper' module SQLite3 class TestStatement < SQLite3::TestCase def setup @db = SQLite3::Database.new(':memory:') @stmt = SQLite3::Statement.new(@db, "select 'foo'") end def test_raises_type_error assert_raises(TypeError) do SQLite3::Statement.new( @db, nil ) end end ### # This method may not exist depending on how sqlite3 was compiled def test_database_name @db.execute('create table foo(text BLOB)') @db.execute('insert into foo(text) values (?)',SQLite3::Blob.new('hello')) stmt = @db.prepare('select text from foo') if stmt.respond_to?(:database_name) assert_equal 'main', stmt.database_name(0) end end def test_prepare_blob @db.execute('create table foo(text BLOB)') stmt = @db.prepare('insert into foo(text) values (?)') stmt.bind_param(1, SQLite3::Blob.new('hello')) stmt.step stmt.close end def test_select_blob @db.execute('create table foo(text BLOB)') @db.execute('insert into foo(text) values (?)',SQLite3::Blob.new('hello')) assert_equal 'hello', @db.execute('select * from foo').first.first end def test_new assert @stmt end def test_new_closed_handle @db = SQLite3::Database.new(':memory:') @db.close assert_raises(ArgumentError) do SQLite3::Statement.new(@db, 'select "foo"') end end def test_new_with_remainder stmt = SQLite3::Statement.new(@db, "select 'foo';bar") assert_equal 'bar', stmt.remainder end def test_empty_remainder assert_equal '', @stmt.remainder end def test_close @stmt.close assert @stmt.closed? end def test_double_close @stmt.close assert_raises(SQLite3::Exception) do @stmt.close end end def test_bind_param_string stmt = SQLite3::Statement.new(@db, "select ?") stmt.bind_param(1, "hello") result = nil stmt.each { |x| result = x } assert_equal ['hello'], result end def test_bind_param_int stmt = SQLite3::Statement.new(@db, "select ?") stmt.bind_param(1, 10) result = nil stmt.each { |x| result = x } assert_equal [10], result end def test_bind_nil stmt = SQLite3::Statement.new(@db, "select ?") stmt.bind_param(1, nil) result = nil stmt.each { |x| result = x } assert_equal [nil], result end def test_bind_blobs end def test_bind_64 stmt = SQLite3::Statement.new(@db, "select ?") stmt.bind_param(1, 2 ** 31) result = nil stmt.each { |x| result = x } assert_equal [2 ** 31], result end def test_bind_double stmt = SQLite3::Statement.new(@db, "select ?") stmt.bind_param(1, 2.2) result = nil stmt.each { |x| result = x } assert_equal [2.2], result end def test_named_bind stmt = SQLite3::Statement.new(@db, "select :foo") stmt.bind_param(':foo', 'hello') result = nil stmt.each { |x| result = x } assert_equal ['hello'], result end def test_named_bind_no_colon stmt = SQLite3::Statement.new(@db, "select :foo") stmt.bind_param('foo', 'hello') result = nil stmt.each { |x| result = x } assert_equal ['hello'], result end def test_named_bind_symbol stmt = SQLite3::Statement.new(@db, "select :foo") stmt.bind_param(:foo, 'hello') result = nil stmt.each { |x| result = x } assert_equal ['hello'], result end def test_named_bind_not_found stmt = SQLite3::Statement.new(@db, "select :foo") assert_raises(SQLite3::Exception) do stmt.bind_param('bar', 'hello') end end def test_each r = nil @stmt.each do |row| r = row end assert_equal(['foo'], r) end def test_reset! r = [] @stmt.each { |row| r << row } @stmt.reset! @stmt.each { |row| r << row } assert_equal [['foo'], ['foo']], r end def test_step r = @stmt.step assert_equal ['foo'], r end def test_tainted r = @stmt.step assert r.first.tainted? end def test_step_twice assert_not_nil @stmt.step assert !@stmt.done? assert_nil @stmt.step assert @stmt.done? @stmt.reset! assert !@stmt.done? end def test_step_never_moves_past_done 10.times { @stmt.step } @stmt.done? end def test_column_count assert_equal 1, @stmt.column_count end def test_column_name assert_equal "'foo'", @stmt.column_name(0) assert_equal nil, @stmt.column_name(10) end def test_bind_parameter_count stmt = SQLite3::Statement.new(@db, "select ?, ?, ?") assert_equal 3, stmt.bind_parameter_count end def test_execute_with_varargs stmt = @db.prepare('select ?, ?') assert_equal [[nil, nil]], stmt.execute(nil, nil).to_a end def test_execute_with_hash stmt = @db.prepare('select :n, :h') assert_equal [[10, nil]], stmt.execute('n' => 10, 'h' => nil).to_a end def test_with_error @db.execute('CREATE TABLE "employees" ("name" varchar(20) NOT NULL CONSTRAINT "index_employees_on_name" UNIQUE)') stmt = @db.prepare("INSERT INTO Employees(name) VALUES(?)") stmt.execute('employee-1') stmt.execute('employee-1') rescue SQLite3::ConstraintException stmt.reset! assert_nothing_raised(SQLite3::ConstraintException) { stmt.execute('employee-2') } end def test_clear_bindings stmt = @db.prepare('select ?, ?') stmt.bind_param 1, "foo" stmt.bind_param 2, "bar" # We can't fetch bound parameters back out of sqlite3, so just call # the clear_bindings! method and assert that nil is returned stmt.clear_bindings! while x = stmt.step assert_equal [nil, nil], x end end end end