1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#[derive(Clone, Debug)]
pub struct Cancel {
cancel: *mut pq_sys::pg_cancel_conn,
}
impl Cancel {
/**
* Prepares a connection over which a cancel request can be sent.
*
* See [PQcancelCreate](https://www.postgresql.org/docs/current/libpq-cancel.html#LIBPQ-PQCANCELCREATE).
*/
pub fn create(conn: &crate::Connection) -> crate::errors::Result<Self> {
unsafe { pq_sys::PQcancelCreate(conn.into()) }.try_into()
}
/**
* Requests that the server abandons processing of the current command in a blocking manner.
*
* See [PQcancelBlocking](https://www.postgresql.org/docs/current/libpq-cancel.html#LIBPQ-PQCANCELBLOCKING).
*/
pub fn blocking(&mut self) -> crate::errors::Result {
let success = unsafe { pq_sys::PQcancelBlocking(self.into()) };
if success == 0 {
Ok(())
} else {
Err(crate::errors::Error::Backend(self.error_message()))
}
}
/**
* Requests that the server abandons processing of the current command in a non-blocking manner.
*
* See [PQcancelStart](https://www.postgresql.org/docs/current/libpq-cancel.html#LIBPQ-PQCANCELSTART).
*/
pub fn start(&mut self) -> crate::errors::Result {
let success = unsafe { pq_sys::PQcancelStart(self.into()) };
if success == 0 {
Ok(())
} else {
Err(crate::errors::Error::Backend(self.error_message()))
}
}
/**
* Requests that the server abandons processing of the current command in a non-blocking manner.
*
* See [PQcancelPoll](https://www.postgresql.org/docs/current/libpq-cancel.html#LIBPQ-PQCANCELSTART).
*/
pub fn pool(&mut self) -> crate::poll::Status {
unsafe { pq_sys::PQcancelPoll(self.into()) }.into()
}
/**
* Returns the status of the cancel connection.
*
* See [PQcancelStatus](https://www.postgresql.org/docs/current/libpq-cancel.html#LIBPQ-PQCANCELSTATUS).
*/
pub fn status(&self) -> crate::connection::Status {
unsafe { pq_sys::PQcancelStatus(self.into()) }.into()
}
/**
* Obtains the file descriptor number of the cancel connection socket to the server.
*
* See [PQcancelSocket](https://www.postgresql.org/docs/current/libpq-cancel.html#LIBPQ-PQCANCELSOCKET).
*/
pub fn socket(&self) -> crate::errors::Result<std::os::fd::RawFd> {
let fd = unsafe { pq_sys::PQcancelSocket(self.into()) };
if fd >= 0 {
Ok(fd)
} else {
Err(crate::errors::Error::Backend(
"No server connection is currently open".to_string(),
))
}
}
/**
* Returns the error message most recently generated by an operation on the cancel connection.
*
* See [PQcancelErrorMessage](https://www.postgresql.org/docs/current/libpq-cancel.html#LIBPQ-PQCANCELERRORMESSAGE).
*/
pub fn error_message(&self) -> String {
let error = unsafe { pq_sys::PQcancelErrorMessage(self.into()) };
match unsafe { std::ffi::CStr::from_ptr(error) }.to_str() {
Ok(s) => s.to_string(),
Err(_) => "PQerrorMessage internal error: the error message is not UTF-8".to_string(),
}
}
/**
* Closes the cancel connection (if it did not finish sending the cancel request yet).
*
* See [PQcancelFinish](https://www.postgresql.org/docs/current/libpq-cancel.html#LIBPQ-PQCANCELFINISH).
*/
fn finish(&mut self) {
unsafe { pq_sys::PQcancelFinish(self.into()) };
}
/**
* Resets the `CancelConn` so it can be reused for a new cancel connection.
*
* See [PQcancelReset](https://www.postgresql.org/docs/current/libpq-cancel.html#LIBPQ-PQCANCELRESET).
*/
pub fn reset(&mut self) {
unsafe { pq_sys::PQcancelReset(self.into()) };
}
}
#[doc(hidden)]
impl TryFrom<*mut pq_sys::pg_cancel_conn> for Cancel {
type Error = crate::errors::Error;
fn try_from(cancel: *mut pq_sys::pg_cancel_conn) -> std::result::Result<Self, Self::Error> {
if cancel.is_null() {
Err(crate::errors::Error::Backend(
"Unable to create cancel request".to_string(),
))
} else {
Ok(Self { cancel })
}
}
}
#[doc(hidden)]
impl From<&mut Cancel> for *mut pq_sys::pg_cancel_conn {
fn from(cancel: &mut Cancel) -> *mut pq_sys::pg_cancel_conn {
cancel.cancel
}
}
#[doc(hidden)]
impl From<&Cancel> for *const pq_sys::pg_cancel_conn {
fn from(cancel: &Cancel) -> *const pq_sys::pg_cancel_conn {
cancel.cancel
}
}
impl Drop for Cancel {
fn drop(&mut self) {
self.finish();
}
}