35 #include <mysql/mysql.h> 44 static int db_backend_mysql_transaction_rollback(
void*);
49 static int __mysql_initialized = 0;
121 if (bind->
bind && bind->
bind->buffer) {
122 free(bind->
bind->buffer);
143 unsigned long i, params;
146 MYSQL_BIND* mysql_bind;
147 MYSQL_RES* result_metadata = NULL;
150 if (!backend_mysql) {
153 if (!backend_mysql->
db) {
169 ods_log_debug(
"%s", sql);
171 || !((*statement)->statement = mysql_stmt_init(backend_mysql->
db))
172 || mysql_stmt_prepare((*statement)->statement, sql, size))
174 if ((*statement)->statement) {
175 ods_log_info(
"DB prepare SQL %s", sql);
176 ods_log_info(
"DB prepare Err %d: %s", mysql_stmt_errno((*statement)->statement), mysql_stmt_error((*statement)->statement));
178 __db_backend_mysql_finish(*statement);
183 (*statement)->backend_mysql = backend_mysql;
189 if ((params = mysql_stmt_param_count((*statement)->statement)) > 0) {
190 if (!((*statement)->mysql_bind_input = calloc(params,
sizeof(MYSQL_BIND)))) {
191 __db_backend_mysql_finish(*statement);
196 for (i = 0; i < params; i++) {
198 __db_backend_mysql_finish(*statement);
203 bind->
bind = &((*statement)->mysql_bind_input[i]);
204 if (!(*statement)->bind_input) {
205 (*statement)->bind_input = bind;
207 if ((*statement)->bind_input_end) {
208 (*statement)->bind_input_end->
next = bind;
210 (*statement)->bind_input_end = bind;
217 if (object_field_list
219 && (result_metadata = mysql_stmt_result_metadata((*statement)->statement)))
222 || !((*statement)->mysql_bind_output = calloc(params,
sizeof(MYSQL_BIND))))
224 mysql_free_result(result_metadata);
225 __db_backend_mysql_finish(*statement);
230 (*statement)->fields = params;
231 field = mysql_fetch_field(result_metadata);
233 for (i = 0; i < params; i++) {
238 mysql_free_result(result_metadata);
239 __db_backend_mysql_finish(*statement);
244 bind->
bind = (mysql_bind = &((*statement)->mysql_bind_output[i]));
245 mysql_bind->is_null = (my_bool*)0;
246 mysql_bind->error = &bind->
error;
247 mysql_bind->length = &bind->
length;
251 switch (field->type) {
252 case MYSQL_TYPE_TINY:
253 case MYSQL_TYPE_SHORT:
254 case MYSQL_TYPE_LONG:
255 case MYSQL_TYPE_INT24:
256 mysql_bind->buffer_type = MYSQL_TYPE_LONG;
258 mysql_free_result(result_metadata);
259 __db_backend_mysql_finish(*statement);
264 bind->
length = mysql_bind->buffer_length;
265 mysql_bind->is_unsigned = 1;
268 case MYSQL_TYPE_LONGLONG:
269 mysql_bind->buffer_type = MYSQL_TYPE_LONGLONG;
271 mysql_free_result(result_metadata);
272 __db_backend_mysql_finish(*statement);
277 bind->
length = mysql_bind->buffer_length;
278 mysql_bind->is_unsigned = 1;
281 case MYSQL_TYPE_STRING:
282 case MYSQL_TYPE_VAR_STRING:
283 mysql_bind->buffer_type = MYSQL_TYPE_STRING;
288 bind->
length = field->length + 1;
292 if (!(mysql_bind->buffer = calloc(1, bind->
length))) {
293 mysql_free_result(result_metadata);
294 __db_backend_mysql_finish(*statement);
298 mysql_bind->buffer_length = bind->
length;
299 mysql_bind->is_unsigned = 0;
303 mysql_free_result(result_metadata);
304 __db_backend_mysql_finish(*statement);
318 mysql_bind->buffer_type = MYSQL_TYPE_LONG;
320 mysql_free_result(result_metadata);
321 __db_backend_mysql_finish(*statement);
326 bind->
length = mysql_bind->buffer_length;
327 mysql_bind->is_unsigned = 0;
331 mysql_bind->buffer_type = MYSQL_TYPE_LONG;
333 mysql_free_result(result_metadata);
334 __db_backend_mysql_finish(*statement);
339 bind->
length = mysql_bind->buffer_length;
340 mysql_bind->is_unsigned = 1;
344 mysql_bind->buffer_type = MYSQL_TYPE_LONGLONG;
346 mysql_free_result(result_metadata);
347 __db_backend_mysql_finish(*statement);
352 bind->
length = mysql_bind->buffer_length;
353 mysql_bind->is_unsigned = 0;
357 mysql_bind->buffer_type = MYSQL_TYPE_LONGLONG;
359 mysql_free_result(result_metadata);
360 __db_backend_mysql_finish(*statement);
365 bind->
length = mysql_bind->buffer_length;
366 mysql_bind->is_unsigned = 1;
370 mysql_bind->buffer_type = MYSQL_TYPE_STRING;
375 bind->
length = field->length + 1;
379 if (!(mysql_bind->buffer = calloc(1, bind->
length))) {
380 mysql_free_result(result_metadata);
381 __db_backend_mysql_finish(*statement);
385 mysql_bind->buffer_length = bind->
length;
386 mysql_bind->is_unsigned = 0;
391 switch (field->type) {
392 case MYSQL_TYPE_TINY:
393 case MYSQL_TYPE_SHORT:
394 case MYSQL_TYPE_LONG:
395 case MYSQL_TYPE_INT24:
396 mysql_bind->buffer_type = MYSQL_TYPE_LONG;
397 if (field->flags & UNSIGNED_FLAG) {
399 mysql_free_result(result_metadata);
400 __db_backend_mysql_finish(*statement);
405 mysql_bind->is_unsigned = 1;
409 mysql_free_result(result_metadata);
410 __db_backend_mysql_finish(*statement);
415 mysql_bind->is_unsigned = 0;
417 bind->
length = mysql_bind->buffer_length;
420 case MYSQL_TYPE_LONGLONG:
421 mysql_bind->buffer_type = MYSQL_TYPE_LONGLONG;
422 if (field->flags & UNSIGNED_FLAG) {
424 mysql_free_result(result_metadata);
425 __db_backend_mysql_finish(*statement);
430 mysql_bind->is_unsigned = 1;
434 mysql_free_result(result_metadata);
435 __db_backend_mysql_finish(*statement);
440 mysql_bind->is_unsigned = 0;
442 bind->
length = mysql_bind->buffer_length;
445 case MYSQL_TYPE_STRING:
446 case MYSQL_TYPE_VAR_STRING:
447 mysql_bind->buffer_type = MYSQL_TYPE_STRING;
452 bind->
length = field->length + 1;
456 if (!(mysql_bind->buffer = calloc(1, bind->
length))) {
457 mysql_free_result(result_metadata);
458 __db_backend_mysql_finish(*statement);
462 mysql_bind->buffer_length = bind->
length;
463 mysql_bind->is_unsigned = 0;
467 mysql_free_result(result_metadata);
468 __db_backend_mysql_finish(*statement);
478 if (!(*statement)->bind_output) {
479 (*statement)->bind_output = bind;
481 if ((*statement)->bind_output_end) {
482 (*statement)->bind_output_end->
next = bind;
484 (*statement)->bind_output_end = bind;
486 field = mysql_fetch_field(result_metadata);
492 if (object_field || field) {
493 mysql_free_result(result_metadata);
494 __db_backend_mysql_finish(*statement);
499 if (result_metadata) {
500 mysql_free_result(result_metadata);
524 if (!statement->
bound) {
528 ods_log_info(
"DB bind result Err %d: %s", mysql_stmt_errno(statement->
statement), mysql_stmt_error(statement->
statement));
531 statement->
bound = 1;
537 ret = mysql_stmt_fetch(statement->
statement);
539 ods_log_info(
"DB fetch Err %d: %s", mysql_stmt_errno(statement->
statement), mysql_stmt_error(statement->
statement));
542 else if (ret == MYSQL_DATA_TRUNCATED) {
555 for (i = 0, bind = statement->
bind_output; bind; i++, bind = bind->
next) {
560 ods_log_info(
"DB fetch Err data truncated");
567 ods_log_info(
"DB fetch Err data truncated");
575 ods_log_info(
"DB fetch Err data truncated");
581 else if (ret == MYSQL_NO_DATA) {
589 ods_log_info(
"DB fetch UNKNOWN %d Err %d: %s", ret, mysql_stmt_errno(statement->
statement), mysql_stmt_error(statement->
statement));
615 ods_log_info(
"DB bind param Err %d: %s", mysql_stmt_errno(statement->
statement), mysql_stmt_error(statement->
statement));
622 if (mysql_stmt_execute(statement->
statement)) {
623 ods_log_info(
"DB execute Err %d: %s", mysql_stmt_errno(statement->
statement), mysql_stmt_error(statement->
statement));
630 static int db_backend_mysql_initialize(
void* data) {
633 if (!backend_mysql) {
637 if (!__mysql_initialized) {
638 if (mysql_library_init(0, NULL, NULL)) {
641 __mysql_initialized = 1;
646 static int db_backend_mysql_shutdown(
void* data) {
649 if (!backend_mysql) {
653 if (__mysql_initialized) {
655 __mysql_initialized = 0;