Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove row array wrappers #471

Merged
merged 1 commit into from
Jan 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,22 @@ db.prepare("SELECT * FROM items") do |stmt|
end
```

- Removed `types` and `fields` readers on row objects.
Deprecated code looks like this:

```ruby
row = @db.execute("select * from foo")
assert_equal ["blob"], row.first.types
```

If you would like to access the "types" associated with a returned query,
use a prepared statement like this:

```ruby
@db.prepare("select * from foo") do |v|
assert_equal ["blob"], v.types
end
```

## 1.7.0 / 2023-12-27

Expand Down
2 changes: 1 addition & 1 deletion lib/sqlite3/database.rb
Original file line number Diff line number Diff line change
Expand Up @@ -676,7 +676,7 @@ def readonly?
# but only retries up to the indicated number of +milliseconds+.
# This is an alternative to #busy_timeout, which holds the GVL
# while SQLite sleeps and retries.
def busy_handler_timeout=( milliseconds )
def busy_handler_timeout=(milliseconds)
timeout_seconds = milliseconds.fdiv(1000)

busy_handler do |count|
Expand Down
66 changes: 2 additions & 64 deletions lib/sqlite3/resultset.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,51 +9,6 @@ module SQLite3
class ResultSet
include Enumerable

class ArrayWithTypesAndFields < Array # :nodoc:
attr_writer :types
attr_writer :fields

def types
warn(<<~EOWARN) if $VERBOSE
#{caller(1..1).first} is calling `#{self.class}#types` which is deprecated and will be removed in sqlite3 version 2.0.0. Please call the `types` method on the SQLite3::ResultSet object that created this object.
EOWARN
@types
end

def fields
warn(<<~EOWARN) if $VERBOSE
#{caller(1..1).first} is calling `#{self.class}#fields` which is deprecated and will be removed in sqlite3 version 2.0.0. Please call the `columns` method on the SQLite3::ResultSet object that created this object.
EOWARN
@fields
end
end

# The class of which we return an object in case we want a Hash as
# result.
class HashWithTypesAndFields < Hash # :nodoc:
attr_writer :types
attr_writer :fields

def types
warn(<<~EOWARN) if $VERBOSE
#{caller(1..1).first} is calling `#{self.class}#types` which is deprecated and will be removed in sqlite3 version 2.0.0. Please call the `types` method on the SQLite3::ResultSet object that created this object.
EOWARN
@types
end

def fields
warn(<<~EOWARN) if $VERBOSE
#{caller(1..1).first} is calling `#{self.class}#fields` which is deprecated and will be removed in sqlite3 version 2.0.0. Please call the `columns` method on the SQLite3::ResultSet object that created this object.
EOWARN
@fields
end

def [] key
key = fields[key] if key.is_a? Numeric
super(key)
end
end

# Create a new ResultSet attached to the given database, using the
# given sql text.
def initialize db, stmt
Expand Down Expand Up @@ -85,17 +40,7 @@ def eof?
# For hashes, the column names are the keys of the hash, and the column
# types are accessible via the +types+ property.
def next
row = @stmt.step
return nil if @stmt.done?

# FIXME: the `fields` and `types` methods are deprecated on this
# object for version 2.0, so we can safely remove this branch
# as well.
row = ArrayWithTypesAndFields.new(row)

row.fields = @stmt.columns
row.types = @stmt.types
row
@stmt.step
end

# Required by the Enumerable mixin. Provides an internal iterator over the
Expand Down Expand Up @@ -141,14 +86,7 @@ def next_hash
row = @stmt.step
return nil if @stmt.done?

# FIXME: this can be switched to a regular hash in 2.0
row = HashWithTypesAndFields[*@stmt.columns.zip(row).flatten]

# FIXME: these methods are deprecated for version 2.0, so we can remove
# this code in 2.0
row.fields = @stmt.columns
row.types = @stmt.types
row
Hash[*@stmt.columns.zip(row).flatten]
end
end

Expand Down
22 changes: 10 additions & 12 deletions test/test_integration_pending.rb
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,9 @@ def test_busy_handler_timeout_releases_gvl
work = []

Thread.new do
while true
loop do
sleep 0.1
work << '.'
work << "."
end
end
sleep 1
Expand All @@ -91,25 +91,23 @@ def test_busy_handler_timeout_releases_gvl
busy.lock

t = Thread.new do
begin
db2 = SQLite3::Database.open( "test.db" )
db2.transaction( :exclusive ) do
busy.lock
end
ensure
db2.close if db2
db2 = SQLite3::Database.open("test.db")
db2.transaction(:exclusive) do
busy.lock
end
ensure
db2&.close
end
sleep 1

assert_raises( SQLite3::BusyException ) do
work << '|'
work << "|"
assert_raises(SQLite3::BusyException) do
@db.execute "insert into foo (b) values ( 'from 2' )"
end

busy.unlock
t.join

assert work.size - work.find_index('|') > 3
assert_operator work.size - work.find_index("|"), :>, 3
end
end
8 changes: 3 additions & 5 deletions test/test_statement.rb
Original file line number Diff line number Diff line change
Expand Up @@ -136,12 +136,10 @@ def test_bind_blob
stmt = SQLite3::Statement.new(@db, "insert into foo(text) values (?)")
stmt.bind_param(1, SQLite3::Blob.new("hello"))
stmt.execute
row = @db.execute("select * from foo")
stmt.close

assert_equal ["hello"], row.first
capture_io do # hush deprecation warning
assert_equal ["blob"], row.first.types
@db.prepare("select * from foo") do |v|
assert_equal ["hello"], v.first
assert_equal ["blob"], v.types
end
end

Expand Down