1 /* connection.h - definition for the psycopg connection type 2 * 3 * Copyright (C) 2003-2019 Federico Di Gregorio <fog@debian.org> 4 * Copyright (C) 2020-2021 The Psycopg Team 5 * 6 * This file is part of psycopg. 7 * 8 * psycopg2 is free software: you can redistribute it and/or modify it 9 * under the terms of the GNU Lesser General Public License as published 10 * by the Free Software Foundation, either version 3 of the License, or 11 * (at your option) any later version. 12 * 13 * In addition, as a special exception, the copyright holders give 14 * permission to link this program with the OpenSSL library (or with 15 * modified versions of OpenSSL that use the same license as OpenSSL), 16 * and distribute linked combinations including the two. 17 * 18 * You must obey the GNU Lesser General Public License in all respects for 19 * all of the code used other than OpenSSL. 20 * 21 * psycopg2 is distributed in the hope that it will be useful, but WITHOUT 22 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 23 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 24 * License for more details. 25 */ 26 27 #ifndef PSYCOPG_CONNECTION_H 28 #define PSYCOPG_CONNECTION_H 1 29 30 #include "psycopg/xid.h" 31 32 #ifdef __cplusplus 33 extern "C" { 34 #endif 35 36 /* isolation levels */ 37 #define ISOLATION_LEVEL_AUTOCOMMIT 0 38 #define ISOLATION_LEVEL_READ_UNCOMMITTED 4 39 #define ISOLATION_LEVEL_READ_COMMITTED 1 40 #define ISOLATION_LEVEL_REPEATABLE_READ 2 41 #define ISOLATION_LEVEL_SERIALIZABLE 3 42 #define ISOLATION_LEVEL_DEFAULT 5 43 44 /* 3-state values on/off/default */ 45 #define STATE_OFF 0 46 #define STATE_ON 1 47 #define STATE_DEFAULT 2 48 49 /* connection status */ 50 #define CONN_STATUS_SETUP 0 51 #define CONN_STATUS_READY 1 52 #define CONN_STATUS_BEGIN 2 53 #define CONN_STATUS_PREPARED 5 54 /* async connection building statuses */ 55 #define CONN_STATUS_CONNECTING 20 56 #define CONN_STATUS_DATESTYLE 21 57 58 /* async query execution status */ 59 #define ASYNC_DONE 0 60 #define ASYNC_READ 1 61 #define ASYNC_WRITE 2 62 63 /* polling result */ 64 #define PSYCO_POLL_OK 0 65 #define PSYCO_POLL_READ 1 66 #define PSYCO_POLL_WRITE 2 67 #define PSYCO_POLL_ERROR 3 68 69 /* Hard limit on the notices stored by the Python connection */ 70 #define CONN_NOTICES_LIMIT 50 71 72 /* we need the initial date style to be ISO, for typecasters; if the user 73 later change it, she must know what she's doing... these are the queries we 74 need to issue */ 75 #define psyco_datestyle "SET DATESTYLE TO 'ISO'" 76 77 extern HIDDEN PyTypeObject connectionType; 78 79 struct connectionObject_notice { 80 struct connectionObject_notice *next; 81 char *message; 82 }; 83 84 /* the typedef is forward-declared in psycopg.h */ 85 struct connectionObject { 86 PyObject_HEAD 87 88 pthread_mutex_t lock; /* the global connection lock */ 89 90 char *dsn; /* data source name */ 91 char *error; /* temporarily stored error before raising */ 92 char *encoding; /* current backend encoding */ 93 94 long int closed; /* 1 means connection has been closed; 95 2 that something horrible happened */ 96 long int mark; /* number of commits/rollbacks done so far */ 97 int status; /* status of the connection */ 98 xidObject *tpc_xid; /* Transaction ID in two-phase commit */ 99 100 long int async; /* 1 means the connection is async */ 101 int protocol; /* protocol version */ 102 int server_version; /* server version */ 103 104 PGconn *pgconn; /* the postgresql connection */ 105 PGcancel *cancel; /* the cancellation structure */ 106 107 /* Weakref to the object executing an asynchronous query. The object 108 * is a cursor for async connections, but it may be something else 109 * for a green connection. If NULL, the connection is idle. */ 110 PyObject *async_cursor; 111 int async_status; /* asynchronous execution status */ 112 PGresult *pgres; /* temporary result across async calls */ 113 114 /* notice processing */ 115 PyObject *notice_list; 116 struct connectionObject_notice *notice_pending; 117 struct connectionObject_notice *last_notice; 118 119 /* notifies */ 120 PyObject *notifies; 121 122 /* per-connection typecasters */ 123 PyObject *string_types; /* a set of typecasters for string types */ 124 PyObject *binary_types; /* a set of typecasters for binary types */ 125 126 int equote; /* use E''-style quotes for escaped strings */ 127 PyObject *weakreflist; /* list of weak references */ 128 129 int autocommit; 130 131 PyObject *cursor_factory; /* default cursor factory from cursor() */ 132 133 /* Optional pointer to a decoding C function, e.g. PyUnicode_DecodeUTF8 */ 134 PyObject *(*cdecoder)(const char *, Py_ssize_t, const char *); 135 136 /* Pointers to python encoding/decoding functions, e.g. 137 * codecs.getdecoder('utf8') */ 138 PyObject *pyencoder; /* python codec encoding function */ 139 PyObject *pydecoder; /* python codec decoding function */ 140 141 /* Values for the transactions characteristics */ 142 int isolevel; 143 int readonly; 144 int deferrable; 145 146 /* the pid this connection was created into */ 147 pid_t procpid; 148 149 /* inside a with block */ 150 int entered; 151 }; 152 153 /* map isolation level values into a numeric const */ 154 typedef struct { 155 char *name; 156 int value; 157 } IsolationLevel; 158 159 /* C-callable functions in connection_int.c and connection_ext.c */ 160 HIDDEN PyObject *conn_text_from_chars(connectionObject *pgconn, const char *str); 161 HIDDEN PyObject *conn_encode(connectionObject *self, PyObject *b); 162 HIDDEN PyObject *conn_decode(connectionObject *self, const char *str, Py_ssize_t len); 163 HIDDEN int conn_get_standard_conforming_strings(PGconn *pgconn); 164 HIDDEN PyObject *conn_pgenc_to_pyenc(const char *encoding, char **clean_encoding); 165 HIDDEN int conn_get_protocol_version(PGconn *pgconn); 166 HIDDEN int conn_get_server_version(PGconn *pgconn); 167 HIDDEN void conn_notice_process(connectionObject *self); 168 HIDDEN void conn_notice_clean(connectionObject *self); 169 HIDDEN void conn_notifies_process(connectionObject *self); 170 RAISES_NEG HIDDEN int conn_setup(connectionObject *self); 171 HIDDEN int conn_connect(connectionObject *self, const char *dsn, long int async); 172 HIDDEN char *conn_obscure_password(const char *dsn); 173 HIDDEN void conn_close(connectionObject *self); 174 HIDDEN void conn_close_locked(connectionObject *self); 175 RAISES_NEG HIDDEN int conn_commit(connectionObject *self); 176 RAISES_NEG HIDDEN int conn_rollback(connectionObject *self); 177 RAISES_NEG HIDDEN int conn_set_session(connectionObject *self, int autocommit, 178 int isolevel, int readonly, int deferrable); 179 RAISES_NEG HIDDEN int conn_set_client_encoding(connectionObject *self, const char *enc); 180 HIDDEN int conn_poll(connectionObject *self); 181 RAISES_NEG HIDDEN int conn_tpc_begin(connectionObject *self, xidObject *xid); 182 RAISES_NEG HIDDEN int conn_tpc_command(connectionObject *self, 183 const char *cmd, xidObject *xid); 184 HIDDEN PyObject *conn_tpc_recover(connectionObject *self); 185 HIDDEN void conn_set_result(connectionObject *self, PGresult *pgres); 186 HIDDEN void conn_set_error(connectionObject *self, const char *msg); 187 188 /* exception-raising macros */ 189 #define EXC_IF_CONN_CLOSED(self) if ((self)->closed > 0) { \ 190 PyErr_SetString(InterfaceError, "connection already closed"); \ 191 return NULL; } 192 193 #define EXC_IF_CONN_ASYNC(self, cmd) if ((self)->async == 1) { \ 194 PyErr_SetString(ProgrammingError, #cmd " cannot be used " \ 195 "in asynchronous mode"); \ 196 return NULL; } 197 198 #define EXC_IF_IN_TRANSACTION(self, cmd) \ 199 if (self->status != CONN_STATUS_READY) { \ 200 PyErr_Format(ProgrammingError, \ 201 "%s cannot be used inside a transaction", #cmd); \ 202 return NULL; \ 203 } 204 205 #define EXC_IF_TPC_NOT_SUPPORTED(self) \ 206 if ((self)->server_version < 80100) { \ 207 PyErr_Format(NotSupportedError, \ 208 "server version %d: " \ 209 "two-phase transactions not supported", \ 210 (self)->server_version); \ 211 return NULL; \ 212 } 213 214 #define EXC_IF_TPC_BEGIN(self, cmd) if ((self)->tpc_xid) { \ 215 PyErr_Format(ProgrammingError, "%s cannot be used " \ 216 "during a two-phase transaction", #cmd); \ 217 return NULL; } 218 219 #define EXC_IF_TPC_PREPARED(self, cmd) \ 220 if ((self)->status == CONN_STATUS_PREPARED) { \ 221 PyErr_Format(ProgrammingError, "%s cannot be used " \ 222 "with a prepared two-phase transaction", #cmd); \ 223 return NULL; } 224 225 #ifdef __cplusplus 226 } 227 #endif 228 229 #endif /* !defined(PSYCOPG_CONNECTION_H) */ 230