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, utf_16 = 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)


20
21
22
23
24
25
26
27
28
29
# File 'lib/sqlite3/statement.rb', line 20

def initialize(db, sql, utf_16 = false)
  raise ArgumentError, "nil argument passed as sql text" unless sql
  @db = db
  @driver = @db.driver
  @closed = false
  @results = @columns = nil
  @utf_16 = utf_16
  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.



14
15
16
# File 'lib/sqlite3/statement.rb', line 14

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.



11
12
13
# File 'lib/sqlite3/statement.rb', line 11

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)


167
168
169
# File 'lib/sqlite3/statement.rb', line 167

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.



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/sqlite3/statement.rb', line 74

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 nil then
      @driver.bind_null(@handle, param)
    else
      @driver.bind_string(@handle, param, value.to_s)
    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.



57
58
59
60
61
62
63
64
65
66
67
# File 'lib/sqlite3/statement.rb', line 57

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.



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

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

#closed?Boolean

Returns true if the underlying statement has been closed.

Returns:

  • (Boolean)


40
41
42
# File 'lib/sqlite3/statement.rb', line 40

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.



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

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



117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/sqlite3/statement.rb', line 117

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

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

  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.



145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/sqlite3/statement.rb', line 145

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.



209
210
211
212
213
# File 'lib/sqlite3/statement.rb', line 209

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.



160
161
162
163
# File 'lib/sqlite3/statement.rb', line 160

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.



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

def types
   unless @types
  return @types
end