1 /* cursor.h - definition for the psycopg cursor 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_CURSOR_H 28 #define PSYCOPG_CURSOR_H 1 29 30 #include "psycopg/connection.h" 31 32 #ifdef __cplusplus 33 extern "C" { 34 #endif 35 36 extern HIDDEN PyTypeObject cursorType; 37 38 /* the typedef is forward-declared in psycopg.h */ 39 struct cursorObject { 40 PyObject_HEAD 41 42 connectionObject *conn; /* connection owning the cursor */ 43 44 int closed:1; /* 1 if the cursor is closed */ 45 int notuples:1; /* 1 if the command was not a SELECT query */ 46 int withhold:1; /* 1 if the cursor is named and uses WITH HOLD */ 47 48 int scrollable; /* 1 if the cursor is named and SCROLLABLE, 49 0 if not scrollable 50 -1 if undefined (PG may decide scrollable or not) 51 */ 52 53 long int rowcount; /* number of rows affected by last execute */ 54 long int columns; /* number of columns fetched from the db */ 55 long int arraysize; /* how many rows should fetchmany() return */ 56 long int itersize; /* how many rows should iter(cur) fetch in named cursors */ 57 long int row; /* the row counter for fetch*() operations */ 58 long int mark; /* transaction marker, copied from conn */ 59 60 PyObject *description; /* read-only attribute: sequence of 7-item 61 sequences.*/ 62 63 /* postgres connection stuff */ 64 PGresult *pgres; /* result of last query */ 65 PyObject *pgstatus; /* last message from the server after an execute */ 66 Oid lastoid; /* last oid from an insert or InvalidOid */ 67 68 PyObject *casts; /* an array (tuple) of typecast functions */ 69 PyObject *caster; /* the current typecaster object */ 70 71 PyObject *copyfile; /* file-like used during COPY TO/FROM ops */ 72 Py_ssize_t copysize; /* size of the copy buffer during COPY TO/FROM ops */ 73 #define DEFAULT_COPYSIZE 16384 74 #define DEFAULT_COPYBUFF 8192 75 76 PyObject *tuple_factory; /* factory for result tuples */ 77 PyObject *tzinfo_factory; /* factory for tzinfo objects */ 78 79 PyObject *query; /* last query executed */ 80 81 char *qattr; /* quoting attr, used when quoting strings */ 82 char *notice; /* a notice from the backend */ 83 char *name; /* this cursor name */ 84 char *qname; /* this cursor name, quoted */ 85 86 PyObject *string_types; /* a set of typecasters for string types */ 87 PyObject *binary_types; /* a set of typecasters for binary types */ 88 89 PyObject *weakreflist; /* list of weak references */ 90 91 }; 92 93 94 /* C-callable functions in cursor_int.c and cursor_type.c */ 95 BORROWED HIDDEN PyObject *curs_get_cast(cursorObject *self, PyObject *oid); 96 HIDDEN void curs_reset(cursorObject *self); 97 RAISES_NEG HIDDEN int curs_withhold_set(cursorObject *self, PyObject *pyvalue); 98 RAISES_NEG HIDDEN int curs_scrollable_set(cursorObject *self, PyObject *pyvalue); 99 HIDDEN PyObject *curs_validate_sql_basic(cursorObject *self, PyObject *sql); 100 HIDDEN void curs_set_result(cursorObject *self, PGresult *pgres); 101 102 /* exception-raising macros */ 103 #define EXC_IF_CURS_CLOSED(self) \ 104 do { \ 105 if (!(self)->conn) { \ 106 PyErr_SetString(InterfaceError, "the cursor has no connection"); \ 107 return NULL; } \ 108 if ((self)->closed || (self)->conn->closed) { \ 109 PyErr_SetString(InterfaceError, "cursor already closed"); \ 110 return NULL; } \ 111 } while (0) 112 113 #define EXC_IF_NO_TUPLES(self) \ 114 do \ 115 if ((self)->notuples && (self)->name == NULL) { \ 116 PyErr_SetString(ProgrammingError, "no results to fetch"); \ 117 return NULL; } \ 118 while (0) 119 120 #define EXC_IF_NO_MARK(self) \ 121 do \ 122 if ((self)->mark != (self)->conn->mark && (self)->withhold == 0) { \ 123 PyErr_SetString(ProgrammingError, "named cursor isn't valid anymore"); \ 124 return NULL; } \ 125 while (0) 126 127 #define EXC_IF_CURS_ASYNC(self, cmd) \ 128 do \ 129 if ((self)->conn->async == 1) { \ 130 PyErr_SetString(ProgrammingError, \ 131 #cmd " cannot be used in asynchronous mode"); \ 132 return NULL; } \ 133 while (0) 134 135 #define EXC_IF_ASYNC_IN_PROGRESS(self, cmd) \ 136 do \ 137 if ((self)->conn->async_cursor != NULL) { \ 138 PyErr_SetString(ProgrammingError, \ 139 #cmd " cannot be used while an asynchronous query is underway"); \ 140 return NULL; } \ 141 while (0) 142 143 #ifdef __cplusplus 144 } 145 #endif 146 147 #endif /* !defined(PSYCOPG_CURSOR_H) */ 148