Merge commit 'origin/master'
[versaplex.git] / vxodbc / qresult.h
blob52943ce00be1432e9ffc407e7b4c1746fc87b1d3
1 #ifndef __QRESULT_H__
2 #define __QRESULT_H__
4 #include "psqlodbc.h"
6 #include "connection.h"
7 #include "columninfo.h"
8 #include "tuple.h"
10 #ifdef __cplusplus
11 extern "C" {
12 #endif
14 typedef
15 enum QueryResultCode_
17 PORES_EMPTY_QUERY = 0,
18 PORES_COMMAND_OK, /* a query command that doesn't return
19 * anything was executed properly by the backend */
20 PORES_TUPLES_OK, /* a query command that returns tuples
21 * was executed properly by the backend, PGresult
22 * contains the resulttuples */
23 PORES_COPY_OUT,
24 PORES_COPY_IN,
25 PORES_BAD_RESPONSE, /* an unexpected response was recv'd from
26 * the backend */
27 PORES_NONFATAL_ERROR,
28 PORES_FATAL_ERROR,
29 PORES_FIELDS_OK = 100, /* field information from a query was
30 * successful */
31 /* PORES_END_TUPLES, */
32 PORES_INTERNAL_ERROR
33 } QueryResultCode;
35 enum
37 FQR_FETCHING_TUPLES = 1L /* is fetching tuples from db */
38 ,FQR_REACHED_EOF = (1L << 1) /* reached eof */
39 ,FQR_HAS_VALID_BASE = (1L << 2)
42 struct QResultClass_
44 ColumnInfoClass *fields; /* the Column information */
45 ConnectionClass *conn; /* the connection this result is using
46 * (backend) */
47 QResultClass *next; /* the following result class */
49 /* Stuff for declare/fetch tuples */
50 SQLULEN num_total_read; /* the highest absolute position ever read in + 1 */
51 SQLULEN count_backend_allocated;/* m(re)alloced count */
52 SQLULEN num_cached_rows; /* count of tuples kept in backend_tuples member */
53 SQLLEN fetch_number; /* 0-based index to the tuple to read next */
54 SQLLEN cursTuple; /* absolute current position in the servr's cursor used to retrieve tuples from the DB */
55 SQLULEN move_offset;
56 SQLLEN base; /* relative position of rowset start in the current data cache(backend_tuples) */
58 UInt2 num_fields; /* number of fields in the result */
59 UInt2 num_key_fields; /* number of key fields in the result */
60 SQLULEN cache_size;
61 UInt4 rowset_size_include_ommitted; /* PG restriction */
62 SQLLEN recent_processed_row_count;
64 QueryResultCode rstatus; /* result status */
66 char sqlstate[8];
67 char *message;
68 char *cursor_name; /* The name of the cursor for select
69 * statements */
70 char *command;
71 char *notice;
73 TupleField *backend_tuples; /* data from the backend (the tuple cache) */
74 TupleField *tupleField; /* current backend tuple being retrieved */
76 char pstatus; /* processing status */
77 char aborted; /* was aborted ? */
78 char flags; /* this result contains keyset etc ? */
79 char move_direction; /* must move before fetching this
80 result set */
81 SQLULEN count_keyset_allocated; /* m(re)alloced count */
82 SQLULEN num_cached_keys; /* count of keys kept in backend_keys member */
83 KeySet *keyset;
84 SQLLEN key_base; /* relative position of rowset start in the current keyset cache */
85 UInt2 reload_count;
86 UInt2 rb_alloc; /* count of allocated rollback info */
87 UInt2 rb_count; /* count of rollback info */
88 Rollback *rollback;
89 UInt4 ad_alloc; /* count of allocated added info */
90 UInt4 ad_count; /* count of newly added rows */
91 KeySet *added_keyset; /* added keyset info */
92 TupleField *added_tuples; /* added data by myself */
93 UInt2 dl_alloc; /* count of allocated deleted info */
94 UInt2 dl_count; /* count of deleted info */
95 SQLULEN *deleted; /* deleted index info */
96 KeySet *deleted_keyset; /* deleted keyset info */
97 UInt2 up_alloc; /* count of allocated updated info */
98 UInt2 up_count; /* count of updated info */
99 SQLULEN *updated; /* updated index info */
100 KeySet *updated_keyset; /* uddated keyset info */
101 TupleField *updated_tuples; /* uddated data by myself */
104 enum {
105 FQR_HASKEYSET = 1L
106 ,FQR_WITHHOLD = (1L << 1)
107 ,FQR_HOLDPERMANENT = (1L << 2) /* the cursor is alive across transactions */
108 ,FQR_SYNCHRONIZEKEYS = (1L<<3) /* synchronize the keyset range with that of cthe tuples cache */
111 #define QR_haskeyset(self) (0 != (self->flags & FQR_HASKEYSET))
112 #define QR_is_withhold(self) (0 != (self->flags & FQR_WITHHOLD))
113 #define QR_is_permanent(self) (0 != (self->flags & FQR_HOLDPERMANENT))
114 #define QR_synchronize_keys(self) (0 != (self->flags & FQR_SYNCHRONIZEKEYS))
115 #define QR_get_fields(self) (self->fields)
118 /* These functions are for retrieving data from the qresult */
119 #define QR_get_value_backend(self, fieldno) (self->tupleField[fieldno].value)
120 #define QR_get_value_backend_row(self, tupleno, fieldno) ((self->backend_tuples + (tupleno * self->num_fields))[fieldno].value)
121 #define QR_get_value_backend_text(self, tupleno, fieldno) ((const char *)QR_get_value_backend_row(self, tupleno, fieldno))
122 #define QR_get_value_backend_int(self, tupleno, fieldno, isNull) atoi((const char *)QR_get_value_backend_row(self, tupleno, fieldno))
124 /* These functions are used by both manual and backend results */
125 #define QR_NumResultCols(self) (CI_get_num_fields(self->fields))
126 #define QR_NumPublicResultCols(self) (QR_haskeyset(self) ? (CI_get_num_fields(self->fields) - self->num_key_fields) : CI_get_num_fields(self->fields))
127 #define QR_get_fieldname(self, fieldno_) (CI_get_fieldname(self->fields, fieldno_))
128 #define QR_get_fieldsize(self, fieldno_) (CI_get_fieldsize(self->fields, fieldno_))
129 #define QR_get_display_size(self, fieldno_) (CI_get_display_size(self->fields, fieldno_))
130 #define QR_get_atttypmod(self, fieldno_) (CI_get_atttypmod(self->fields, fieldno_))
131 #define QR_get_field_type(self, fieldno_) (CI_get_oid(self->fields, fieldno_))
132 #define QR_get_relid(self, fieldno_) (CI_get_relid(self->fields, fieldno_))
133 #define QR_get_attid(self, fieldno_) (CI_get_attid(self->fields, fieldno_))
135 /* These functions are used only for manual result sets */
136 #define QR_get_num_total_tuples(self) (QR_once_reached_eof(self) ? (self->num_total_read + self->ad_count) : self->num_total_read)
137 #define QR_get_num_total_read(self) (self->num_total_read)
138 #define QR_get_num_cached_tuples(self) (self->num_cached_rows)
139 #define QR_set_field_info(self, field_num, name, adtid, adtsize, relid, attid) (CI_set_field_info(self->fields, field_num, name, adtid, adtsize, -1, relid, attid))
140 #define QR_set_field_info_v(self, field_num, name, adtid, adtsize) (CI_set_field_info(self->fields, field_num, name, adtid, adtsize, -1, 0, 0))
142 /* status macros */
143 #define QR_command_successful(self) (self && !(self->rstatus == PORES_BAD_RESPONSE || self->rstatus == PORES_NONFATAL_ERROR || self->rstatus == PORES_FATAL_ERROR))
144 #define QR_command_maybe_successful(self) (self && !(self->rstatus == PORES_BAD_RESPONSE || self->rstatus == PORES_FATAL_ERROR))
145 #define QR_command_nonfatal(self) ( self->rstatus == PORES_NONFATAL_ERROR)
146 #define QR_set_conn(self, conn_) ( self->conn = conn_ )
147 #define QR_set_rstatus(self, condition) ( self->rstatus = condition )
148 #define QR_set_sqlstatus(self, status) strcpy(self->sqlstatus, status)
149 #define QR_set_aborted(self, aborted_) ( self->aborted = aborted_)
150 #define QR_set_haskeyset(self) (self->flags |= FQR_HASKEYSET)
151 #define QR_set_synchronize_keys(self) (self->flags |= FQR_SYNCHRONIZEKEYS)
152 #define QR_set_no_cursor(self) (self->flags &= ~(FQR_WITHHOLD | FQR_HOLDPERMANENT))
153 #define QR_set_withhold(self) (self->flags |= FQR_WITHHOLD)
154 #define QR_set_permanent(self) (self->flags |= FQR_HOLDPERMANENT)
155 #define QR_set_reached_eof(self) (self->pstatus |= FQR_REACHED_EOF)
156 #define QR_set_fetching_tuples(self) (self->pstatus |= FQR_FETCHING_TUPLES)
157 #define QR_set_no_fetching_tuples(self) (self->pstatus &= ~FQR_FETCHING_TUPLES)
158 #define QR_set_has_valid_base(self) (self->pstatus |= FQR_HAS_VALID_BASE)
159 #define QR_set_no_valid_base(self) (self->pstatus &= ~FQR_HAS_VALID_BASE)
160 #define QR_inc_num_cache(self) \
161 do { \
162 self->num_cached_rows++; \
163 if (QR_haskeyset(self)) \
164 self->num_cached_keys++; \
165 } while (0)
166 #define QR_set_next_in_cache(self, number) \
167 do { \
168 inolog("set the number to %d to read next\n", number); \
169 self->fetch_number = number; \
170 } while (0)
171 #define QR_inc_next_in_cache(self) \
172 do { \
173 inolog("increased the number %d", self->fetch_number); \
174 self->fetch_number++; \
175 inolog("to %d to next read\n", self->fetch_number); \
176 } while (0)
178 #define QR_get_message(self) (self->message)
179 #define QR_get_command(self) (self->command)
180 #define QR_get_notice(self) (self->notice)
181 #define QR_get_rstatus(self) (self->rstatus)
182 #define QR_get_aborted(self) (self->aborted)
183 #define QR_get_conn(self) (self->conn)
184 #define QR_get_cursor(self) (self->cursor_name)
185 #define QR_get_rowstart_in_cache(self) (self->base)
186 #define QR_once_reached_eof(self) ((self->pstatus & FQR_REACHED_EOF) != 0)
187 #define QR_is_fetching_tuples(self) ((self->pstatus & FQR_FETCHING_TUPLES) != 0)
188 #define QR_has_valid_base(self) (0 != (self->pstatus & FQR_HAS_VALID_BASE))
190 #define QR_aborted(self) (!self || self->aborted)
191 #define QR_get_reqsize(self) (self->rowset_size_include_ommitted)
193 #define QR_stop_movement(self) (self->move_direction = 0)
194 #define QR_is_moving(self) (0 != self->move_direction)
195 #define QR_is_not_moving(self) (0 == self->move_direction)
196 #define QR_set_move_forward(self) (self->move_direction = 1)
197 #define QR_is_moving_forward(self) (1 == self->move_direction)
198 #define QR_set_move_backward(self) (self->move_direction = -1)
199 #define QR_is_moving_backward(self) (-1 == self->move_direction)
200 #define QR_set_move_from_the_last(self) (self->move_direction = 2)
201 #define QR_is_moving_from_the_last(self) (2 == self->move_direction)
202 #define QR_is_moving_not_backward(self) (0 < self->move_direction)
204 /* Core Functions */
205 QResultClass *QR_Constructor(void);
206 void QR_Destructor(QResultClass *self);
207 TupleField *QR_AddNew(QResultClass *self);
208 void QR_close_result(QResultClass *self, BOOL destroy);
209 void QR_free_memory(QResultClass *self);
210 void QR_set_command(QResultClass *self, const char *msg);
211 void QR_set_message(QResultClass *self, const char *msg);
212 void QR_add_message(QResultClass *self, const char *msg);
213 void QR_set_notice(QResultClass *self, const char *msg);
214 void QR_add_notice(QResultClass *self, const char *msg);
216 void QR_set_num_fields(QResultClass *self, int new_num_fields); /* catalog functions' result only */
218 void QR_set_num_cached_rows(QResultClass *, SQLLEN);
219 void QR_set_rowstart_in_cache(QResultClass *, SQLLEN);
220 void QR_inc_rowstart_in_cache(QResultClass *self, SQLLEN base_inc);
221 void QR_set_cache_size(QResultClass *self, SQLLEN cache_size);
222 void QR_set_rowset_size(QResultClass *self, Int4 rowset_size);
223 void QR_set_position(QResultClass *self, SQLLEN pos);
224 void QR_set_cursor(QResultClass *self, const char *name);
225 SQLLEN getNthValid(const QResultClass *self, SQLLEN sta, UWORD orientation, SQLULEN nth, SQLLEN *nearest);
227 #define QR_MALLOC_return_with_error(t, tp, s, a, m, r) \
228 do { \
229 if (t = (tp *) malloc(s), NULL == t) \
231 QR_set_rstatus(a, PORES_FATAL_ERROR); \
232 QR_set_message(a, m); \
233 return r; \
235 } while (0)
236 #define QR_REALLOC_return_with_error(t, tp, s, a, m, r) \
237 do { \
238 if (t = (tp *) realloc(t, s), NULL == t) \
240 QR_set_rstatus(a, PORES_FATAL_ERROR); \
241 QR_set_message(a, m); \
242 return r; \
244 } while (0)
246 #ifdef __cplusplus
248 #endif
249 #endif /* __QRESULT_H__ */