1 /* Copyright (C) 2004 MySQL AB 2 Copyright (C) 2004-2017 Alexey Kopytov <akopytov@gmail.com> 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 2 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program; if not, write to the Free Software 16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 19 #ifndef DB_DRIVER_H 20 #define DB_DRIVER_H 21 22 #ifdef HAVE_CONFIG_H 23 # include "config.h" 24 #endif 25 26 #include "sysbench.h" 27 #include "sb_list.h" 28 #include "sb_histogram.h" 29 #include "sb_counter.h" 30 31 /* Prepared statements usage modes */ 32 33 typedef enum 34 { 35 DB_PS_MODE_AUTO, 36 DB_PS_MODE_DISABLE, 37 } db_ps_mode_t; 38 39 /* Global DB API options */ 40 41 typedef struct 42 { 43 db_ps_mode_t ps_mode; /* Requested prepared statements usage mode */ 44 char *driver; /* Requested database driver */ 45 unsigned char debug; /* debug flag */ 46 } db_globals_t; 47 48 /* Driver capabilities definition */ 49 50 typedef struct 51 { 52 char multi_rows_insert; /* 1 if database supports multi-row inserts */ 53 char prepared_statements; /* 1 if database supports prepared statements */ 54 char auto_increment; /* 1 if database supports AUTO_INCREMENT clause */ 55 char needs_commit; /* 1 if database needs explicit commit after INSERTs */ 56 char serial; /* 1 if database supports SERIAL clause */ 57 char unsigned_int; /* 1 if database supports UNSIGNED INTEGER types */ 58 } drv_caps_t; 59 60 /* Database errors definition */ 61 62 typedef enum 63 { 64 DB_ERROR_NONE, /* no error(s) */ 65 DB_ERROR_IGNORABLE, /* error should be ignored as defined by command 66 line arguments or a custom error handler */ 67 DB_ERROR_FATAL /* non-ignorable error */ 68 } db_error_t; 69 70 71 /* Available buffer types (for parameters binding) */ 72 73 typedef enum 74 { 75 DB_TYPE_NONE, 76 DB_TYPE_TINYINT, 77 DB_TYPE_SMALLINT, 78 DB_TYPE_INT, 79 DB_TYPE_BIGINT, 80 DB_TYPE_FLOAT, 81 DB_TYPE_DOUBLE, 82 DB_TYPE_TIME, 83 DB_TYPE_DATE, 84 DB_TYPE_DATETIME, 85 DB_TYPE_TIMESTAMP, 86 DB_TYPE_CHAR, 87 DB_TYPE_VARCHAR 88 } db_bind_type_t; 89 90 91 /* Structure used to represent DATE, TIME, DATETIME and TIMESTAMP values */ 92 93 typedef struct 94 { 95 unsigned int year; 96 unsigned int month; 97 unsigned int day; 98 unsigned int hour; 99 unsigned int minute; 100 unsigned int second; 101 } db_time_t; 102 103 104 /* Structure used to bind data for prepared statements */ 105 106 typedef struct 107 { 108 db_bind_type_t type; 109 void *buffer; 110 unsigned long *data_len; 111 unsigned long max_len; 112 char *is_null; 113 } db_bind_t; 114 115 /* Forward declarations */ 116 117 struct db_conn; 118 struct db_stmt; 119 struct db_result; 120 struct db_row; 121 122 /* Driver operations definition */ 123 124 typedef int drv_op_init(void); 125 typedef int drv_op_thread_init(int); 126 typedef int drv_op_describe(drv_caps_t *); 127 typedef int drv_op_connect(struct db_conn *); 128 typedef int drv_op_reconnect(struct db_conn *); 129 typedef int drv_op_disconnect(struct db_conn *); 130 typedef int drv_op_prepare(struct db_stmt *, const char *, size_t); 131 typedef int drv_op_bind_param(struct db_stmt *, db_bind_t *, size_t); 132 typedef int drv_op_bind_result(struct db_stmt *, db_bind_t *, size_t); 133 typedef db_error_t drv_op_execute(struct db_stmt *, struct db_result *); 134 typedef int drv_op_fetch(struct db_result *); 135 typedef int drv_op_fetch_row(struct db_result *, struct db_row *); 136 typedef db_error_t drv_op_query(struct db_conn *, const char *, size_t, 137 struct db_result *); 138 typedef int drv_op_free_results(struct db_result *); 139 typedef int drv_op_close(struct db_stmt *); 140 typedef int drv_op_thread_done(int); 141 typedef int drv_op_done(void); 142 143 typedef struct 144 { 145 drv_op_init *init; /* initializate driver */ 146 drv_op_thread_init *thread_init; /* thread-local driver initialization */ 147 drv_op_describe *describe; /* describe database capabilities */ 148 drv_op_connect *connect; /* connect to database */ 149 drv_op_disconnect *disconnect; /* disconnect from database */ 150 drv_op_reconnect *reconnect; /* reconnect with the same parameters */ 151 drv_op_prepare *prepare; /* prepare statement */ 152 drv_op_bind_param *bind_param; /* bind params for prepared statement */ 153 drv_op_bind_result *bind_result; /* bind results for prepared statement */ 154 drv_op_execute *execute; /* execute prepared statement */ 155 drv_op_fetch *fetch; /* fetch row for prepared statement */ 156 drv_op_fetch_row *fetch_row; /* fetch row for queries */ 157 drv_op_free_results *free_results; /* free result set */ 158 drv_op_close *close; /* close prepared statement */ 159 drv_op_query *query; /* execute non-prepared statement */ 160 drv_op_thread_done *thread_done; /* thread-local driver deinitialization */ 161 drv_op_done *done; /* uninitialize driver */ 162 } drv_ops_t; 163 164 /* Database driver definition */ 165 166 typedef struct 167 { 168 const char *sname; /* short name */ 169 const char *lname; /* long name */ 170 sb_arg_t *args; /* driver command line arguments */ 171 drv_ops_t ops; /* driver operations */ 172 173 sb_list_item_t listitem; /* can be linked in a list */ 174 bool initialized; 175 pthread_mutex_t mutex; 176 } db_driver_t; 177 178 /* Row value definition */ 179 180 typedef struct { 181 uint32_t len; /* Value length */ 182 const char *ptr; /* Value string */ 183 } db_value_t; 184 185 /* Result set row definition */ 186 187 typedef struct db_row 188 { 189 void *ptr; /* Driver-specific row data */ 190 db_value_t *values; /* Array of column values */ 191 } db_row_t; 192 193 /* Result set definition */ 194 195 typedef struct db_result 196 { 197 sb_counter_type_t counter; /* Statistical counter type */ 198 uint32_t nrows; /* Number of affected rows */ 199 uint32_t nfields; /* Number of fields */ 200 struct db_stmt *statement; /* Pointer to prepared statement (if used) */ 201 void *ptr; /* Pointer to driver-specific data */ 202 db_row_t row; /* Last fetched row */ 203 } db_result_t; 204 205 typedef enum { 206 DB_CONN_READY, 207 DB_CONN_RESULT_SET, 208 DB_CONN_INVALID 209 } db_conn_state_t; 210 211 /* Database connection structure */ 212 213 typedef struct db_conn 214 { 215 db_error_t error; /* Database-independent error code */ 216 int sql_errno; /* Database-specific error code */ 217 const char *sql_state; /* Database-specific SQL state */ 218 const char *sql_errmsg; /* Database-specific error message */ 219 db_driver_t *driver; /* DB driver for this connection */ 220 void *ptr; /* Driver-specific data */ 221 db_result_t rs; /* Result set */ 222 db_conn_state_t state; /* Connection state */ 223 int thread_id; /* Thread this connection belongs to */ 224 225 unsigned int bulk_cnt; /* Current number of rows in bulk insert buffer */ 226 unsigned int bulk_buflen; /* Current length of bulk_buffer */ 227 char *bulk_buffer; /* Bulk insert query buffer */ 228 unsigned int bulk_ptr; /* Current position in bulk_buffer */ 229 unsigned int bulk_values; /* Save value of bulk_ptr */ 230 unsigned int bulk_commit_cnt; /* Current value of uncommitted rows */ 231 unsigned int bulk_commit_max; /* Maximum value of uncommitted rows */ 232 233 char pad[SB_CACHELINE_PAD(sizeof(db_error_t) + 234 sizeof(int) + 235 sizeof(void *) + 236 sizeof(void *) + 237 sizeof(void *) + 238 sizeof(void *) + 239 sizeof(db_result_t) + 240 sizeof(db_conn_state_t) + 241 sizeof(int) + 242 sizeof(int) * 2 + 243 sizeof(void *) + 244 sizeof(int) * 4 245 )]; 246 } db_conn_t; 247 248 /* Prepared statement definition */ 249 250 typedef struct db_stmt 251 { 252 db_conn_t *connection; /* Connection which this statement belongs to */ 253 char *query; /* Query string for emulated PS */ 254 db_bind_t *bound_param; /* Array of bound parameters for emulated PS */ 255 unsigned int bound_param_len; /* Length of the bound_param array */ 256 db_bind_t *bound_res; /* Array of bound results for emulated PS */ 257 db_bind_t *bound_res_len; /* Length of the bound_res array */ 258 char emulated; /* Should this statement be emulated? */ 259 sb_counter_type_t counter; /* Query type */ 260 void *ptr; /* Pointer to driver-specific data structure */ 261 } db_stmt_t; 262 263 extern db_globals_t db_globals; 264 265 /* Database abstraction layer calls */ 266 267 int db_register(void); 268 269 void db_print_help(void); 270 271 db_driver_t *db_create(const char *); 272 273 int db_destroy(db_driver_t *); 274 275 int db_describe(db_driver_t *, drv_caps_t *); 276 277 db_conn_t *db_connection_create(db_driver_t *); 278 279 int db_connection_close(db_conn_t *); 280 281 int db_connection_reconnect(db_conn_t *con); 282 283 void db_connection_free(db_conn_t *con); 284 285 db_stmt_t *db_prepare(db_conn_t *, const char *, size_t); 286 287 int db_bind_param(db_stmt_t *, db_bind_t *, size_t); 288 289 int db_bind_result(db_stmt_t *, db_bind_t *, size_t); 290 291 db_result_t *db_execute(db_stmt_t *); 292 293 db_row_t *db_fetch_row(db_result_t *); 294 295 db_result_t *db_query(db_conn_t *, const char *, size_t len); 296 297 int db_free_results(db_result_t *); 298 299 int db_store_results(db_result_t *); 300 301 int db_close(db_stmt_t *); 302 303 void db_done(void); 304 305 int db_print_value(db_bind_t *, char *, int); 306 307 /* Initialize multi-row insert operation */ 308 int db_bulk_insert_init(db_conn_t *, const char *, size_t); 309 310 /* Add row to multi-row insert operation */ 311 int db_bulk_insert_next(db_conn_t *, const char *, size_t); 312 313 /* Finish multi-row insert operation */ 314 int db_bulk_insert_done(db_conn_t *); 315 316 /* Print database-specific test stats */ 317 void db_report_intermediate(sb_stat_t *); 318 void db_report_cumulative(sb_stat_t *); 319 320 /* DB drivers registrars */ 321 322 #ifdef USE_MYSQL 323 int register_driver_mysql(sb_list_t *); 324 #endif 325 326 #ifdef USE_DRIZZLE 327 int register_driver_drizzle(sb_list_t *); 328 #endif 329 330 #ifdef USE_ATTACHSQL 331 int register_driver_attachsql(sb_list_t *); 332 #endif 333 334 #ifdef USE_DRIZZLECLIENT 335 int register_driver_drizzleclient(sb_list_t *); 336 #endif 337 338 #ifdef USE_ORACLE 339 int register_driver_oracle(sb_list_t *); 340 #endif 341 342 #ifdef USE_PGSQL 343 int register_driver_pgsql(sb_list_t *); 344 #endif 345 346 #endif /* DB_DRIVER_H */ 347