102
102
#define DECLARE_VERBOSE(name, printf_mask, verbose_mask, value, help_desc) \
103
103
class Verbose_Callback_##name : public Verbose_Callback \
106
106
Verbose_Callback_##name() \
108
::g_verbose_error |= \
109
(0 == strcmp( #name, "Error_Explain_Length" )) \
110
|| (0 == strcmp( #name, "Error_Explain_Data")); \
108
::g_verbose_error |= \
109
(0 == strcmp( #name, "Error_Explain_Length" )) \
110
|| (0 == strcmp( #name, "Error_Explain_Data")); \
112
112
static const char* mask() \
114
114
return verbose_mask; \
182
182
void set_verbose(const char* mask)
184
184
if (0 == strcmp(mask, "full"))
186
verbose_callback_variable= full_verbose_callback;
187
g_verbose_error= true;
186
verbose_callback_variable= full_verbose_callback;
187
g_verbose_error= true;
189
189
else if (0 == strcmp(mask, "error"))
191
verbose_callback_variable= error_verbose_callback;
192
g_verbose_error= true;
191
verbose_callback_variable= error_verbose_callback;
192
g_verbose_error= true;
194
194
else if (0 == strcmp(mask, "status"))
195
195
verbose_callback_variable= status_verbose_callback;
196
196
else if (0 == strcmp(mask, "quiet"))
197
197
verbose_callback_variable= quiet_verbose_callback;
200
verbose_callback_variable= &custom_verbose_callback;
201
const char *mask_backup= mask;
202
Verbose_Callback_Pointer fill(new Verbose_Callback_Fill());
203
for (std::size_t length= strlen(mask); length > 0; --length, ++mask)
200
verbose_callback_variable= &custom_verbose_callback;
201
const char *mask_backup= mask;
202
Verbose_Callback_Pointer fill(new Verbose_Callback_Fill());
203
for (std::size_t length= strlen(mask); length > 0; --length, ++mask)
207
const char *current_mask;
208
std::size_t current_mask_length;
207
const char *current_mask;
208
std::size_t current_mask_length;
209
209
#define ADD(name) \
210
current_mask= Verbose_Callback_##name::mask(); \
211
current_mask_length= strlen(current_mask); \
212
if (length >= current_mask_length \
213
&& 0 == strncmp(mask, \
215
current_mask_length)) \
217
Verbose_Callback_Pointer current(new Verbose_Callback_##name()); \
218
custom_verbose_callback_vector.push_back(current); \
219
mask += current_mask_length - 1; \
220
length -= current_mask_length - 1; \
223
ADD(Original_Thread);
230
ADD(Error_Explain_Length);
231
ADD(Error_Explain_Data);
232
ADD(Query_Explain_Length);
233
ADD(Query_Explain_Data);
210
current_mask= Verbose_Callback_##name::mask(); \
211
current_mask_length= strlen(current_mask); \
212
if (length >= current_mask_length \
213
&& 0 == strncmp(mask, \
215
current_mask_length)) \
217
Verbose_Callback_Pointer current(new Verbose_Callback_##name()); \
218
custom_verbose_callback_vector.push_back(current); \
219
mask += current_mask_length - 1; \
220
length -= current_mask_length - 1; \
223
ADD(Original_Thread);
230
ADD(Error_Explain_Length);
231
ADD(Error_Explain_Data);
232
ADD(Query_Explain_Length);
233
ADD(Query_Explain_Data);
235
std::ostringstream error;
236
error << "Verbose mask '" << mask_backup << "' incorrect from " << (mask - mask_backup) << " symbol, fix please '" << mask << "'";
237
throw Error(error.str());
241
Verbose_Callback_Fill *fill= 0;
242
if (!custom_verbose_callback_vector.empty())
244
fill= custom_verbose_callback_vector.back().get()->fill();
248
custom_verbose_callback_vector.push_back(Verbose_Callback_Pointer(new Verbose_Callback_Fill()));
249
fill= custom_verbose_callback_vector.back().get()->fill();
235
std::ostringstream error;
236
error << "Verbose mask '" << mask_backup << "' incorrect from " << (mask - mask_backup) << " symbol, fix please '" << mask << "'";
237
throw Error(error.str());
241
Verbose_Callback_Fill *fill= 0;
242
if (!custom_verbose_callback_vector.empty())
244
fill= custom_verbose_callback_vector.back().get()->fill();
248
custom_verbose_callback_vector.push_back(Verbose_Callback_Pointer(new Verbose_Callback_Fill()));
249
fill= custom_verbose_callback_vector.back().get()->fill();
258
258
std::size_t verbose(char* buffer, std::size_t length, Query const &q, Query_Result const &r)
357
372
("version", "version number")
358
373
("config", po::value<std::string>(), "config")
359
374
("verbose,v", po::value<std::string>(), verbose_help_string.c_str())
360
("dry_run", "don't run queries on mysql (don't connect)");
375
("dry_run", "don't run queries on mysql (don't connect)")
376
("split_by_connection", "split queries by connection")
377
("split_by_transaction", "split queries by transaction")
378
("worker_count", po::value<unsigned int>()
379
, "thread count [split_by_transation]");
380
//("transaction_count", po::value<unsigned int>()
381
// , "transaction in queue count [split_by_transation]");
361
382
po::options_description desc_mysql("MySQL client");
362
383
desc_mysql.add_options()
363
384
("host", po::value<std::string>(), "mysql host")
373
394
po::options_description desc("USAGE: ppb [General Options] [Input Source] [MySQ Options]");
374
395
desc.add(desc_general).add(desc_mysql).add(desc_input);
377
std::cerr << desc << std::endl;
398
std::cerr << desc << std::endl;
380
401
po::variables_map vm;
381
402
po::store(po::parse_command_line(argc, argv, desc), vm);
384
405
if (vm.count("help"))
386
std::cerr << desc << std::endl;
407
std::cerr << desc << std::endl;
389
410
if (vm.count("version"))
391
std::cerr << "version: " << PERCONA_PLAYBACK_VERSION << std::endl;
412
std::cerr << "version: " << PERCONA_PLAYBACK_VERSION << std::endl;
394
415
if (vm.count("config"))
396
std::ifstream config_file(vm["config"].as< std::string >().c_str());
397
po::store(po::parse_config_file(config_file, desc), vm);
417
std::ifstream config_file(vm["config"].as< std::string >().c_str());
418
po::store(po::parse_config_file(config_file, desc), vm);
400
421
if (vm.count("verbose"))
402
std::string verbose_mask= vm[ "verbose" ].as<std::string>();
403
set_verbose(verbose_mask.c_str());
423
std::string verbose_mask= vm[ "verbose" ].as<std::string>();
424
set_verbose(verbose_mask.c_str());
405
426
g_dry_run= vm.count("dry_run");
406
427
#define STRING(name) \
407
428
if (vm.count( #name )) \
409
std::string result= vm[ #name ].as<std::string>(); \
410
if (result.length() > g_##name .max()) \
412
std::string limitation("maximum length is "); \
413
limitation += boost::lexical_cast< std::string >( \
415
throw Too_Long_Argument( #name \
419
g_##name .set(result); \
430
std::string result= vm[ #name ].as<std::string>(); \
431
if (result.length() > g_##name .max()) \
433
std::string limitation("maximum length is "); \
434
limitation += boost::lexical_cast< std::string >( \
436
throw Too_Long_Argument( #name \
440
g_##name .set(result); \
442
#define NUMBER(name) \
443
if (vm.count( #name )) \
445
g_##name = vm[ #name ].as<unsigned int>(); \
446
if ((unsigned int)g_##name > g_##name##_max) \
448
std::ostringstream max_string; \
449
max_string << "maximum value is " << g_##name##_max; \
450
std::ostringstream result_string; \
451
result_string << g_##name ; \
452
throw Too_Long_Argument(#name , max_string.str(), result_string.str()); \
422
456
STRING(database);
424
458
STRING(password);
425
if (vm.count("port"))
427
g_port= vm["port"].as<unsigned int>();
430
std::ostringstream port_string;
431
port_string << g_port;
432
throw Too_Long_Argument("port", "maximum value is 66536", port_string.str());
460
NUMBER(worker_count);
461
//NUMBER(transaction_count);
462
if (vm.count("split_by_transaction"))
464
if(vm.count("split_by_connection"))
466
throw Error("please choost just one: "
467
"split_by_connection"
469
"split_by_transction");
471
if (g_worker_count == 0)
473
throw Error("please choose not-zero worker_count");
475
/*if (g_transaction_count == 0)
477
throw Error("please choose not-zero transaction_count");
482
if(vm.count("worker_count"))
484
throw Error("please use worker_count just for split_by_transction");
486
/*if(vm.count("transaction_count"))
488
throw Error("please use transaction_count just for split_by_transction");
436
492
STRING(slow_query_log_file);
437
493
STRING(slow_query_log_socket);