Class: Mysql::Stmt

Inherits:
Object
  • Object
show all
Defined in:
lib/ffi-mysql/stmt.rb,
lib/ffi-mysql/constants.rb

Overview

A MySQL statement.

Constant Summary collapse

CURSOR_TYPE_NO_CURSOR =

Cursor type

0
CURSOR_TYPE_READ_ONLY =
1
NO_DATA =
100
DATA_TRUNCATED =
101

Instance Method Summary collapse

Constructor Details

#initialize(mysql) ⇒ Stmt

Returns a new instance of Stmt.

Raises:



169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/ffi-mysql/stmt.rb', line 169

def initialize( mysql )
    @mysql = mysql
    @stmt = C::mysql_stmt_init(mysql)
    @params = []
    raise Error, error_msg if @stmt.nil? or @stmt.null?
    ObjectSpace.define_finalizer( self, Stmt.finalizer(@stmt) )

    _true = FFI::MemoryPointer.new(:int)
    _true.write_int(1)
    if C::mysql_stmt_attr_set(@stmt, :update_max_length, _true) != 0
        raise Error, error_msg
    end
end

Instance Method Details

#affected_rowsInteger

Returns the number of rows changed by the latest execution of this statement.

Returns:

  • (Integer)

    the number of rows changed by the latest execution of this statement

Raises:



318
319
320
321
# File 'lib/ffi-mysql/stmt.rb', line 318

def affected_rows
    raise Error, "Statment already closed" unless @stmt
    C::mysql_stmt_affected_rows(@stmt)
end

#bind_result(*args) ⇒ self

Associated output columns with buffer.

Parameters:

  • classes (Class)

    of the result columns like Fixnum, String, …

Returns:

  • (self)

Raises:



265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
# File 'lib/ffi-mysql/stmt.rb', line 265

def bind_result(*args)
    raise Error, "Statment already closed" unless @stmt
    if args.size != @result_binds.size
        raise Error, "result value count (#{@result_binds.size}) != number of arguments (#{args.size})"
    end

    fields = @result.fetch_fields
    @result_binds.each_with_index do |bind, i|
        bind.set_bind_result( args[i], fields[i] )
        if C::mysql_stmt_bind_result( @stmt, @result_binds_ary ) != 0
            raise Error, error_msg
        end
    end
    self
end

#closeObject

Closes the statement.



184
185
186
187
188
# File 'lib/ffi-mysql/stmt.rb', line 184

def close
    C::mysql_stmt_close(@stmt)
    @stmt = nil
    ObjectSpace.undefine_finalizer(self)
end

#data_seek(offset) ⇒ self

Seeks to an arbitrary row in the result set.

Parameters:

  • the (offset)

    row to seek to

Returns:

  • (self)

Raises:



309
310
311
312
313
# File 'lib/ffi-mysql/stmt.rb', line 309

def data_seek( offset )
    raise Error, "Statment already closed" unless @stmt
    C::mysql_stmt_data_seek( @stmt, offset )
    self
end

#each {|Array| ... } ⇒ Object

Iterates over all rows in this result set.

Yields:

  • (Array)

    Called once for each row in this result set

See Also:

  • fetch_row


300
301
302
303
304
# File 'lib/ffi-mysql/stmt.rb', line 300

def each
    while row = fetch
        yield row
    end
end

#execute(*args) ⇒ self

Executes the statement.

Parameters:

  • args

    statement parameters

Returns:

  • (self)

Raises:



224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
# File 'lib/ffi-mysql/stmt.rb', line 224

def execute(*args)
    raise Error, "Statment already closed" unless @stmt
    if args.size != @param_binds.size
        raise Error, "param_count(#{@param_binds.size}) != number of arguments(#{args.size})"
    end

    free_result
    unless @param_binds.empty?
        @param_binds.each_with_index do |bind, i|
            bind.set_param args[i]
        end
        if C::mysql_stmt_bind_param(@stmt, @param_binds_ary) != 0
            raise Error, error_msg
        end
    end

    if C::mysql_stmt_execute(@stmt) != 0
        raise Error, error_msg
    end

    if @result
        if C::mysql_stmt_store_result(@stmt) != 0
            raise Error, error_msg
        end

        fields = @result.fetch_fields
        @result_binds.each_with_index do |bind, i|
            bind.set_result fields[i]
        end

        if C::mysql_stmt_bind_result(@stmt, @result_binds_ary) != 0
            raise Error, error_msg
        end
    end

    self
end

#fetchArray

Returns the next row.

Returns:

  • (Array)

    the next row.

Raises:



282
283
284
285
286
287
288
289
290
291
292
293
294
295
# File 'lib/ffi-mysql/stmt.rb', line 282

def fetch
    raise Error, "Statment already closed" unless @stmt
    r = C::mysql_stmt_fetch(@stmt)
    case r
    when NO_DATA
        nil
    when DATA_TRUNCATED
        raise Error, "unexpectedly data truncated"
    when 1
        raise Error, error_msg
    else
        @result_binds.map{|bind| bind.value}
    end
end

#field_countInteger

Returns the number of columns of this statement.

Returns:

  • (Integer)

    the number of columns of this statement

Raises:



324
325
326
327
# File 'lib/ffi-mysql/stmt.rb', line 324

def field_count
    raise Error, "Statment already closed" unless @stmt
    C::mysql_stmt_field_count(@stmt)
end

#free_resultself

Frees the current result of this statement.

Returns:

  • (self)

Raises:



331
332
333
334
335
336
# File 'lib/ffi-mysql/stmt.rb', line 331

def free_result
    raise Error, "Statment already closed" unless @stmt
    if C::mysql_stmt_free_result(@stmt) != 0
        raise Error, error_msg
    end
end

#insert_idInteger

Returns the value of an auto-increment column of the last INSERT or UPDATE statement.

Returns:

  • (Integer)

    the value of an auto-increment column of the last INSERT or UPDATE statement

Raises:



380
381
382
383
# File 'lib/ffi-mysql/stmt.rb', line 380

def insert_id
    raise Error, "Statment already closed" unless @stmt
    C::mysql_stmt_insert_id(@stmt)
end

#num_rowsInteger

Returns the number of rows of this statement.

Returns:

  • (Integer)

    the number of rows of this statement

Raises:



339
340
341
342
# File 'lib/ffi-mysql/stmt.rb', line 339

def num_rows
    raise Error, "Statment already closed" unless @stmt
    C::mysql_stmt_num_rows(@stmt)
end

#param_countInteger

Returns the number of parameters of this statement.

Returns:

  • (Integer)

    the number of parameters of this statement

Raises:



345
346
347
348
# File 'lib/ffi-mysql/stmt.rb', line 345

def param_count
    raise Error, "Statment already closed" unless @stmt
    C::mysql_stmt_param_count(@stmt)
end

#prepare(stmt) ⇒ self

Preparse the statement

Parameters:

  • stmt (String)

    the SQL statement

Returns:

  • (self)

Raises:



193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/ffi-mysql/stmt.rb', line 193

def prepare(stmt)
    raise Error, "Statment already closed" unless @stmt
    if C::mysql_stmt_prepare(@stmt, stmt, stmt.size) != 0
        raise Error, error_msg
    end

    nparams = param_count
    @param_binds_ary = FFI::MemoryPointer.new C::Bind, nparams, true
    @param_binds = (0...nparams).map {|i|
        C::Bind.new(FFI::Pointer.new(C::Bind, @param_binds_ary.address + i * C::Bind.size))
    }

    if @result = 
        fields = @result.fetch_fields
        @result_binds_ary = FFI::MemoryPointer.new C::Bind, fields.size, true
        @result_binds = (0...fields.size).map{|i|
            bind = C::Bind.new(FFI::Pointer.new(C::Bind, @result_binds_ary.address + i * C::Bind.size))
            bind.prepare_result( fields[i] )
            bind
        }
    else
        @result_binds_ary = nil
        @result_binds = []
    end

    self
end

#result_metadataResult

Returns the result metadata of the current statement.

Returns:

  • (Result)

    the result metadata of the current statement

Raises:



365
366
367
368
369
370
371
372
373
374
375
376
# File 'lib/ffi-mysql/stmt.rb', line 365

def 
    raise Error, "Statment already closed" unless @stmt
    result = C::(@stmt)
    if result.nil? or result.null?
        if C::mysql_stmt_errno(@stmt) != 0
            raise Error, error_msg
        end
        nil
    else
        Result.new(@mysql, result)
    end
end

#row_seek(offset) ⇒ Integer

Sets the position of the row cursor.

Parameters:

  • offset (Integer)

    the new position of the row cursor

Returns:

  • (Integer)

    the former position of the row cursor

Raises:



359
360
361
362
# File 'lib/ffi-mysql/stmt.rb', line 359

def row_seek( offset )
    raise Error, "Statment already closed" unless @stmt
    C::mysql_stmt_row_seek(@stmt, offset)
end

#row_tellInteger

Returns the number of the current row of the most recent result.

Returns:

  • (Integer)

    the number of the current row of the most recent result

Raises:



351
352
353
354
# File 'lib/ffi-mysql/stmt.rb', line 351

def row_tell
    raise Error, "Statment already closed" unless @stmt
    C::mysql_stmt_row_tell(@stmt)
end

#sqlstateString

Returns the SQLSTATE error code for this statement.

Returns:

  • (String)

    the SQLSTATE error code for this statement

Raises:



386
387
388
389
# File 'lib/ffi-mysql/stmt.rb', line 386

def sqlstate
    raise Error, "Statment already closed" unless @stmt
    C::mysql_stmt_sqlstate(@stmt)
end