Class: SQLite3::Statement

Inherits:
Object
  • Object
show all
Defined in:
lib/sqlite3/statement.rb

Overview

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.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(db, sql, utf16 = false) ⇒ Statement

Create a new statement attached to the given Database instance, and which encapsulates the given SQL text. If the text contains more than one statement (i.e., separated by semicolons), then the #remainder property will be set to the trailing text.

Raises:

  • (ArgumentError)


33
34
35
36
37
38
39
40
41
# File 'lib/sqlite3/statement.rb', line 33

def initialize(db, sql, utf16 = false)
  raise ArgumentError, "nil argument passed as sql text" unless sql
  @db = db
  @driver = @db.driver
  @closed = false
  @results = @columns = nil
  result, @handle, @remainder = @driver.prepare(@db.handle, sql)
  Error.check(result, @db)
end

Instance Attribute Details

#handleObject (readonly)

The underlying opaque handle used to access the SQLite @driver.



27
28
29
# File 'lib/sqlite3/statement.rb', line 27

def handle
  @handle
end

#remainderObject (readonly)

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.



24
25
26
# File 'lib/sqlite3/statement.rb', line 24

def remainder
  @remainder
end

Instance Method Details

#active?Boolean

Returns true if the statement is currently active, meaning it has an open result set.

Returns:

  • (Boolean)


181
182
183
# File 'lib/sqlite3/statement.rb', line 181

def active?
  not @results.nil?
end

#bind_param(param, value) ⇒ Object

Binds value to the named (or positional) placeholder. If param is a Fixnum, it is treated as an index for a positional placeholder. Otherwise it is used as the name of the placeholder to bind to.

See also #bind_params.



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/sqlite3/statement.rb', line 86

def bind_param(param, value)
  must_be_open!
  reset! if active?
  if Fixnum === param
    case value
    when Bignum then
      @driver.bind_int64(@handle, param, value)
    when Integer then
      if value >= (2 ** 31)
        @driver.bind_int64(@handle, param, value)
      else
        @driver.bind_int(@handle, param, value)
      end
    when Numeric then
      @driver.bind_double(@handle, param, value.to_f)
    when Blob then
      @driver.bind_blob(@handle, param, value)
    when nil then
      @driver.bind_null(@handle, param)
    else
      @driver.bind_text(@handle, param, value)
    end
  else
    param = param.to_s
    param = ":#{param}" unless param[0] == ?:
    index = @driver.bind_parameter_index(@handle, param)
    raise Exception, "no such bind parameter '#{param}'" if index == 0
    bind_param index, value
  end
end

#bind_params(*bind_vars) ⇒ Object

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.



69
70
71
72
73
74
75
76
77
78
79
# File 'lib/sqlite3/statement.rb', line 69

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

#closeObject

Closes the statement by finalizing the underlying statement handle. The statement must not be used after being closed.



45
46
47
48
49
# File 'lib/sqlite3/statement.rb', line 45

def close
  must_be_open!
  @closed = true
  @driver.finalize(@handle)
end

#closed?Boolean

Returns true if the underlying statement has been closed.

Returns:

  • (Boolean)


52
53
54
# File 'lib/sqlite3/statement.rb', line 52

def closed?
  @closed
end

#columnsObject

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.



188
189
190
191
# File 'lib/sqlite3/statement.rb', line 188

def columns
   unless @columns
  return @columns
end

#execute(*bind_vars) ⇒ Object

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!.



131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/sqlite3/statement.rb', line 131

def execute(*bind_vars)
  must_be_open!
  reset! if active?

  bind_params(*bind_vars) unless bind_vars.empty?
  @results = ResultSet.new(@db, self)

  if block_given?
    yield @results
  else
    return @results
  end
end

#execute!(*bind_vars) ⇒ Object

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.



159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/sqlite3/statement.rb', line 159

def execute!(*bind_vars)
  result = execute(*bind_vars)
  rows = [] unless block_given?
  while row = result.next
    if block_given?
      yield row
    else
      rows << row
    end
  end
  rows
end

#must_be_open!Object

Performs a sanity check to ensure that the statement is not closed. If it is, an exception is raised.



223
224
225
226
227
# File 'lib/sqlite3/statement.rb', line 223

def must_be_open! # :nodoc:
  if @closed
    raise SQLite3::Exception, "cannot use a closed statement"
  end
end

#reset!(clear_result = true) ⇒ Object

Resets the statement. This is typically done internally, though it might occassionally be necessary to manually reset the statement.



174
175
176
177
# File 'lib/sqlite3/statement.rb', line 174

def reset!(clear_result=true)
  @driver.reset(@handle)
  @results = nil if clear_result
end

#typesObject

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.



196
197
198
199
# File 'lib/sqlite3/statement.rb', line 196

def types
   unless @types
  return @types
end