VALUE do_sqlite3_cCommand_execute_non_query(int argc, VALUE *argv, VALUE self) { VALUE query = data_objects_build_query_from_args(self, argc, argv); VALUE connection = rb_iv_get(self, "@connection"); VALUE sqlite3_connection = rb_iv_get(connection, "@connection"); if (sqlite3_connection == Qnil) { rb_raise(eConnectionError, "This connection has already been closed."); } sqlite3 *db = NULL; Data_Get_Struct(sqlite3_connection, sqlite3, db); struct timeval start; char *error_message; int status; gettimeofday(&start, NULL); status = sqlite3_exec(db, rb_str_ptr_readonly(query), 0, 0, &error_message); if (status != SQLITE_OK) { do_sqlite3_raise_error(self, db, query); } data_objects_debug(connection, query, &start); int affected_rows = sqlite3_changes(db); do_int64 insert_id = sqlite3_last_insert_rowid(db); return rb_funcall(cSqlite3Result, ID_NEW, 3, self, INT2NUM(affected_rows), INT2NUM(insert_id)); }
VALUE do_postgres_cCommand_execute_reader(int argc, VALUE *argv, VALUE self) { VALUE connection = rb_iv_get(self, "@connection"); VALUE postgres_connection = rb_iv_get(connection, "@connection"); if (postgres_connection == Qnil) { rb_raise(eDO_ConnectionError, "This connection has already been closed."); } VALUE query = data_objects_build_query_from_args(self, argc, argv); PGconn *db = DATA_PTR(postgres_connection); PGresult *response = do_postgres_cCommand_execute(self, connection, db, query); int status = PQresultStatus(response); if(status != PGRES_TUPLES_OK && status != PGRES_COMMAND_OK) { do_postgres_raise_error(self, response, query); } int field_count = PQnfields(response); VALUE reader = rb_funcall(cDO_PostgresReader, DO_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)); rb_iv_set(reader, "@row_count", INT2NUM(PQntuples(response))); VALUE field_names = rb_ary_new(); VALUE field_types = rb_iv_get(self, "@field_types"); int infer_types = 0; 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(rb_eArgError, "Field-count mismatch. Expected %ld fields, but the query yielded %d", RARRAY_LEN(field_types), field_count); } int i; 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, do_postgres_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; }
VALUE do_sqlite3_cCommand_execute_reader(int argc, VALUE *argv, VALUE self) { VALUE query = data_objects_build_query_from_args(self, argc, argv); VALUE connection = rb_iv_get(self, "@connection"); VALUE sqlite3_connection = rb_iv_get(connection, "@connection"); if (sqlite3_connection == Qnil) { rb_raise(eConnectionError, "This connection has already been closed."); } sqlite3 *db = NULL; Data_Get_Struct(sqlite3_connection, sqlite3, db); sqlite3_stmt *sqlite3_reader; struct timeval start; int status; gettimeofday(&start, NULL); status = sqlite3_prepare_v2(db, rb_str_ptr_readonly(query), -1, &sqlite3_reader, 0); data_objects_debug(connection, query, &start); if (status != SQLITE_OK) { do_sqlite3_raise_error(self, db, query); } int field_count = sqlite3_column_count(sqlite3_reader); VALUE reader = rb_funcall(cSqlite3Reader, ID_NEW, 0); rb_iv_set(reader, "@reader", Data_Wrap_Struct(rb_cObject, 0, 0, sqlite3_reader)); rb_iv_set(reader, "@field_count", INT2NUM(field_count)); rb_iv_set(reader, "@connection", connection); VALUE field_types = rb_iv_get(self, "@field_types"); if (field_types == Qnil || RARRAY_LEN(field_types) == 0) { field_types = rb_ary_new(); } 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); } VALUE field_names = rb_ary_new(); int i; for (i = 0; i < field_count; i++) { rb_ary_push(field_names, rb_str_new2((char *)sqlite3_column_name(sqlite3_reader, i))); } rb_iv_set(reader, "@fields", field_names); rb_iv_set(reader, "@field_types", field_types); return reader; }
VALUE do_postgres_cCommand_execute_non_query(int argc, VALUE *argv, VALUE self) { VALUE connection = rb_iv_get(self, "@connection"); VALUE postgres_connection = rb_iv_get(connection, "@connection"); if (postgres_connection == Qnil) { rb_raise(eDO_ConnectionError, "This connection has already been closed."); } VALUE query = data_objects_build_query_from_args(self, argc, argv); PGconn *db = DATA_PTR(postgres_connection); PGresult *response; int status; response = do_postgres_cCommand_execute(self, connection, db, query); status = PQresultStatus(response); VALUE affected_rows = Qnil; VALUE insert_id = Qnil; if (status == PGRES_TUPLES_OK) { if (PQgetlength(response, 0, 0) == 0) { insert_id = Qnil; } else { insert_id = INT2NUM(atoi(PQgetvalue(response, 0, 0))); } affected_rows = INT2NUM(atoi(PQcmdTuples(response))); } else if (status == PGRES_COMMAND_OK) { insert_id = Qnil; affected_rows = INT2NUM(atoi(PQcmdTuples(response))); } else { do_postgres_raise_error(self, response, query); } PQclear(response); return rb_funcall(cDO_PostgresResult, DO_ID_NEW, 3, self, affected_rows, insert_id); }
VALUE do_mysql_cCommand_execute_non_query(int argc, VALUE *argv, VALUE self) { VALUE connection = rb_iv_get(self, "@connection"); VALUE mysql_connection = rb_iv_get(connection, "@connection"); if (mysql_connection == Qnil) { rb_raise(eConnectionError, "This connection has already been closed."); } MYSQL *db = DATA_PTR(mysql_connection); VALUE query = data_objects_build_query_from_args(self, argc, argv); MYSQL_RES *response = do_mysql_cCommand_execute(self, connection, db, query); my_ulonglong affected_rows = mysql_affected_rows(db); my_ulonglong insert_id = mysql_insert_id(db); mysql_free_result(response); if (((my_ulonglong)-1) == affected_rows) { return Qnil; } return rb_funcall(cMysqlResult, ID_NEW, 3, self, INT2NUM(affected_rows), insert_id == 0 ? Qnil : INT2NUM(insert_id)); }
VALUE do_mysql_cCommand_execute_reader(int argc, VALUE *argv, VALUE self) { VALUE connection = rb_iv_get(self, "@connection"); VALUE mysql_connection = rb_iv_get(connection, "@connection"); if (mysql_connection == Qnil) { rb_raise(eConnectionError, "This connection has already been closed."); } VALUE query = data_objects_build_query_from_args(self, argc, argv); MYSQL *db = DATA_PTR(mysql_connection); MYSQL_RES *response = do_mysql_cCommand_execute(self, connection, db, query); if (!response) { rb_raise(eConnectionError, "No result set received for a query that should yield one."); } unsigned int field_count = mysql_field_count(db); VALUE reader = rb_funcall(cMysqlReader, 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)); VALUE field_names = rb_ary_new(); VALUE field_types = rb_iv_get(self, "@field_types"); char guess_default_field_types = 0; if (field_types == Qnil || RARRAY_LEN(field_types) == 0) { 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); } MYSQL_FIELD *field; unsigned int i; 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 (guess_default_field_types == 1) { rb_ary_push(field_types, do_mysql_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; }