Repository: diesel-rs/diesel
File: diesel/src/pg/connection/result.rs (Rust)

Code before:
                    match get_result_field(internal_result.as_ptr(), ResultField::SqlState) {
                        Some(error_codes::UNIQUE_VIOLATION) => DatabaseErrorKind::UniqueViolation,
                        Some(error_codes::FOREIGN_KEY_VIOLATION) => {
                            DatabaseErrorKind::ForeignKeyViolation
                        }
                        Some(error_codes::SERIALIZATION_FAILURE) => {
                            DatabaseErrorKind::SerializationFailure
                        }
                        Some(error_codes::READ_ONLY_TRANSACTION) => {
                            DatabaseErrorKind::ReadOnlyTransaction
                        }
                        Some(error_codes::NOT_NULL_VIOLATION) => {
                            DatabaseErrorKind::NotNullViolation
                        }
                        Some(error_codes::CHECK_VIOLATION) => DatabaseErrorKind::CheckViolation,
                        Some(error_codes::CONNECTION_EXCEPTION)
                        | Some(error_codes::CONNECTION_FAILURE)
                        | Some(error_codes::SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION)
                        | Some(error_codes::SQLSERVER_REJECTED_ESTABLISHMENT_OF_SQLCONNECTION) => {
                            DatabaseErrorKind::ClosedConnection
                        }
                        _ => DatabaseErrorKind::Unknown,
                    };
                let error_information = Box::new(PgErrorInformation(internal_result));
                let pg_connection: *const PGconn = conn.into();
                if unsafe { PQstatus(pg_connection) } == ConnStatusType::CONNECTION_BAD {
                    error_kind = DatabaseErrorKind::ClosedConnection;
                }
                Err(Error::DatabaseError(error_kind, error_information))
            }
        }
    }

    pub(super) fn rows_affected(&self) -> usize {
        unsafe {
            let count_char_ptr = PQcmdTuples(self.internal_result.as_ptr());
            let count_bytes = CStr::from_ptr(count_char_ptr).to_bytes();
            // Using from_utf8_unchecked is ok here because, we've set the
            // client encoding to utf8
            let count_str = str::from_utf8_unchecked(count_bytes);
            match count_str {
                "" => 0,
                _ => count_str
                    .parse()
                    .expect("Error parsing `rows_affected` as integer value"),
            }
        }
    }

    pub(super) fn num_rows(&self) -> usize {
        self.row_count

Review comment (suggestion):
We should likely add a method to `RawConnection` to wrap the call to `PQstatus` there, so something like `RawConnection::get_status() -> i32` or so. This has multiple advantages:
* We can only call `PQstatus` with a valid connection object
* We have most connection related unsafe code in one module.

Code after:
                    match get_result_field(internal_result.as_ptr(), ResultField::SqlState) {
                        Some(error_codes::UNIQUE_VIOLATION) => DatabaseErrorKind::UniqueViolation,
                        Some(error_codes::FOREIGN_KEY_VIOLATION) => {
                            DatabaseErrorKind::ForeignKeyViolation
                        }
                        Some(error_codes::SERIALIZATION_FAILURE) => {
                            DatabaseErrorKind::SerializationFailure
                        }
                        Some(error_codes::READ_ONLY_TRANSACTION) => {
                            DatabaseErrorKind::ReadOnlyTransaction
                        }
                        Some(error_codes::NOT_NULL_VIOLATION) => {
                            DatabaseErrorKind::NotNullViolation
                        }
                        Some(error_codes::CHECK_VIOLATION) => DatabaseErrorKind::CheckViolation,
                        Some(error_codes::CONNECTION_EXCEPTION)
                        | Some(error_codes::CONNECTION_FAILURE)
                        | Some(error_codes::SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION)
                        | Some(error_codes::SQLSERVER_REJECTED_ESTABLISHMENT_OF_SQLCONNECTION) => {
                            DatabaseErrorKind::ClosedConnection
                        }
                        _ => DatabaseErrorKind::Unknown,
                    };
                let error_information = Box::new(PgErrorInformation(internal_result));
                let conn_status = conn.get_status();
                if conn_status == ConnStatusType::CONNECTION_BAD {
                    error_kind = DatabaseErrorKind::ClosedConnection;
                }
                Err(Error::DatabaseError(error_kind, error_information))
            }
        }
    }

    pub(super) fn rows_affected(&self) -> usize {
        unsafe {
            let count_char_ptr = PQcmdTuples(self.internal_result.as_ptr());
            let count_bytes = CStr::from_ptr(count_char_ptr).to_bytes();
            // Using from_utf8_unchecked is ok here because, we've set the
            // client encoding to utf8
            let count_str = str::from_utf8_unchecked(count_bytes);
            match count_str {
                "" => 0,
                _ => count_str
                    .parse()
                    .expect("Error parsing `rows_affected` as integer value"),
            }
        }
    }

    pub(super) fn num_rows(&self) -> usize {
        self.row_count