static VALUE cCommand_execute_reader(int argc, VALUE *argv[], VALUE self) { VALUE reader, query; VALUE field_names, field_types; int i; int field_count; int infer_types = 0; VALUE connection = rb_iv_get(self, "@connection"); VALUE postgres_connection = rb_iv_get(connection, "@connection"); if (Qnil == postgres_connection) { rb_raise(eConnectionError, "This connection has already been closed."); } PGconn *db = DATA_PTR(postgres_connection); PGresult *response; query = build_query_from_args(self, argc, argv); response = cCommand_execute(self, db, query); if ( PQresultStatus(response) != PGRES_TUPLES_OK ) { raise_error(self, response, query); } field_count = PQnfields(response); reader = rb_funcall(cReader, ID_NEW, 0); rb_iv_set(reader, "@connection", connection); rb_iv_set(reader, "@reader", Data_Wrap_Struct(rb_cObject, 0, 0, response)); rb_iv_set(reader, "@field_count", INT2NUM(field_count)); rb_iv_set(reader, "@row_count", INT2NUM(PQntuples(response))); field_names = rb_ary_new(); field_types = rb_iv_get(self, "@field_types"); if ( field_types == Qnil || 0 == RARRAY_LEN(field_types) ) { field_types = rb_ary_new(); infer_types = 1; } else if (RARRAY_LEN(field_types) != field_count) { // Whoops... wrong number of types passed to set_types. Close the reader and raise // and error rb_funcall(reader, rb_intern("close"), 0); rb_raise(eArgumentError, "Field-count mismatch. Expected %ld fields, but the query yielded %d", RARRAY_LEN(field_types), field_count); } for ( i = 0; i < field_count; i++ ) { rb_ary_push(field_names, rb_str_new2(PQfname(response, i))); if ( infer_types == 1 ) { rb_ary_push(field_types, infer_ruby_type(PQftype(response, i))); } } rb_iv_set(reader, "@position", INT2NUM(0)); rb_iv_set(reader, "@fields", field_names); rb_iv_set(reader, "@field_types", field_types); return reader; }
static VALUE cDO_OracleCommand_execute_reader(int argc, VALUE *argv[], VALUE self) { VALUE reader, query; VALUE field_names, field_types; VALUE column_metadata, column, column_name; int i; long field_count; int infer_types = 0; VALUE cursor = rb_funcall2(self, DO_ID_EXECUTE, argc, (VALUE *)argv); if (rb_obj_class(cursor) != cOCI8_Cursor) { rb_raise(eArgumentError, "\"%s\" is invalid SELECT query", StringValuePtr(query)); } column_metadata = rb_funcall(cursor, DO_ID_COLUMN_METADATA, 0); field_count = RARRAY_LEN(column_metadata); // reduce field_count by 1 if RAW_RNUM_ is present as last column // (generated by DataMapper to simulate LIMIT and OFFSET) column = rb_ary_entry(column_metadata, field_count-1); column_name = rb_funcall(column, DO_ID_NAME, 0); if (strncmp(RSTRING_PTR(column_name), "RAW_RNUM_", RSTRING_LEN(column_name)) == 0) field_count--; reader = rb_funcall(cDO_OracleReader, DO_ID_NEW, 0); rb_iv_set(reader, "@reader", cursor); rb_iv_set(reader, "@field_count", INT2NUM(field_count)); field_names = rb_ary_new(); field_types = rb_iv_get(self, "@field_types"); if ( field_types == Qnil || 0 == RARRAY_LEN(field_types) ) { field_types = rb_ary_new(); infer_types = 1; } else if (RARRAY_LEN(field_types) != field_count) { // Whoops... wrong number of types passed to set_types. Close the reader and raise // and error rb_funcall(reader, DO_ID_CLOSE, 0); rb_raise(eArgumentError, "Field-count mismatch. Expected %ld fields, but the query yielded %ld", RARRAY_LEN(field_types), field_count); } for ( i = 0; i < field_count; i++ ) { column = rb_ary_entry(column_metadata, i); column_name = rb_funcall(column, DO_ID_NAME, 0); rb_ary_push(field_names, column_name); if ( infer_types == 1 ) { rb_ary_push(field_types, infer_ruby_type(rb_iv_get(column, "@data_type"), rb_funcall(column, DO_ID_PRECISION, 0), rb_funcall(column, DO_ID_SCALE, 0)) ); } } rb_iv_set(reader, "@position", INT2NUM(0)); rb_iv_set(reader, "@fields", field_names); rb_iv_set(reader, "@field_types", field_types); rb_iv_set(reader, "@last_row", Qfalse); return reader; }
static VALUE cCommand_execute_reader(int argc, VALUE *argv, VALUE self) { VALUE query, reader; VALUE field_names, field_types; unsigned int field_count; unsigned int i; char guess_default_field_types = 0; VALUE connection = rb_iv_get(self, "@connection"); VALUE mysql_connection = rb_iv_get(connection, "@connection"); if (Qnil == mysql_connection) { rb_raise(eConnectionError, "This connection has already been closed."); } MYSQL *db = DATA_PTR(mysql_connection); MYSQL_RES *response = 0; MYSQL_FIELD *field; query = build_query_from_args(self, argc, argv); response = cCommand_execute(self, connection, db, query); if (!response) { return Qnil; } field_count = mysql_field_count(db); reader = rb_funcall(cReader, ID_NEW, 0); rb_iv_set(reader, "@connection", connection); rb_iv_set(reader, "@reader", Data_Wrap_Struct(rb_cObject, 0, 0, response)); rb_iv_set(reader, "@opened", Qfalse); rb_iv_set(reader, "@field_count", INT2NUM(field_count)); field_names = rb_ary_new(); field_types = rb_iv_get(self, "@field_types"); if ( field_types == Qnil || 0 == RARRAY_LEN(field_types) ) { field_types = rb_ary_new(); guess_default_field_types = 1; } else if (RARRAY_LEN(field_types) != field_count) { // Whoops... wrong number of types passed to set_types. Close the reader and raise // and error rb_funcall(reader, rb_intern("close"), 0); rb_raise(rb_eArgError, "Field-count mismatch. Expected %ld fields, but the query yielded %d", RARRAY_LEN(field_types), field_count); } for(i = 0; i < field_count; i++) { field = mysql_fetch_field_direct(response, i); rb_ary_push(field_names, rb_str_new2(field->name)); if (1 == guess_default_field_types) { rb_ary_push(field_types, infer_ruby_type(field)); } } rb_iv_set(reader, "@fields", field_names); rb_iv_set(reader, "@field_types", field_types); if (rb_block_given_p()) { rb_yield(reader); rb_funcall(reader, rb_intern("close"), 0); } return reader; }