32
32
#include < string.h>
33
33
#include < stdlib.h>
34
34
#include < stdio.h>
35
+ #include < assert.h>
35
36
36
37
#include < iostream>
37
38
#include < sstream>
@@ -47,6 +48,7 @@ DIAGNOSTIC_POP
47
48
#endif
48
49
#include < cppconn/exception.h>
49
50
#include " mysql_connection.h"
51
+ #include " mysql_connection_data.h"
50
52
#include " mysql_statement.h"
51
53
#include " mysql_prepared_statement.h"
52
54
#include " mysql_ps_resultset.h"
@@ -352,28 +354,68 @@ class MySQL_ParamBind
352
354
};
353
355
354
356
357
+ telemetry::Telemetry<MySQL_Connection>&
358
+ MySQL_Prepared_Statement::conn_telemetry ()
359
+ {
360
+ assert (connection);
361
+ assert (connection->intern );
362
+ return connection->intern ->telemetry ;
363
+ }
364
+
365
+
355
366
/* {{{ MySQL_Prepared_Statement::MySQL_Prepared_Statement() -I- */
356
367
MySQL_Prepared_Statement::MySQL_Prepared_Statement (
357
- std::shared_ptr<NativeAPI::NativeStatementWrapper> &s ,
368
+ const sql::SQLString &sql ,
358
369
MySQL_Connection *conn, sql::ResultSet::enum_type rset_type,
359
370
std::shared_ptr<MySQL_DebugLogger> &log)
360
371
: connection(conn),
361
- proxy (s),
362
372
isClosed (false ),
363
373
warningsHaveBeenLoaded(true ),
364
374
logger(log),
365
375
resultset_type(rset_type),
366
- result_bind(new MySQL_ResultBind(proxy, logger)),
367
376
warningsCount(0 )
368
377
369
378
{
370
379
CPP_ENTER (" MySQL_Prepared_Statement::MySQL_Prepared_Statement" );
371
380
CPP_INFO_FMT (" this=%p" , this );
372
- param_count = proxy->param_count ();
373
- param_bind.reset (new MySQL_ParamBind (param_count));
374
381
375
- res_meta.reset (new MySQL_PreparedResultSetMetaData (proxy, logger));
376
- param_meta.reset (new MySQL_ParameterMetaData (proxy));
382
+ std::shared_ptr<NativeAPI::NativeStatementWrapper> stmt;
383
+
384
+ // TODO change - probably no need to catch and throw here. Logging can be done inside proxy
385
+ auto &connProxy = connection->proxy ;
386
+ try {
387
+ stmt.reset (&connProxy->stmt_init ());
388
+ } catch (sql::SQLException& e) {
389
+ CPP_ERR_FMT (" No statement : %d:(%s) %s" , connProxy->errNo (),
390
+ connProxy->sqlstate ().c_str (), connProxy->error ().c_str ());
391
+ throw e;
392
+ }
393
+
394
+ telemetry.span_start (this , " SQL prepare" );
395
+ try
396
+ {
397
+ if (stmt->prepare (sql)) {
398
+ CPP_ERR_FMT (" Cannot prepare %d:(%s) %s" , stmt->errNo (), stmt->sqlstate ().c_str (), stmt->error ().c_str ());
399
+ sql::SQLException e (stmt->error (), stmt->sqlstate (), stmt->errNo ());
400
+ stmt.reset ();
401
+ throw e;
402
+ }
403
+
404
+ proxy = stmt;
405
+ result_bind.reset (new MySQL_ResultBind (proxy, logger));
406
+
407
+ param_count = proxy->param_count ();
408
+ param_bind.reset (new MySQL_ParamBind (param_count));
409
+
410
+ res_meta.reset (new MySQL_PreparedResultSetMetaData (proxy, logger));
411
+ param_meta.reset (new MySQL_ParameterMetaData (proxy));
412
+ }
413
+ catch (sql::SQLException &e)
414
+ {
415
+ telemetry.set_error (this , e.what ());
416
+ throw ;
417
+ }
418
+ telemetry.span_end (this );
377
419
}
378
420
/* }}} */
379
421
@@ -418,20 +460,30 @@ MySQL_Prepared_Statement::sendLongDataBeforeParamBind()
418
460
void
419
461
MySQL_Prepared_Statement::do_query ()
420
462
{
421
- CPP_ENTER (" MySQL_Prepared_Statement::do_query" );
422
- if (param_count && !param_bind->isAllSet ()) {
423
- CPP_ERR (" Value not set for all parameters" );
424
- throw sql::SQLException (" Value not set for all parameters" );
425
- }
463
+ telemetry.span_start (this , " SQL execute" );
426
464
427
- if (proxy->bind_param (param_bind->getBindObject ())) {
428
- CPP_ERR_FMT (" Couldn't bind : %d:(%s) %s" , proxy->errNo (), proxy->sqlstate ().c_str (), proxy->error ().c_str ());
429
- sql::mysql::util::throwSQLException (*proxy.get ());
430
- }
465
+ try
466
+ {
467
+ CPP_ENTER (" MySQL_Prepared_Statement::do_query" );
468
+ if (param_count && !param_bind->isAllSet ()) {
469
+ CPP_ERR (" Value not set for all parameters" );
470
+ throw sql::SQLException (" Value not set for all parameters" );
471
+ }
472
+
473
+ if (proxy->bind_param (param_bind->getBindObject ())) {
474
+ CPP_ERR_FMT (" Couldn't bind : %d:(%s) %s" , proxy->errNo (), proxy->sqlstate ().c_str (), proxy->error ().c_str ());
475
+ sql::mysql::util::throwSQLException (*proxy.get ());
476
+ }
431
477
432
- if (!sendLongDataBeforeParamBind () || proxy->execute ()) {
433
- CPP_ERR_FMT (" Couldn't execute : %d:(%s) %s" , proxy->errNo (), proxy->sqlstate ().c_str (), proxy->error ().c_str ());
434
- sql::mysql::util::throwSQLException (*proxy.get ());
478
+ if (!sendLongDataBeforeParamBind () || proxy->execute ()) {
479
+ CPP_ERR_FMT (" Couldn't execute : %d:(%s) %s" , proxy->errNo (), proxy->sqlstate ().c_str (), proxy->error ().c_str ());
480
+ sql::mysql::util::throwSQLException (*proxy.get ());
481
+ }
482
+ }
483
+ catch (sql::SQLException &e)
484
+ {
485
+ telemetry.set_error (this , e.what ());
486
+ throw ;
435
487
}
436
488
437
489
warningsCount= proxy->warning_count ();
@@ -473,6 +525,12 @@ MySQL_Prepared_Statement::execute()
473
525
CPP_INFO_FMT (" this=%p" , this );
474
526
checkClosed ();
475
527
do_query ();
528
+
529
+ if (proxy->num_rows () == 0 && !proxy->more_results ())
530
+ {
531
+ // No result set, just end the span
532
+ telemetry.span_end (this );
533
+ }
476
534
return (proxy->field_count () > 0 );
477
535
}
478
536
/* }}} */
@@ -499,23 +557,7 @@ MySQL_Prepared_Statement::executeQuery()
499
557
500
558
do_query ();
501
559
502
- my_bool bool_tmp=1 ;
503
- proxy->attr_set ( STMT_ATTR_UPDATE_MAX_LENGTH, &bool_tmp);
504
- sql::ResultSet::enum_type tmp_type;
505
- if (resultset_type == sql::ResultSet::TYPE_SCROLL_INSENSITIVE) {
506
- if (proxy->store_result ()) {
507
- sql::mysql::util::throwSQLException (*proxy.get ());
508
- }
509
- tmp_type = sql::ResultSet::TYPE_SCROLL_INSENSITIVE;
510
- } else if (resultset_type == sql::ResultSet::TYPE_FORWARD_ONLY) {
511
- tmp_type = sql::ResultSet::TYPE_FORWARD_ONLY;
512
- } else {
513
- throw SQLException (" Invalid value for result set type" );
514
- }
515
- sql::ResultSet * tmp = new MySQL_Prepared_ResultSet (proxy, result_bind, tmp_type, this , logger);
516
-
517
- CPP_INFO_FMT (" rset=%p" , tmp);
518
- return tmp;
560
+ return _getResultSet ();
519
561
}
520
562
/* }}} */
521
563
@@ -538,6 +580,8 @@ MySQL_Prepared_Statement::executeUpdate()
538
580
CPP_INFO_FMT (" this=%p" , this );
539
581
checkClosed ();
540
582
do_query ();
583
+ // No result set, just end the span
584
+ telemetry.span_end (this );
541
585
return static_cast <int >(proxy->affected_rows ());
542
586
}
543
587
/* }}} */
@@ -1017,32 +1061,50 @@ MySQL_Prepared_Statement::getParameterMetaData()
1017
1061
/* }}} */
1018
1062
1019
1063
1020
- /* {{{ MySQL_Prepared_Statement::getResultSet() -I- */
1021
1064
sql::ResultSet *
1022
- MySQL_Prepared_Statement::getResultSet ()
1065
+ MySQL_Prepared_Statement::_getResultSet ()
1023
1066
{
1024
- CPP_ENTER (" MySQL_Prepared_Statement::getResultSet" );
1025
- CPP_INFO_FMT (" this=%p" , this );
1026
- checkClosed ();
1027
-
1028
1067
my_bool bool_tmp = 1 ;
1029
- proxy->attr_set (STMT_ATTR_UPDATE_MAX_LENGTH, &bool_tmp);
1030
- sql::ResultSet::enum_type tmp_type;
1031
- if (resultset_type == sql::ResultSet::TYPE_SCROLL_INSENSITIVE) {
1032
- if (proxy->store_result ()) {
1033
- sql::mysql::util::throwSQLException (*proxy.get ());
1068
+ try
1069
+ {
1070
+ proxy->attr_set (STMT_ATTR_UPDATE_MAX_LENGTH, &bool_tmp);
1071
+ sql::ResultSet::enum_type tmp_type;
1072
+ if (resultset_type == sql::ResultSet::TYPE_SCROLL_INSENSITIVE) {
1073
+ if (proxy->store_result ()) {
1074
+ sql::mysql::util::throwSQLException (*proxy.get ());
1075
+ }
1076
+ tmp_type = sql::ResultSet::TYPE_SCROLL_INSENSITIVE;
1077
+ } else if (resultset_type == sql::ResultSet::TYPE_FORWARD_ONLY) {
1078
+ tmp_type = sql::ResultSet::TYPE_FORWARD_ONLY;
1079
+ } else {
1080
+ throw SQLException (" Invalid value for result set type" );
1034
1081
}
1035
- tmp_type = sql::ResultSet::TYPE_SCROLL_INSENSITIVE;
1036
- } else if (resultset_type == sql::ResultSet::TYPE_FORWARD_ONLY) {
1037
- tmp_type = sql::ResultSet::TYPE_FORWARD_ONLY;
1038
- } else {
1039
- throw SQLException (" Invalid value for result set type" );
1082
+
1083
+ sql::ResultSet * tmp = new MySQL_Prepared_ResultSet (proxy, result_bind, tmp_type, this , logger);
1084
+
1085
+ CPP_INFO_FMT (" rset=%p" , tmp);
1086
+ return tmp;
1087
+ }
1088
+ catch (sql::SQLException &e)
1089
+ {
1090
+ telemetry.set_error (this , e.what ());
1091
+ throw ;
1040
1092
}
1041
1093
1042
- sql::ResultSet * tmp = new MySQL_Prepared_ResultSet (proxy, result_bind, tmp_type, this , logger);
1094
+ // Normally it should never come to this line.
1095
+ return nullptr ;
1096
+ }
1097
+ /* }}} */
1098
+
1043
1099
1044
- CPP_INFO_FMT (" rset=%p" , tmp);
1045
- return tmp;
1100
+ /* {{{ MySQL_Prepared_Statement::getResultSet() -I- */
1101
+ sql::ResultSet *
1102
+ MySQL_Prepared_Statement::getResultSet ()
1103
+ {
1104
+ CPP_ENTER (" MySQL_Prepared_Statement::getResultSet" );
1105
+ CPP_INFO_FMT (" this=%p" , this );
1106
+ checkClosed ();
1107
+ return _getResultSet ();
1046
1108
}
1047
1109
/* }}} */
1048
1110
@@ -1126,12 +1188,17 @@ MySQL_Prepared_Statement::getMoreResults()
1126
1188
CPP_INFO_FMT (" this=%p" , this );
1127
1189
checkClosed ();
1128
1190
1129
- if (proxy->more_results ()) {
1130
-
1191
+ if (proxy->more_results ())
1192
+ try
1193
+ {
1131
1194
int next_result = proxy->stmt_next_result ();
1132
1195
1133
1196
if (next_result == 0 ) {
1134
1197
bool ret = proxy->field_count () > 0 ;
1198
+ if (!ret)
1199
+ {
1200
+ telemetry.span_end (this );
1201
+ }
1135
1202
return ret;
1136
1203
} else if (next_result == -1 ) {
1137
1204
throw sql::SQLException (" Impossible! more_results() said true, next_result says no more results" );
@@ -1140,8 +1207,14 @@ MySQL_Prepared_Statement::getMoreResults()
1140
1207
sql::mysql::util::throwSQLException (*proxy.get ());
1141
1208
}
1142
1209
}
1143
- return false ;
1210
+ catch (sql::SQLException &e)
1211
+ {
1212
+ telemetry.set_error (this , e.what ());
1213
+ throw ;
1214
+ }
1144
1215
1216
+ telemetry.span_end (this );
1217
+ return false ;
1145
1218
}
1146
1219
/* }}} */
1147
1220
0 commit comments