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