/** * 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; }