static PGresult* cCommand_execute_sync(VALUE self, PGconn *db, VALUE query) { PGresult *response; struct timeval start; char* str = StringValuePtr(query); while ((response = PQgetResult(db)) != NULL) { PQclear(response); } gettimeofday(&start, NULL); response = PQexec(db, str); if (response == NULL) { if(PQstatus(db) != CONNECTION_OK) { PQreset(db); if (PQstatus(db) == CONNECTION_OK) { response = PQexec(db, str); } else { VALUE connection = rb_iv_get(self, "@connection"); full_connect(connection, db); response = PQexec(db, str); } } if(response == NULL) { rb_raise(eConnectionError, PQerrorMessage(db)); } } data_objects_debug(query, &start); return response; }
static VALUE cDO_OracleCommand_execute_ensure(cDO_OracleCommand_execute_try_t *arg) { if (SYM2ID(arg->statement_type) != DO_ID_SELECT_STMT) rb_funcall(arg->cursor, DO_ID_CLOSE, 0); // Log SQL and execution time data_objects_debug(arg->connection, arg->sql, &(arg->start)); return Qnil; }
PGresult * do_postgres_cCommand_execute_async(VALUE self, VALUE connection, PGconn *db, VALUE query) { PGresult *response; char* str = StringValuePtr(query); while ((response = PQgetResult(db))) { PQclear(response); } struct timeval start; int retval; gettimeofday(&start, NULL); retval = PQsendQuery(db, str); if (!retval) { if (PQstatus(db) != CONNECTION_OK) { PQreset(db); if (PQstatus(db) == CONNECTION_OK) { retval = PQsendQuery(db, str); } else { do_postgres_full_connect(connection, db); retval = PQsendQuery(db, str); } } if (!retval) { rb_raise(eDO_ConnectionError, "%s", PQerrorMessage(db)); } } int socket_fd = PQsocket(db); fd_set rset; while (1) { FD_ZERO(&rset); FD_SET(socket_fd, &rset); retval = rb_thread_select(socket_fd + 1, &rset, NULL, NULL, NULL); if (retval < 0) { rb_sys_fail(0); } if (retval == 0) { continue; } if (PQconsumeInput(db) == 0) { rb_raise(eDO_ConnectionError, "%s", PQerrorMessage(db)); } if (PQisBusy(db) == 0) { break; } } data_objects_debug(connection, query, &start); return PQgetResult(db); }
PGresult * do_postgres_cCommand_execute_sync(VALUE self, VALUE connection, PGconn *db, VALUE query) { char *str = StringValuePtr(query); PGresult *response; while ((response = PQgetResult(db))) { PQclear(response); } struct timeval start; gettimeofday(&start, NULL); response = PQexec(db, str); if (!response) { if (PQstatus(db) != CONNECTION_OK) { PQreset(db); if (PQstatus(db) == CONNECTION_OK) { response = PQexec(db, str); } else { do_postgres_full_connect(connection, db); response = PQexec(db, str); } } if(!response) { rb_raise(eDO_ConnectionError, PQerrorMessage(db)); } } data_objects_debug(connection, query, &start); return response; }
static VALUE cCommand_execute_non_query(int argc, VALUE *argv, VALUE self) { sqlite3 *db; char *error_message; int status; int affected_rows; int insert_id; VALUE conn_obj; VALUE query; struct timeval start; query = build_query_from_args(self, argc, argv); conn_obj = rb_iv_get(self, "@connection"); Data_Get_Struct(rb_iv_get(conn_obj, "@connection"), sqlite3, db); gettimeofday(&start, NULL); status = sqlite3_exec(db, StringValuePtr(query), 0, 0, &error_message); if ( status != SQLITE_OK ) { rb_raise(eSqlite3Error, "%s\nQuery: %s", sqlite3_errmsg(db), StringValuePtr(query)); } data_objects_debug(query, &start); affected_rows = sqlite3_changes(db); insert_id = sqlite3_last_insert_rowid(db); return rb_funcall(cResult, ID_NEW, 3, self, INT2NUM(affected_rows), INT2NUM(insert_id)); }
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)); }
static VALUE cCommand_execute_reader(int argc, VALUE *argv, VALUE self) { sqlite3 *db; sqlite3_stmt *sqlite3_reader; int status; int field_count; int i; VALUE reader; VALUE conn_obj; VALUE query; VALUE field_names, field_types; struct timeval start; conn_obj = rb_iv_get(self, "@connection"); Data_Get_Struct(rb_iv_get(conn_obj, "@connection"), sqlite3, db); query = build_query_from_args(self, argc, argv); gettimeofday(&start, NULL); status = sqlite3_prepare_v2(db, StringValuePtr(query), -1, &sqlite3_reader, 0); data_objects_debug(query, &start); if ( status != SQLITE_OK ) { rb_raise(eSqlite3Error, "%s\nQuery: %s", sqlite3_errmsg(db), StringValuePtr(query)); } field_count = sqlite3_column_count(sqlite3_reader); reader = rb_funcall(cReader, 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)); field_names = rb_ary_new(); field_types = rb_iv_get(self, "@field_types"); // if ( field_types == Qnil ) { // field_types = rb_ary_new(); // } if ( field_types == Qnil || 0 == RARRAY_LEN(field_types) ) { 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(eSqlite3Error, "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((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_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; }
MYSQL_RES *do_mysql_cCommand_execute_async(VALUE self, VALUE connection, MYSQL *db, VALUE query) { int retval; if ((retval = mysql_ping(db)) && mysql_errno(db) == CR_SERVER_GONE_ERROR) { do_mysql_full_connect(connection, db); } struct timeval start; const char *str = rb_str_ptr_readonly(query); long len = rb_str_len(query); gettimeofday(&start, NULL); retval = mysql_send_query(db, str, len); CHECK_AND_RAISE(retval, query); int socket_fd = db->net.fd; fd_set rset; while (1) { FD_ZERO(&rset); FD_SET(socket_fd, &rset); retval = rb_thread_select(socket_fd + 1, &rset, NULL, NULL, NULL); if (retval < 0) { rb_sys_fail(0); } if (retval == 0) { continue; } if (db->status == MYSQL_STATUS_READY) { break; } } retval = mysql_read_query_result(db); CHECK_AND_RAISE(retval, query); data_objects_debug(connection, query, &start); MYSQL_RES *result = mysql_store_result(db); if (!result) { CHECK_AND_RAISE(mysql_errno(db), query); } return result; }
static MYSQL_RES* cCommand_execute_sync(VALUE self, VALUE connection, MYSQL* db, VALUE query) { int retval; struct timeval start; const char* str = rb_str_ptr_readonly(query); int len = rb_str_len(query); if(mysql_ping(db) && mysql_errno(db) == CR_SERVER_GONE_ERROR) { // Ok, we do one more try here by doing a full connect VALUE connection = rb_iv_get(self, "@connection"); full_connect(connection, db); } gettimeofday(&start, NULL); retval = mysql_real_query(db, str, len); data_objects_debug(connection, query, &start); CHECK_AND_RAISE(retval, query); return mysql_store_result(db); }
// We can add custom information to error messages using this function // if we think it matters static void raise_mysql_error(VALUE connection, MYSQL *db, int mysql_error_code, char* str) { char *mysql_error_message = (char *)mysql_error(db); int length = strlen(mysql_error_message) + 25; // length of " (mysql_error_code=0000)" char *error_message; if(str) { error_message = (char *)calloc(length + strlen(str) + 8, sizeof(char)); sprintf(error_message, "%s (mysql_error_code=%04d)\nQuery: %s", mysql_error_message, mysql_error_code, str); } else { error_message = (char *)calloc(length, sizeof(char)); sprintf(error_message, "%s (mysql_error_code=%04d)", mysql_error_message, mysql_error_code); } data_objects_debug(rb_str_new2(error_message)); switch(mysql_error_code) { case CR_UNKNOWN_ERROR: case CR_SOCKET_CREATE_ERROR: case CR_CONNECTION_ERROR: case CR_CONN_HOST_ERROR: case CR_IPSOCK_ERROR: case CR_UNKNOWN_HOST: case CR_SERVER_GONE_ERROR: case CR_VERSION_ERROR: case CR_OUT_OF_MEMORY: case CR_WRONG_HOST_INFO: case CR_LOCALHOST_CONNECTION: case CR_TCP_CONNECTION: case CR_SERVER_HANDSHAKE_ERR: case CR_SERVER_LOST: case CR_COMMANDS_OUT_OF_SYNC: case CR_NAMEDPIPE_CONNECTION: case CR_NAMEDPIPEWAIT_ERROR: case CR_NAMEDPIPEOPEN_ERROR: case CR_NAMEDPIPESETSTATE_ERROR: case CR_CANT_READ_CHARSET: case CR_NET_PACKET_TOO_LARGE: case CR_EMBEDDED_CONNECTION: case CR_PROBE_SLAVE_STATUS: case CR_PROBE_SLAVE_HOSTS: case CR_PROBE_SLAVE_CONNECT: case CR_PROBE_MASTER_CONNECT: case CR_SSL_CONNECTION_ERROR: case CR_MALFORMED_PACKET: case CR_WRONG_LICENSE: case CR_NULL_POINTER: case CR_NO_PREPARE_STMT: case CR_PARAMS_NOT_BOUND: case CR_DATA_TRUNCATED: case CR_NO_PARAMETERS_EXISTS: case CR_INVALID_PARAMETER_NO: case CR_INVALID_BUFFER_USE: case CR_UNSUPPORTED_PARAM_TYPE: case CR_SHARED_MEMORY_CONNECTION: case CR_SHARED_MEMORY_CONNECT_REQUEST_ERROR: case CR_SHARED_MEMORY_CONNECT_ANSWER_ERROR: case CR_SHARED_MEMORY_CONNECT_FILE_MAP_ERROR: case CR_SHARED_MEMORY_CONNECT_MAP_ERROR: case CR_SHARED_MEMORY_FILE_MAP_ERROR: case CR_SHARED_MEMORY_MAP_ERROR: case CR_SHARED_MEMORY_EVENT_ERROR: case CR_SHARED_MEMORY_CONNECT_ABANDONED_ERROR: case CR_SHARED_MEMORY_CONNECT_SET_ERROR: case CR_CONN_UNKNOW_PROTOCOL: case CR_INVALID_CONN_HANDLE: case CR_SECURE_AUTH: case CR_FETCH_CANCELED: case CR_NO_DATA: case CR_NO_STMT_METADATA: #if MYSQL_VERSION_ID >= 50000 case CR_NO_RESULT_SET: case CR_NOT_IMPLEMENTED: #endif { break; } default: { // Hmmm break; } } rb_raise(eMysqlError, error_message); }