VALUE do_postgres_cConnection_quote_byte_array(VALUE self, VALUE string) { PGconn *db = DATA_PTR(rb_iv_get(self, "@connection")); const unsigned char *source = (unsigned char *)rb_str_ptr_readonly(string); size_t source_len = rb_str_len(string); unsigned char *escaped; unsigned char *escaped_quotes; size_t quoted_length = 0; VALUE result; // Allocate space for the escaped version of 'string' // http://www.postgresql.org/docs/8.3/static/libpq-exec.html#LIBPQ-EXEC-ESCAPE-STRING escaped = PQescapeByteaConn(db, source, source_len, "ed_length); if(!escaped) { rb_memerror(); } if (!(escaped_quotes = calloc(quoted_length + 1, sizeof(unsigned char)))) { rb_memerror(); } memcpy(escaped_quotes + 1, escaped, quoted_length * sizeof(unsigned char)); // Wrap the escaped string in single-quotes, this is DO's convention (replace trailing \0) escaped_quotes[0] = escaped_quotes[quoted_length] = '\''; result = rb_str_new((const char *)escaped_quotes, quoted_length + 1); PQfreemem(escaped); free(escaped_quotes); return result; }
VALUE cConnection_quote_string(VALUE self, VALUE string) { MYSQL *db = DATA_PTR(rb_iv_get(self, "@connection")); const char *source = rb_str_ptr_readonly(string); unsigned long source_len = rb_str_len(string); // Allocate space for the escaped version of 'string'. Use + 3 allocate space for null term. // and the leading and trailing single-quotes. // Thanks to http://www.browardphp.com/mysql_manual_en/manual_MySQL_APIs.html#mysql_real_escape_string char *escaped = calloc((source_len * 2) + 3, sizeof(char)); if (!escaped) { return Qnil; } unsigned long quoted_length; VALUE result; // Escape 'source' using the current encoding in use on the conection 'db' quoted_length = mysql_real_escape_string(db, escaped + 1, source, source_len); // Wrap the escaped string in single-quotes, this is DO's convention escaped[0] = escaped[quoted_length + 1] = '\''; // We don't want to use the internal encoding, because this needs // to go into the database in the connection encoding result = DO_STR_NEW(escaped, quoted_length + 2, FIX2INT(rb_iv_get(self, "@encoding_id")), NULL); free(escaped); return result; }
static VALUE cConnection_quote_string(VALUE self, VALUE string) { PGconn *db = DATA_PTR(rb_iv_get(self, "@connection")); const char *source = rb_str_ptr_readonly(string); size_t source_len = rb_str_len(string); char *escaped; size_t quoted_length = 0; VALUE result; // Allocate space for the escaped version of 'string' // http://www.postgresql.org/docs/8.3/static/libpq-exec.html#LIBPQ-EXEC-ESCAPE-STRING escaped = (char *)calloc(source_len * 2 + 3, sizeof(char)); // Escape 'source' using the current charset in use on the conection 'db' quoted_length = PQescapeStringConn(db, escaped + 1, source, source_len, NULL); // Wrap the escaped string in single-quotes, this is DO's convention escaped[quoted_length + 1] = escaped[0] = '\''; result = DO_STR_NEW(escaped, quoted_length + 2, FIX2INT(rb_iv_get(self, "@encoding_id"))); free(escaped); return result; }
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); }
VALUE do_postgres_cConnection_quote_string(VALUE self, VALUE string) { PGconn *db = DATA_PTR(rb_iv_get(self, "@connection")); const char *source = rb_str_ptr_readonly(string); int error = 0; long source_len = rb_str_len(string); long buffer_len = source_len * 2 + 3; // Overflow check if(buffer_len <= source_len) { rb_raise(rb_eArgError, "Input string is too large to be safely quoted"); } char *escaped; // Allocate space for the escaped version of 'string' // http://www.postgresql.org/docs/8.3/static/libpq-exec.html#LIBPQ-EXEC-ESCAPE-STRING if (!(escaped = calloc(buffer_len, sizeof(char)))) { rb_memerror(); } long quoted_length; VALUE result; // Escape 'source' using the current charset in use on the conection 'db' quoted_length = PQescapeStringConn(db, escaped + 1, source, source_len, &error); if(error) { rb_raise(eDO_DataError, "%s", PQerrorMessage(db)); } // Wrap the escaped string in single-quotes, this is DO's convention escaped[0] = escaped[quoted_length + 1] = '\''; result = DATA_OBJECTS_STR_NEW(escaped, quoted_length + 2, FIX2INT(rb_iv_get(self, "@encoding_id")), NULL); free(escaped); return result; }
static void data_objects_debug(VALUE string, struct timeval* start) { struct timeval stop; char *message; const char *query = rb_str_ptr_readonly(string); size_t length = rb_str_len(string); char total_time[32]; do_int64 duration = 0; VALUE logger = rb_funcall(mPostgres, ID_LOGGER, 0); int log_level = NUM2INT(rb_funcall(logger, ID_LEVEL, 0)); if (0 == log_level) { gettimeofday(&stop, NULL); duration = (stop.tv_sec - start->tv_sec) * 1000000 + stop.tv_usec - start->tv_usec; snprintf(total_time, 32, "%.6f", duration / 1000000.0); message = (char *)calloc(length + strlen(total_time) + 4, sizeof(char)); snprintf(message, length + strlen(total_time) + 4, "(%s) %s", total_time, query); rb_funcall(logger, ID_DEBUG, 1, rb_str_new(message, length + strlen(total_time) + 3)); } }
static VALUE cConnection_quote_string(VALUE self, VALUE string) { MYSQL *db = DATA_PTR(rb_iv_get(self, "@connection")); const char *source = rb_str_ptr_readonly(string); size_t source_len = rb_str_len(string); char *escaped; VALUE result; size_t quoted_length = 0; // Allocate space for the escaped version of 'string'. Use + 3 allocate space for null term. // and the leading and trailing single-quotes. // Thanks to http://www.browardphp.com/mysql_manual_en/manual_MySQL_APIs.html#mysql_real_escape_string escaped = (char *)calloc(source_len * 2 + 3, sizeof(char)); // Escape 'source' using the current encoding in use on the conection 'db' quoted_length = mysql_real_escape_string(db, escaped + 1, source, source_len); // Wrap the escaped string in single-quotes, this is DO's convention escaped[0] = escaped[quoted_length + 1] = '\''; result = DO_STR_NEW(escaped, quoted_length + 2, FIX2INT(rb_iv_get(self, "@encoding_id"))); free(escaped); return result; }
VALUE string_spec_rb_str_len(VALUE self, VALUE str) { return INT2FIX(rb_str_len(str)); }