/// Executes the prepared statement. int SqlStmt_Execute(SqlStmt* self) { if( self == NULL ) return SQL_ERROR; SqlStmt_FreeResult(self); if( (self->bind_params && mysql_stmt_bind_param(self->stmt, self->params)) || mysql_stmt_execute(self->stmt) ) { ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt)); hercules_mysql_error_handler(mysql_stmt_errno(self->stmt)); return SQL_ERROR; } self->bind_columns = false; if( mysql_stmt_store_result(self->stmt) )// store all the data { ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt)); hercules_mysql_error_handler(mysql_stmt_errno(self->stmt)); return SQL_ERROR; } return SQL_SUCCESS; }
/// Executes a query. int Sql_QueryStr(Sql* self, const char* query) { if( self == NULL ) return SQL_ERROR; Sql_FreeResult(self); StringBuf_Clear(&self->buf); StringBuf_AppendStr(&self->buf, query); if( mysql_real_query(&self->handle, StringBuf_Value(&self->buf), (unsigned long)StringBuf_Length(&self->buf)) ) { ShowSQL("DB error - %s\n", mysql_error(&self->handle)); hercules_mysql_error_handler(mysql_errno(&self->handle)); return SQL_ERROR; } self->result = mysql_store_result(&self->handle); if( mysql_errno(&self->handle) != 0 ) { ShowSQL("DB error - %s\n", mysql_error(&self->handle)); hercules_mysql_error_handler(mysql_errno(&self->handle)); return SQL_ERROR; } return SQL_SUCCESS; }
/// Executes a query. int Sql_QueryV(Sql* self, const char* query, va_list args) { if( self == NULL ) return SQL_ERROR; SQL->FreeResult(self); StrBuf->Clear(&self->buf); StrBuf->Vprintf(&self->buf, query, args); if( mysql_real_query(&self->handle, StrBuf->Value(&self->buf), (unsigned long)StrBuf->Length(&self->buf)) ) { ShowSQL("DB error - %s\n", mysql_error(&self->handle)); hercules_mysql_error_handler(mysql_errno(&self->handle)); return SQL_ERROR; } self->result = mysql_store_result(&self->handle); if( mysql_errno(&self->handle) != 0 ) { ShowSQL("DB error - %s\n", mysql_error(&self->handle)); hercules_mysql_error_handler(mysql_errno(&self->handle)); return SQL_ERROR; } return SQL_SUCCESS; }
/// Prepares the statement. int SqlStmt_PrepareStr(SqlStmt* self, const char* query) { if( self == NULL ) return SQL_ERROR; SqlStmt_FreeResult(self); StringBuf_Clear(&self->buf); StringBuf_AppendStr(&self->buf, query); if( mysql_stmt_prepare(self->stmt, StringBuf_Value(&self->buf), (unsigned long)StringBuf_Length(&self->buf)) ) { ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt)); hercules_mysql_error_handler(mysql_stmt_errno(self->stmt)); return SQL_ERROR; } self->bind_params = false; return SQL_SUCCESS; }
/// Prepares the statement. int SqlStmt_PrepareV(SqlStmt* self, const char* query, va_list args) { if( self == NULL ) return SQL_ERROR; SqlStmt_FreeResult(self); StrBuf->Clear(&self->buf); StrBuf->Vprintf(&self->buf, query, args); if( mysql_stmt_prepare(self->stmt, StrBuf->Value(&self->buf), (unsigned long)StrBuf->Length(&self->buf)) ) { ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt)); hercules_mysql_error_handler(mysql_stmt_errno(self->stmt)); return SQL_ERROR; } self->bind_params = false; return SQL_SUCCESS; }
/// Fetches the next row. int SqlStmt_NextRow(SqlStmt* self) { int err; size_t i; size_t cols; MYSQL_BIND* column; unsigned long length; if( self == NULL ) return SQL_ERROR; // bind columns if( self->bind_columns && mysql_stmt_bind_result(self->stmt, self->columns) ) err = 1;// error binding columns else err = mysql_stmt_fetch(self->stmt);// fetch row // check for errors if( err == MYSQL_NO_DATA ) return SQL_NO_DATA; #if defined(MYSQL_DATA_TRUNCATED) // MySQL 5.0/5.1 defines and returns MYSQL_DATA_TRUNCATED [FlavioJS] if( err == MYSQL_DATA_TRUNCATED ) { my_bool truncated; if( !self->bind_columns ) { ShowSQL("DB error - data truncated (unknown source, columns are not bound)\n"); return SQL_ERROR; } // find truncated column cols = SqlStmt_NumColumns(self); for( i = 0; i < cols; ++i ) { column = &self->columns[i]; column->error = &truncated; mysql_stmt_fetch_column(self->stmt, column, (unsigned int)i, 0); column->error = NULL; if( truncated ) {// report truncated column SqlStmt_P_ShowDebugTruncatedColumn(self, i); return SQL_ERROR; } } ShowSQL("DB error - data truncated (unknown source)\n"); return SQL_ERROR; } #endif if( err ) { ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt)); hercules_mysql_error_handler(mysql_stmt_errno(self->stmt)); return SQL_ERROR; } // propagate column lengths and clear unused parts of string/enum/blob buffers cols = SqlStmt_NumColumns(self); for( i = 0; i < cols; ++i ) { length = self->column_lengths[i].length; column = &self->columns[i]; #if !defined(MYSQL_DATA_TRUNCATED) // MySQL 4.1/(below?) returns success even if data is truncated, so we test truncation manually [FlavioJS] if( column->buffer_length < length ) {// report truncated column if( column->buffer_type == MYSQL_TYPE_STRING || column->buffer_type == MYSQL_TYPE_BLOB ) {// string/enum/blob column SqlStmt_P_ShowDebugTruncatedColumn(self, i); return SQL_ERROR; } // FIXME numeric types and null [FlavioJS] } #endif if( self->column_lengths[i].out_length ) *self->column_lengths[i].out_length = (uint32)length; if( column->buffer_type == MYSQL_TYPE_STRING ) {// clear unused part of the string/enum buffer (and nul-terminate) memset((char*)column->buffer + length, 0, column->buffer_length - length + 1); } else if( column->buffer_type == MYSQL_TYPE_BLOB && length < column->buffer_length ) {// clear unused part of the blob buffer memset((char*)column->buffer + length, 0, column->buffer_length - length); } } return SQL_SUCCESS; }