Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
Файл: do_mysql.c Проект: NZX/do
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;
}