1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
|
/* File: statement.h
*
* Description: See "statement.c"
*
* Comments: See "notice.txt" for copyright and license information.
*
*/
#ifndef __STATEMENT_H__
#define __STATEMENT_H__
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "psqlodbc.h"
#include "bind.h"
#ifndef WIN32
#ifdef UNIXODBC
#include <sql.h>
#else
#include "iodbc.h"
#include "isql.h"
#include "isqlext.h"
#endif
#else
#include <windows.h>
#include <sql.h>
#endif
#ifndef FALSE
#define FALSE (BOOL)0
#endif
#ifndef TRUE
#define TRUE (BOOL)1
#endif
typedef enum {
STMT_ALLOCATED, /* The statement handle is allocated, but not used so far */
STMT_READY, /* the statement is waiting to be executed */
STMT_PREMATURE, /* ODBC states that it is legal to call e.g. SQLDescribeCol before
a call to SQLExecute, but after SQLPrepare. To get all the necessary
information in such a case, we simply execute the query _before_ the
actual call to SQLExecute, so that statement is considered to be "premature".
*/
STMT_FINISHED, /* statement execution has finished */
STMT_EXECUTING /* statement execution is still going on */
} STMT_Status;
#define STMT_TRUNCATED -2
#define STMT_INFO_ONLY -1 /* not an error message, just a notification to be returned by SQLError */
#define STMT_OK 0 /* will be interpreted as "no error pending" */
#define STMT_EXEC_ERROR 1
#define STMT_STATUS_ERROR 2
#define STMT_SEQUENCE_ERROR 3
#define STMT_NO_MEMORY_ERROR 4
#define STMT_COLNUM_ERROR 5
#define STMT_NO_STMTSTRING 6
#define STMT_ERROR_TAKEN_FROM_BACKEND 7
#define STMT_INTERNAL_ERROR 8
#define STMT_STILL_EXECUTING 9
#define STMT_NOT_IMPLEMENTED_ERROR 10
#define STMT_BAD_PARAMETER_NUMBER_ERROR 11
#define STMT_OPTION_OUT_OF_RANGE_ERROR 12
#define STMT_INVALID_COLUMN_NUMBER_ERROR 13
#define STMT_RESTRICTED_DATA_TYPE_ERROR 14
#define STMT_INVALID_CURSOR_STATE_ERROR 15
#define STMT_OPTION_VALUE_CHANGED 16
#define STMT_CREATE_TABLE_ERROR 17
#define STMT_NO_CURSOR_NAME 18
#define STMT_INVALID_CURSOR_NAME 19
#define STMT_INVALID_ARGUMENT_NO 20
#define STMT_ROW_OUT_OF_RANGE 21
#define STMT_OPERATION_CANCELLED 22
#define STMT_INVALID_CURSOR_POSITION 23
#define STMT_VALUE_OUT_OF_RANGE 24
#define STMT_OPERATION_INVALID 25
#define STMT_PROGRAM_TYPE_OUT_OF_RANGE 26
#define STMT_BAD_ERROR 27
/* statement types */
enum {
STMT_TYPE_UNKNOWN = -2,
STMT_TYPE_OTHER = -1,
STMT_TYPE_SELECT = 0,
STMT_TYPE_INSERT,
STMT_TYPE_UPDATE,
STMT_TYPE_DELETE,
STMT_TYPE_CREATE,
STMT_TYPE_ALTER,
STMT_TYPE_DROP,
STMT_TYPE_GRANT,
STMT_TYPE_REVOKE
};
#define STMT_UPDATE(stmt) (stmt->statement_type > STMT_TYPE_SELECT)
/* Parsing status */
enum {
STMT_PARSE_NONE = 0,
STMT_PARSE_COMPLETE,
STMT_PARSE_INCOMPLETE,
STMT_PARSE_FATAL
};
/* Result style */
enum {
STMT_FETCH_NONE = 0,
STMT_FETCH_NORMAL,
STMT_FETCH_EXTENDED
};
typedef struct {
COL_INFO *col_info; /* cached SQLColumns info for this table */
char name[MAX_TABLE_LEN+1];
char alias[MAX_TABLE_LEN+1];
} TABLE_INFO;
typedef struct {
TABLE_INFO *ti; /* resolve to explicit table names */
int precision;
int display_size;
int length;
int type;
char nullable;
char func;
char expr;
char quote;
char dquote;
char numeric;
char dot[MAX_TABLE_LEN+1];
char name[MAX_COLUMN_LEN+1];
char alias[MAX_COLUMN_LEN+1];
} FIELD_INFO;
/******** Statement Handle ***********/
struct StatementClass_ {
ConnectionClass *hdbc; /* pointer to ConnectionClass this statement belongs to */
QResultClass *result; /* result of the current statement */
HSTMT FAR *phstmt;
StatementOptions options;
STMT_Status status;
char *errormsg;
int errornumber;
/* information on bindings */
BindInfoClass *bindings; /* array to store the binding information */
BindInfoClass bookmark;
int bindings_allocated;
/* information on statement parameters */
int parameters_allocated;
ParameterInfoClass *parameters;
Int4 currTuple; /* current absolute row number (GetData, SetPos, SQLFetch) */
int save_rowset_size; /* saved rowset size in case of change/FETCH_NEXT */
int rowset_start; /* start of rowset (an absolute row number) */
int bind_row; /* current offset for Multiple row/column binding */
int last_fetch_count; /* number of rows retrieved in last fetch/extended fetch */
int current_col; /* current column for GetData -- used to handle multiple calls */
int lobj_fd; /* fd of the current large object */
char *statement; /* if non--null pointer to the SQL statement that has been executed */
TABLE_INFO **ti;
FIELD_INFO **fi;
int nfld;
int ntab;
int parse_status;
int statement_type; /* According to the defines above */
int data_at_exec; /* Number of params needing SQLPutData */
int current_exec_param; /* The current parameter for SQLPutData */
char put_data; /* Has SQLPutData been called yet? */
char errormsg_created; /* has an informative error msg been created? */
char manual_result; /* Is the statement result manually built? */
char prepare; /* is this statement a prepared statement or direct */
char internal; /* Is this statement being called internally? */
char cursor_name[MAX_CURSOR_LEN+1];
char stmt_with_params[65536 /* MAX_STATEMENT_LEN */]; /* statement after parameter substitution */
};
#define SC_get_conn(a) (a->hdbc)
#define SC_get_Result(a) (a->result);
/* options for SC_free_params() */
#define STMT_FREE_PARAMS_ALL 0
#define STMT_FREE_PARAMS_DATA_AT_EXEC_ONLY 1
/* Statement prototypes */
StatementClass *SC_Constructor(void);
void InitializeStatementOptions(StatementOptions *opt);
char SC_Destructor(StatementClass *self);
int statement_type(char *statement);
char parse_statement(StatementClass *stmt);
void SC_pre_execute(StatementClass *self);
char SC_unbind_cols(StatementClass *self);
char SC_recycle_statement(StatementClass *self);
void SC_clear_error(StatementClass *self);
char SC_get_error(StatementClass *self, int *number, char **message);
char *SC_create_errormsg(StatementClass *self);
RETCODE SC_execute(StatementClass *self);
RETCODE SC_fetch(StatementClass *self);
void SC_free_params(StatementClass *self, char option);
void SC_log_error(char *func, char *desc, StatementClass *self);
unsigned long SC_get_bookmark(StatementClass *self);
#endif
|