# ]
PQescapeStringConn.restype = c_size_t
-# won't wrap: PQescapeString
+PQescapeString = pq.PQescapeString
+# TODO: raises "wrong type" error
+# PQescapeString.argtypes = [c_char_p, c_char_p, c_size_t]
+PQescapeString.restype = c_size_t
PQescapeByteaConn = pq.PQescapeByteaConn
PQescapeByteaConn.argtypes = [
arg4: int,
arg5: pointer[c_int],
) -> int: ...
+def PQescapeString(arg1: c_char_p, arg2: bytes, arg3: int) -> int: ...
def PQsendPrepare(
arg1: Optional[PGconn_struct],
arg2: bytes,
return out.value
else:
- raise PQerror("escape_identifier failed: no connection provided")
+ out = create_string_buffer(len(data) * 2 + 1)
+ impl.PQescapeString(
+ pointer(out), # type: ignore
+ data,
+ len(data),
+ )
+ return out.value
def escape_bytea(self, data: bytes) -> bytes:
len_out = c_size_t()
Oid PQoidValue(const PGresult *res)
# 33.3.4. Escaping Strings for Inclusion in SQL Commands
- # TODO: PQescapeStringConn PQescapeString
char *PQescapeIdentifier(PGconn *conn, const char *str, size_t length)
char *PQescapeLiteral(PGconn *conn, const char *str, size_t length)
size_t PQescapeStringConn(PGconn *conn,
char *to, const char *from_, size_t length,
int *error)
+ size_t PQescapeString(char *to, const char *from_, size_t length)
unsigned char *PQescapeByteaConn(PGconn *conn,
const unsigned char *src,
size_t from_length,
cdef size_t len_data = len(data)
cdef char *out
cdef size_t len_out
+ cdef bytes rv
+
if self.conn is not None:
if self.conn.pgconn_ptr is NULL:
raise PQerror("the connection is closed")
)
if error:
+ PyMem_Free(out)
raise PQerror(
f"escape_string failed: {error_message(self.conn)}"
)
- return out[:len_out]
+
+ rv = out[:len_out]
+ PyMem_Free(out)
+ return rv
else:
- raise PQerror("escape_identifier failed: no connection provided")
+ out = <char *>PyMem_Malloc(len_data * 2 + 1)
+ len_out = impl.PQescapeString(out, data, len_data)
+ rv = out[:len_out]
+ PyMem_Free(out)
+ return rv
+
def escape_bytea(self, data: bytes) -> bytes:
cdef size_t len_out
assert rv == exp
-def test_escape_string_noconn(pgconn):
+@pytest.mark.parametrize(
+ "data, want",
+ [
+ (b"", b""),
+ (b"hello", b"hello"),
+ (b"foo'bar", b"foo''bar"),
+ (b"foo\\bar", b"foo\\\\bar"),
+ ],
+)
+def test_escape_string_noconn(data, want):
esc = pq.Escaping()
- with pytest.raises(psycopg3.OperationalError):
- esc.escape_string(b"hi")
+ out = esc.escape_string(data)
+ assert out == want
+
+def test_escape_string_badconn(pgconn):
esc = pq.Escaping(pgconn)
pgconn.finish()
with pytest.raises(psycopg3.OperationalError):