summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorJamis Buck <jamis@37signals.com>2005-02-07 17:23:53 +0000
committerJamis Buck <jamis@37signals.com>2005-02-07 17:23:53 +0000
commit4c3f433efc54403478cbc56d348773167ee5a775 (patch)
treee7784809e0ca71949b191018ebb3fa00b5f6fc51 /lib
parent372281cf9bef717f3a0b60167bc0fe1a35c6f352 (diff)
downloadthird_party-sqlite3-ruby-4c3f433efc54403478cbc56d348773167ee5a775.tar.gz
third_party-sqlite3-ruby-4c3f433efc54403478cbc56d348773167ee5a775.tar.xz
third_party-sqlite3-ruby-4c3f433efc54403478cbc56d348773167ee5a775.zip
Added Database#query and made it possible to close a statement from a resultset. This should make it easier to create a sqlite3 adapter for Og.
Diffstat (limited to 'lib')
-rw-r--r--lib/sqlite3/database.rb28
-rw-r--r--lib/sqlite3/resultset.rb17
-rw-r--r--lib/sqlite3/statement.rb22
-rw-r--r--lib/sqlite3/version.rb4
4 files changed, 67 insertions, 4 deletions
diff --git a/lib/sqlite3/database.rb b/lib/sqlite3/database.rb
index 4b42936..f126004 100644
--- a/lib/sqlite3/database.rb
+++ b/lib/sqlite3/database.rb
@@ -204,7 +204,7 @@ module SQLite3
# by the query. Otherwise, any results are accumulated into an array and
# returned wholesale.
#
- # See also #execute2, and #execute_batch for additional ways of
+ # See also #execute2, #query, and #execute_batch for additional ways of
# executing statements.
def execute( sql, *bind_vars )
prepare( sql ) do |stmt|
@@ -225,7 +225,7 @@ module SQLite3
# Thus, even if the query itself returns no rows, this method will always
# return at least one row--the names of the columns.
#
- # See also #execute, and #execute_batch for additional ways of
+ # See also #execute, #query, and #execute_batch for additional ways of
# executing statements.
def execute2( sql, *bind_vars )
prepare( sql ) do |stmt|
@@ -259,6 +259,30 @@ module SQLite3
nil
end
+ # This is a convenience method for creating a statement, binding
+ # paramters to it, and calling execute:
+ #
+ # result = db.query( "select * from foo where a=?", 5 )
+ # # is the same as
+ # result = db.prepare( "select * from foo where a=?" ).execute( 5 )
+ #
+ # You must be sure to call +close+ on the ResultSet instance that is
+ # returned, or you could have problems with locks on the table. If called
+ # with a block, +close+ will be invoked implicitly when the block
+ # terminates.
+ def query( sql, *bind_vars )
+ result = prepare( sql ).execute( *bind_vars )
+ if block_given?
+ begin
+ yield result
+ ensure
+ result.close
+ end
+ else
+ return result
+ end
+ end
+
# A convenience method for obtaining the first row of a result set, and
# discarding all others. It is otherwise identical to #execute.
#
diff --git a/lib/sqlite3/resultset.rb b/lib/sqlite3/resultset.rb
index bef2a0d..d90073c 100644
--- a/lib/sqlite3/resultset.rb
+++ b/lib/sqlite3/resultset.rb
@@ -80,6 +80,7 @@ module SQLite3
# Reset the cursor, so that a result set which has reached end-of-file
# can be rewound and reiterated.
def reset( *bind_params )
+ @stmt.must_be_open!
@driver.reset( @stmt.handle )
@stmt.bind_params( *bind_params )
@eof = false
@@ -107,6 +108,8 @@ module SQLite3
def next
return nil if @eof
+ @stmt.must_be_open!
+
unless @first_row
result = @driver.step( @stmt.handle )
check result
@@ -159,10 +162,24 @@ module SQLite3
end
end
+ # Closes the statement that spawned this result set.
+ # <em>Use with caution!</em> Closing a result set will automatically
+ # close any other result sets that were spawned from the same statement.
+ def close
+ @stmt.close
+ end
+
+ # Queries whether the underlying statement has been closed or not.
+ def closed?
+ @stmt.closed?
+ end
+
+ # Returns the types of the columns returned by this result set.
def types
@stmt.types
end
+ # Returns the names of the columns returned by this result set.
def columns
@stmt.columns
end
diff --git a/lib/sqlite3/statement.rb b/lib/sqlite3/statement.rb
index bad70db..af26d42 100644
--- a/lib/sqlite3/statement.rb
+++ b/lib/sqlite3/statement.rb
@@ -65,14 +65,24 @@ module SQLite3
def initialize( db, sql, utf16=false )
@db = db
@driver = @db.driver
+ @closed = false
result, @handle, @remainder = @driver.prepare( @db.handle, sql )
Error.check( result, @db )
end
+ # Closes the statement by finalizing the underlying statement
+ # handle. The statement must not be used after being closed.
def close
+ must_be_open!
+ @closed = true
@driver.finalize( @handle )
end
+ # Returns true if the underlying statement has been closed.
+ def closed?
+ @closed
+ end
+
# Binds the given variables to the corresponding placeholders in the SQL
# text.
#
@@ -104,6 +114,7 @@ module SQLite3
#
# See also #bind_params.
def bind_param( param, value )
+ must_be_open!
if Fixnum === param
case value
when Integer then
@@ -140,6 +151,7 @@ module SQLite3
#
# See also #bind_params, #execute!.
def execute( *bind_vars )
+ must_be_open!
@driver.reset( @handle ) if @results
bind_params *bind_vars unless bind_vars.empty?
@@ -199,6 +211,8 @@ module SQLite3
# that this will actually execute the SQL, which means it can be a
# (potentially) expensive operation.
def get_metadata
+ must_be_open!
+
@columns = []
@types = []
@@ -213,6 +227,14 @@ module SQLite3
end
private :get_metadata
+ # Performs a sanity check to ensure that the statement is not
+ # closed. If it is, an exception is raised.
+ def must_be_open! # :nodoc:
+ if @closed
+ raise SQLite3::Exception, "cannot use a closed statement"
+ end
+ end
+
end
end
diff --git a/lib/sqlite3/version.rb b/lib/sqlite3/version.rb
index 4ee8fc2..b6e22e1 100644
--- a/lib/sqlite3/version.rb
+++ b/lib/sqlite3/version.rb
@@ -35,8 +35,8 @@ module SQLite3
module Version
MAJOR = 1
- MINOR = 0
- TINY = 1
+ MINOR = 1
+ TINY = 0
STRING = [ MAJOR, MINOR, TINY ].join( "." )