require 'sqlite3/errors' require 'sqlite3/resultset' class String def to_blob SQLite3::Blob.new( self ) end end module SQLite3 # A statement represents a prepared-but-unexecuted SQL query. It will rarely # (if ever) be instantiated directly by a client, and is most often obtained # via the Database#prepare method. class Statement include Enumerable # This is any text that followed the first valid SQL statement in the text # with which the statement was initialized. If there was no trailing text, # this will be the empty string. attr_reader :remainder # Binds the given variables to the corresponding placeholders in the SQL # text. # # See Database#execute for a description of the valid placeholder # syntaxes. # # Example: # # stmt = db.prepare( "select * from table where a=? and b=?" ) # stmt.bind_params( 15, "hello" ) # # See also #execute, #bind_param, Statement#bind_param, and # Statement#bind_params. def bind_params( *bind_vars ) index = 1 bind_vars.flatten.each do |var| if Hash === var var.each { |key, val| bind_param key, val } else bind_param index, var index += 1 end end end # Execute the statement. This creates a new ResultSet object for the # statement's virtual machine. If a block was given, the new ResultSet will # be yielded to it; otherwise, the ResultSet will be returned. # # Any parameters will be bound to the statement using #bind_params. # # Example: # # stmt = db.prepare( "select * from table" ) # stmt.execute do |result| # ... # end # # See also #bind_params, #execute!. def execute( *bind_vars ) reset! if active? || done? bind_params(*bind_vars) unless bind_vars.empty? @results = ResultSet.new(@connection, self) yield @results if block_given? @results end # Execute the statement. If no block was given, this returns an array of # rows returned by executing the statement. Otherwise, each row will be # yielded to the block. # # Any parameters will be bound to the statement using #bind_params. # # Example: # # stmt = db.prepare( "select * from table" ) # stmt.execute! do |row| # ... # end # # See also #bind_params, #execute. def execute!( *bind_vars, &block ) execute(*bind_vars) block_given? ? each(&block) : to_a end # Returns true if the statement is currently active, meaning it has an # open result set. def active? !done? end # Return an array of the column names for this statement. Note that this # may execute the statement in order to obtain the metadata; this makes it # a (potentially) expensive operation. def columns get_metadata unless @columns return @columns end def each loop do val = step break self if done? yield val end end # Return an array of the data types for each column in this statement. Note # that this may execute the statement in order to obtain the metadata; this # makes it a (potentially) expensive operation. def types must_be_open! get_metadata unless @types @types end # A convenience method for obtaining the metadata about the query. Note # that this will actually execute the SQL, which means it can be a # (potentially) expensive operation. def get_metadata @columns = [] @types = [] column_count.times do |column| @columns << column_name(column) @types << column_decltype(column) end @columns.freeze @types.freeze 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