Skip to content

Commit

Permalink
make SQLite3::Database.open return the block result instead of the db…
Browse files Browse the repository at this point in the history
… instance

To make it follow common pattern, like for File:

    result = File.open('/dev/zero') do |f|
      f.read(10)
    end

See discussion in #414
  • Loading branch information
toy committed Oct 22, 2023
1 parent 2611034 commit 0ef9a94
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 3 deletions.
17 changes: 16 additions & 1 deletion lib/sqlite3/database.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,22 @@ class Database

class << self

alias :open :new
# Without block works exactly as new.
# With block, like new closes the database at the end, but unlike new
# returns the result of the block instead of the database instance.
def open( *args )
database = new(*args)

if block_given?
begin
yield database
ensure
database.close
end
else
database
end
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
Expand Down
47 changes: 45 additions & 2 deletions test/test_database.rb
Original file line number Diff line number Diff line change
Expand Up @@ -198,11 +198,25 @@ def test_execute_batch2

def test_new
db = SQLite3::Database.new(':memory:')
assert db
assert_instance_of(SQLite3::Database, db)
ensure
db.close if db
end

def test_open
db = SQLite3::Database.open(':memory:')
assert_instance_of(SQLite3::Database, db)
ensure
db.close if db
end

def test_open_returns_block_result
result = SQLite3::Database.open(':memory:') do |db|
:foo
end
assert_equal :foo, result
end

def test_new_yields_self
thing = nil
SQLite3::Database.new(':memory:') do |db|
Expand All @@ -211,6 +225,14 @@ def test_new_yields_self
assert_instance_of(SQLite3::Database, thing)
end

def test_open_yields_self
thing = nil
SQLite3::Database.open(':memory:') do |db|
thing = db
end
assert_instance_of(SQLite3::Database, thing)
end

def test_new_with_options
# determine if Ruby is running on Big Endian platform
utf16 = ([1].pack("I") == [1].pack("N")) ? "UTF-16BE" : "UTF-16LE"
Expand All @@ -221,7 +243,7 @@ def test_new_with_options
db = SQLite3::Database.new(Iconv.conv(utf16, 'UTF-8', ':memory:'),
:utf16 => true)
end
assert db
assert_instance_of(SQLite3::Database, db)
ensure
db.close if db
end
Expand All @@ -241,6 +263,15 @@ def test_block_closes_self
assert thing.closed?
end

def test_open_with_block_closes_self
thing = nil
SQLite3::Database.open(':memory:') do |db|
thing = db
assert !thing.closed?
end
assert thing.closed?
end

def test_block_closes_self_even_raised
thing = nil
begin
Expand All @@ -253,6 +284,18 @@ def test_block_closes_self_even_raised
assert thing.closed?
end

def test_open_with_block_closes_self_even_raised
thing = nil
begin
SQLite3::Database.open(':memory:') do |db|
thing = db
raise
end
rescue
end
assert thing.closed?
end

def test_prepare
db = SQLite3::Database.new(':memory:')
stmt = db.prepare('select "hello world"')
Expand Down

0 comments on commit 0ef9a94

Please sign in to comment.