/**
* call-seq:
* step( vm ) -> hash | nil
*
* Steps through a single result for the given virtual machine. Returns a
* Hash object. If there was a valid row returned, the hash will contain
* a <tt>:row</tt> key, which maps to an array of values for that row.
* In addition, the hash will (nearly) always contain a <tt>:columns</tt>
* key (naming the columns in the result) and a <tt>:types</tt> key
* (giving the data types for each column).
*
* This will return +nil+ if there was an error previously.
*/
static VALUE
static_api_step( VALUE module, VALUE vm )
{
sqlite_vm *vm_ptr;
const char **values;
const char **metadata;
int columns;
int result;
int index;
VALUE hash;
VALUE value;
GetVM( vm_ptr, vm );
hash = rb_hash_new();
result = sqlite_step( vm_ptr,
&columns,
&values,
&metadata );
switch( result )
{
case SQLITE_BUSY:
static_raise_db_error( result, "busy in step" );
case SQLITE_ROW:
value = rb_ary_new2( columns );
for( index = 0; index < columns; index++ )
{
VALUE entry = Qnil;
if( values[index] != NULL )
entry = rb_str_new2( values[index] );
rb_ary_store( value, index, entry );
}
rb_hash_aset( hash, ID2SYM(idRow), value );
case SQLITE_DONE:
value = rb_ivar_get( vm, idColumns );
if( value == Qnil )
{
value = rb_ary_new2( columns );
for( index = 0; index < columns; index++ )
{
rb_ary_store( value, index, rb_str_new2( metadata[ index ] ) );
}
rb_ivar_set( vm, idColumns, value );
}
rb_hash_aset( hash, ID2SYM(idColumns), value );
value = rb_ivar_get( vm, idTypes );
if( value == Qnil )
{
value = rb_ary_new2( columns );
for( index = 0; index < columns; index++ )
{
VALUE item = Qnil;
if( metadata[ index+columns ] )
item = rb_str_new2( metadata[ index+columns ] );
rb_ary_store( value, index, item );
}
rb_ivar_set( vm, idTypes, value );
}
rb_hash_aset( hash, ID2SYM(idTypes), value );
break;
case SQLITE_ERROR:
case SQLITE_MISUSE:
{
char *msg = NULL;
sqlite_finalize( vm_ptr, &msg );
RDATA(vm)->dfree = NULL;
RDATA(vm)->data = NULL;
static_raise_db_error2( result, &msg );
}
/* "raise" doesn't return */
default:
static_raise_db_error( -1, "[BUG] unknown result %d from sqlite_step",
result );
/* "raise" doesn't return */
}
return hash;
}