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 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335
|
/*
* DBD::mysql - DBI driver for the MySQL database
*
* Copyright (c) 2005 Patrick Galbraith
* Copyright (c) 2003 Rudolf Lippan
* Copyright (c) 1997-2003 Jochen Wiedmann
*
* Based on DBD::Oracle; DBD::Oracle is
*
* Copyright (c) 1994,1995 Tim Bunce
*
* You may distribute this under the terms of either the GNU General Public
* License or the Artistic License, as specified in the Perl README file.
*
* $Id$
*/
/*
* Header files we use
*/
#include <DBIXS.h> /* installed by the DBI module */
#include <mysql.h> /* Comes with MySQL-devel */
#include <mysqld_error.h> /* Comes MySQL */
#include <errmsg.h> /* Comes with MySQL-devel */
/*
* This is the version of MySQL wherer
* the server will be used to process prepare
* statements as opposed to emulation in the driver
*/
#define SQL_STATE_VERSION 40101
#define WARNING_COUNT_VERSION 40101
#define FIELD_CHARSETNR_VERSION 40101 /* should equivalent to 4.1.0 */
#define MULTIPLE_RESULT_SET_VERSION 40102
#define SERVER_PREPARE_VERSION 40103
#define LIMIT_PLACEHOLDER_VERSION 50100
#define GEO_DATATYPE_VERSION 50007
#define NEW_DATATYPE_VERSION 50003
#define SSL_VERIFY_VERSION 50023
#define MYSQL_VERSION_5_0 50001
/* This is to avoid the ugly #ifdef mess in dbdimp.c */
#if MYSQL_VERSION_ID < SQL_STATE_VERSION
#define mysql_sqlstate(svsock) (NULL)
#endif
#if MYSQL_VERSION_ID < WARNING_COUNT_VERSION
#define mysql_warning_count(svsock) 0
#endif
#define true 1
#define false 0
/*
* The following are return codes passed in $h->err in case of
* errors by DBD::mysql.
*/
enum errMsgs {
JW_ERR_CONNECT = 1,
JW_ERR_SELECT_DB,
JW_ERR_STORE_RESULT,
JW_ERR_NOT_ACTIVE,
JW_ERR_QUERY,
JW_ERR_FETCH_ROW,
JW_ERR_LIST_DB,
JW_ERR_CREATE_DB,
JW_ERR_DROP_DB,
JW_ERR_LIST_TABLES,
JW_ERR_LIST_FIELDS,
JW_ERR_LIST_FIELDS_INT,
JW_ERR_LIST_SEL_FIELDS,
JW_ERR_NO_RESULT,
JW_ERR_NOT_IMPLEMENTED,
JW_ERR_ILLEGAL_PARAM_NUM,
JW_ERR_MEM,
JW_ERR_LIST_INDEX,
JW_ERR_SEQUENCE,
AS_ERR_EMBEDDED,
TX_ERR_AUTOCOMMIT,
TX_ERR_COMMIT,
TX_ERR_ROLLBACK
};
/*
* Internal constants, used for fetching array attributes
*/
enum av_attribs {
AV_ATTRIB_NAME = 0,
AV_ATTRIB_TABLE,
AV_ATTRIB_TYPE,
AV_ATTRIB_SQL_TYPE,
AV_ATTRIB_IS_PRI_KEY,
AV_ATTRIB_IS_NOT_NULL,
AV_ATTRIB_NULLABLE,
AV_ATTRIB_LENGTH,
AV_ATTRIB_IS_NUM,
AV_ATTRIB_TYPE_NAME,
AV_ATTRIB_PRECISION,
AV_ATTRIB_SCALE,
AV_ATTRIB_MAX_LENGTH,
AV_ATTRIB_IS_KEY,
AV_ATTRIB_IS_BLOB,
AV_ATTRIB_IS_AUTO_INCREMENT,
AV_ATTRIB_LAST /* Dummy attribute, never used, for allocation */
}; /* purposes only */
/*
* This is our part of the driver handle. We receive the handle as
* an "SV*", say "drh", and receive a pointer to the structure below
* by declaring
*
* D_imp_drh(drh);
*
* This declares a variable called "imp_drh" of type
* "struct imp_drh_st *".
*/
typedef struct imp_drh_embedded_st {
int state;
SV * args;
SV * groups;
} imp_drh_embedded_t;
struct imp_drh_st {
dbih_drc_t com; /* MUST be first element in structure */
#if defined(DBD_MYSQL_EMBEDDED)
imp_drh_embedded_t embedded; /* */
#endif
};
/*
* Likewise, this is our part of the database handle, as returned
* by DBI->connect. We receive the handle as an "SV*", say "dbh",
* and receive a pointer to the structure below by declaring
*
* D_imp_dbh(dbh);
*
* This declares a variable called "imp_dbh" of type
* "struct imp_dbh_st *".
*/
struct imp_dbh_st {
dbih_dbc_t com; /* MUST be first element in structure */
MYSQL *pmysql;
bool has_transactions; /* boolean indicating support for
* transactions, currently always TRUE for MySQL
*/
bool auto_reconnect;
bool bind_type_guessing;
bool bind_comment_placeholders;
bool no_autocommit_cmd;
bool use_mysql_use_result; /* TRUE if execute should use
* mysql_use_result rather than
* mysql_store_result
*/
bool use_server_side_prepare;
#if defined(sv_utf8_decode) && MYSQL_VERSION_ID >=SERVER_PREPARE_VERSION
bool enable_utf8;
#endif
struct {
unsigned int auto_reconnects_ok;
unsigned int auto_reconnects_failed;
} stats;
};
/*
* The bind_param method internally uses this structure for storing
* parameters.
*/
typedef struct imp_sth_ph_st {
SV* value;
int type;
} imp_sth_ph_t;
/*
* The bind_param method internally uses this structure for storing
* parameters.
*/
typedef struct imp_sth_phb_st {
union
{
long lval;
double dval;
} numeric_val;
unsigned long length;
char is_null;
} imp_sth_phb_t;
/*
* The dbd_describe uses this structure for storing
* fields meta info.
* Added ddata, ldata, lldata for accomodate
* being able to use different data types
* 12.02.20004 PMG
*/
typedef struct imp_sth_fbh_st {
unsigned long length;
bool is_null;
char *data;
int charsetnr;
double ddata;
long ldata;
} imp_sth_fbh_t;
typedef struct imp_sth_fbind_st {
unsigned long * length;
char * is_null;
} imp_sth_fbind_t;
/*
* Finally our part of the statement handle. We receive the handle as
* an "SV*", say "dbh", and receive a pointer to the structure below
* by declaring
*
* D_imp_sth(sth);
*
* This declares a variable called "imp_sth" of type
* "struct imp_sth_st *".
*/
struct imp_sth_st {
dbih_stc_t com; /* MUST be first element in structure */
#if (MYSQL_VERSION_ID >= SERVER_PREPARE_VERSION)
MYSQL_STMT *stmt;
MYSQL_BIND *bind;
MYSQL_BIND *buffer;
imp_sth_phb_t *fbind;
imp_sth_fbh_t *fbh;
int has_been_bound;
int use_server_side_prepare; /* server side prepare statements? */
#endif
MYSQL_RES* result; /* result */
int currow; /* number of current row */
int fetch_done; /* mark that fetch done */
my_ulonglong row_num; /* total number of rows */
int done_desc; /* have we described this sth yet ? */
long long_buflen; /* length for long/longraw (if >0) */
bool long_trunc_ok; /* is truncating a long an error */
my_ulonglong insertid; /* ID of auto insert */
int warning_count; /* Number of warnings after execute() */
imp_sth_ph_t* params; /* Pointer to parameter array */
AV* av_attr[AV_ATTRIB_LAST];/* For caching array attributes */
int use_mysql_use_result; /* TRUE if execute should use */
/* mysql_use_result rather than */
/* mysql_store_result */
};
/*
* And last, not least: The prototype definitions.
*
* These defines avoid name clashes for multiple statically linked DBD's */
#define dbd_init mysql_dr_init
#define dbd_db_login mysql_db_login
#define dbd_db_do mysql_db_do
#define dbd_db_commit mysql_db_commit
#define dbd_db_rollback mysql_db_rollback
#define dbd_db_disconnect mysql_db_disconnect
#define dbd_db_destroy mysql_db_destroy
#define dbd_db_STORE_attrib mysql_db_STORE_attrib
#define dbd_db_FETCH_attrib mysql_db_FETCH_attrib
#define dbd_st_prepare mysql_st_prepare
#define dbd_st_execute mysql_st_execute
#define dbd_st_fetch mysql_st_fetch
#define dbd_st_more_results mysql_st_next_results
#define dbd_st_finish mysql_st_finish
#define dbd_st_destroy mysql_st_destroy
#define dbd_st_blob_read mysql_st_blob_read
#define dbd_st_STORE_attrib mysql_st_STORE_attrib
#define dbd_st_FETCH_attrib mysql_st_FETCH_attrib
#define dbd_st_FETCH_internal mysql_st_FETCH_internal
#define dbd_describe mysql_describe
#define dbd_bind_ph mysql_bind_ph
#define BindParam mysql_st_bind_param
#define mymsql_constant mysql_constant
#define do_warn mysql_dr_warn
#define do_error mysql_dr_error
#define dbd_db_type_info_all mysql_db_type_info_all
#define dbd_db_quote mysql_db_quote
#ifdef DBD_MYSQL_INSERT_ID_IS_GOOD /* prototype was broken in some versions of dbi */
#define dbd_db_last_insert_id mysql_db_last_insert_id
#endif
#include <dbd_xsh.h>
void do_error (SV* h, int rc, const char *what, const char *sqlstate);
SV *dbd_db_fieldlist (MYSQL_RES* res);
void dbd_preparse (imp_sth_t *imp_sth, SV *statement);
my_ulonglong mysql_st_internal_execute(SV *,
SV *,
SV *,
int,
imp_sth_ph_t *,
MYSQL_RES **,
MYSQL *,
int);
#if MYSQL_VERSION_ID >= SERVER_PREPARE_VERSION
my_ulonglong mysql_st_internal_execute41(SV *,
int,
MYSQL_RES **,
MYSQL_STMT *,
MYSQL_BIND *,
int *);
int mysql_st_clean_cursor(SV*, imp_sth_t*);
#endif
#if defined(DBD_MYSQL_EMBEDDED)
int count_embedded_options(char *);
char ** fill_out_embedded_options(char *, int , int , int );
int free_embedded_options(char **, int);
/* We have to define dbd_discon_all method for mysqlEmb driver at least
to be able to stop embedded server properly */
#define dbd_discon_all dbd_discon_all
#endif
AV* dbd_db_type_info_all (SV* dbh, imp_dbh_t* imp_dbh);
SV* dbd_db_quote(SV*, SV*, SV*);
extern MYSQL* mysql_dr_connect(SV*, MYSQL*, char*, char*, char*, char*, char*,
char*, imp_dbh_t*);
extern int mysql_db_reconnect(SV*);
int mysql_st_free_result_sets (SV * sth, imp_sth_t * imp_sth);
|