~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzle.cc

few updates and modifications to admin commands

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
 *
35
35
 **/
36
36
 
37
 
#include <config.h>
 
37
#include "config.h"
38
38
#include <libdrizzle/drizzle_client.h>
39
39
 
40
 
#include "server_detect.h"
41
 
#include "get_password.h"
 
40
#include "client/get_password.h"
42
41
 
43
 
#include <boost/date_time/posix_time/posix_time.hpp>
 
42
#if TIME_WITH_SYS_TIME
 
43
# include <sys/time.h>
 
44
# include <time.h>
 
45
#else
 
46
# if HAVE_SYS_TIME_H
 
47
#  include <sys/time.h>
 
48
# else
 
49
#  include <time.h>
 
50
# endif
 
51
#endif
44
52
 
45
53
#include <cerrno>
46
54
#include <string>
54
62
#include <stdarg.h>
55
63
#include <math.h>
56
64
#include <memory>
57
 
#include <client/linebuffer.h>
 
65
#include "client/linebuffer.h"
58
66
#include <signal.h>
59
67
#include <sys/ioctl.h>
60
68
#include <drizzled/configmake.h>
61
 
#include <drizzled/utf8/utf8.h>
 
69
#include "drizzled/utf8/utf8.h"
62
70
#include <cstdlib>
63
71
 
64
72
#if defined(HAVE_CURSES_H) && defined(HAVE_TERM_H)
152
160
#endif
153
161
#include <boost/program_options.hpp>
154
162
#include <boost/scoped_ptr.hpp>
155
 
#include <drizzled/program_options/config_file.h>
 
163
#include "drizzled/program_options/config_file.h"
156
164
 
157
165
using namespace std;
158
166
namespace po=boost::program_options;
308
316
static uint32_t select_limit;
309
317
static uint32_t max_join_size;
310
318
static uint32_t opt_connect_timeout= 0;
311
 
static ServerDetect::server_type server_type= ServerDetect::SERVER_UNKNOWN_FOUND;
312
319
std::string current_db,
313
320
  delimiter_str,  
314
321
  current_host,
318
325
  current_password,
319
326
  opt_password,
320
327
  opt_protocol;
321
 
 
322
 
static const char* get_day_name(int day_of_week)
323
 
{
324
 
  switch(day_of_week)
325
 
  {
326
 
  case 0:
327
 
    return _("Sun");
328
 
  case 1:
329
 
    return _("Mon");
330
 
  case 2:
331
 
    return _("Tue");
332
 
  case 3:
333
 
    return _("Wed");
334
 
  case 4:
335
 
    return _("Thu");
336
 
  case 5:
337
 
    return _("Fri");
338
 
  case 6:
339
 
    return _("Sat");
340
 
  }
341
 
 
342
 
  return NULL;
343
 
}
344
 
 
345
 
static const char* get_month_name(int month)
346
 
{
347
 
  switch(month)
348
 
  {
349
 
  case 0:
350
 
    return _("Jan");
351
 
  case 1:
352
 
    return _("Feb");
353
 
  case 2:
354
 
    return _("Mar");
355
 
  case 3:
356
 
    return _("Apr");
357
 
  case 4:
358
 
    return _("May");
359
 
  case 5:
360
 
    return _("Jun");
361
 
  case 6:
362
 
    return _("Jul");
363
 
  case 7:
364
 
    return _("Aug");
365
 
  case 8:
366
 
    return _("Sep");
367
 
  case 9:
368
 
    return _("Oct");
369
 
  case 10:
370
 
    return _("Nov");
371
 
  case 11:
372
 
    return _("Dec");
373
 
  }
374
 
 
375
 
  return NULL;
376
 
}
377
 
 
 
328
// TODO: Need to i18n these
 
329
static const char *day_names[]= {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
 
330
static const char *month_names[]= {"Jan","Feb","Mar","Apr","May","Jun","Jul",
 
331
                                  "Aug","Sep","Oct","Nov","Dec"};
378
332
/* @TODO: Remove this */
379
333
#define FN_REFLEN 512
380
334
 
414
368
  com_nopager(string *str, const char*), com_pager(string *str, const char*);
415
369
 
416
370
static int read_and_execute(bool interactive);
417
 
static int sql_connect(const string &host, const string &database, const string &user, const string &password);
 
371
static int sql_connect(const string &host, const string &database, const string &user, const string &password,
 
372
                       uint32_t silent);
418
373
static const char *server_version_string(drizzle_con_st *con);
419
374
static int put_info(const char *str,INFO_TYPE info,uint32_t error,
420
375
                    const char *sql_state);
430
385
static void add_int_to_prompt(int toadd);
431
386
static int get_result_width(drizzle_result_st *res);
432
387
static int get_field_disp_length(drizzle_column_st * field);
433
 
static const char * strcont(const char *str, const char *set);
 
388
static const char * strcont(register const char *str, register const char *set);
434
389
 
435
390
/* A class which contains information on the commands this program
436
391
   can understand. */
536
491
  Commands( "tee",    'T', com_tee,    1,
537
492
    N_("Set outfile [to_outfile]. Append everything into given outfile.") ),
538
493
  Commands( "use",    'u', com_use,    1,
539
 
    N_("Use another schema. Takes schema name as argument.") ),
 
494
    N_("Use another database. Takes database name as argument.") ),
540
495
  Commands( "shutdown",    'u', com_shutdown,    1,
541
496
    N_("Shutdown the instance you are connected too.") ),
542
497
  Commands( "warnings", 'W', com_warnings,  0,
1167
1122
static void print_tab_data(drizzle_result_st *result);
1168
1123
static void print_table_data_vertically(drizzle_result_st *result);
1169
1124
static void print_warnings(uint32_t error_code);
1170
 
static boost::posix_time::ptime start_timer(void);
1171
 
static void end_timer(boost::posix_time::ptime, string &buff);
1172
 
static void drizzle_end_timer(boost::posix_time::ptime, string &buff);
1173
 
static void nice_time(boost::posix_time::time_duration duration, string &buff);
 
1125
static uint32_t start_timer(void);
 
1126
static void end_timer(uint32_t start_time,char *buff);
 
1127
static void drizzle_end_timer(uint32_t start_time,char *buff);
 
1128
static void nice_time(double sec,char *buff,bool part_second);
1174
1129
extern "C" void drizzle_end(int sig);
1175
1130
extern "C" void handle_sigint(int sig);
1176
1131
#if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
1326
1281
# if defined(HAVE_LOCALE_H)
1327
1282
  setlocale(LC_ALL, "");
1328
1283
# endif
1329
 
  bindtextdomain("drizzle7", LOCALEDIR);
1330
 
  textdomain("drizzle7");
 
1284
  bindtextdomain("drizzle", LOCALEDIR);
 
1285
  textdomain("drizzle");
1331
1286
#endif
1332
1287
 
1333
 
  po::options_description commandline_options(_("Options used only in command line"));
 
1288
  po::options_description commandline_options(N_("Options used only in command line"));
1334
1289
  commandline_options.add_options()
1335
 
  ("help,?",_("Displays this help and exit."))
1336
 
  ("batch,B",_("Don't use history file. Disable interactive behavior. (Enables --silent)"))
 
1290
  ("help,?",N_("Displays this help and exit."))
 
1291
  ("batch,B",N_("Don't use history file. Disable interactive behavior. (Enables --silent)"))
1337
1292
  ("column-type-info", po::value<bool>(&column_types_flag)->default_value(false)->zero_tokens(),
1338
 
  _("Display column type information."))
 
1293
  N_("Display column type information."))
1339
1294
  ("comments,c", po::value<bool>(&preserve_comments)->default_value(false)->zero_tokens(),
1340
 
  _("Preserve comments. Send comments to the server. The default is --skip-comments (discard comments), enable with --comments"))
 
1295
  N_("Preserve comments. Send comments to the server. The default is --skip-comments (discard comments), enable with --comments"))
1341
1296
  ("vertical,E", po::value<bool>(&vertical)->default_value(false)->zero_tokens(),
1342
 
  _("Print the output of a query (rows) vertically."))
 
1297
  N_("Print the output of a query (rows) vertically."))
1343
1298
  ("force,f", po::value<bool>(&ignore_errors)->default_value(false)->zero_tokens(),
1344
 
  _("Continue even if we get an sql error."))
 
1299
  N_("Continue even if we get an sql error."))
1345
1300
  ("named-commands,G", po::value<bool>(&named_cmds)->default_value(false)->zero_tokens(),
1346
 
  _("Enable named commands. Named commands mean this program's internal commands; see drizzle> help . When enabled, the named commands can be used from any line of the query, otherwise only from the first line, before an enter."))
 
1301
  N_("Enable named commands. Named commands mean this program's internal commands; see drizzle> help . When enabled, the named commands can be used from any line of the query, otherwise only from the first line, before an enter."))
1347
1302
  ("no-beep,b", po::value<bool>(&opt_nobeep)->default_value(false)->zero_tokens(),
1348
 
  _("Turn off beep on error."))
1349
 
  ("disable-line-numbers", _("Do not write line numbers for errors."))
1350
 
  ("disable-column-names", _("Do not write column names in results."))
 
1303
  N_("Turn off beep on error."))
 
1304
  ("disable-line-numbers", N_("Do not write line numbers for errors."))
 
1305
  ("disable-column-names", N_("Do not write column names in results."))
1351
1306
  ("skip-column-names,N", 
1352
 
  _("Don't write column names in results. WARNING: -N is deprecated, use long version of this options instead."))
 
1307
  N_("Don't write column names in results. WARNING: -N is deprecated, use long version of this options instead."))
1353
1308
  ("set-variable,O", po::value<string>(),
1354
 
  _("Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value."))
 
1309
  N_("Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value."))
1355
1310
  ("table,t", po::value<bool>(&output_tables)->default_value(false)->zero_tokens(),
1356
 
  _("Output in table format.")) 
 
1311
  N_("Output in table format.")) 
1357
1312
  ("safe-updates,U", po::value<bool>(&safe_updates)->default_value(false)->zero_tokens(),
1358
 
  _("Only allow UPDATE and DELETE that uses keys."))
 
1313
  N_("Only allow UPDATE and DELETE that uses keys."))
1359
1314
  ("i-am-a-dummy,U", po::value<bool>(&safe_updates)->default_value(false)->zero_tokens(),
1360
 
  _("Synonym for option --safe-updates, -U."))
 
1315
  N_("Synonym for option --safe-updates, -U."))
1361
1316
  ("verbose,v", po::value<string>(&opt_verbose)->default_value(""),
1362
 
  _("-v vvv implies that verbose= 3, Used to specify verbose"))
1363
 
  ("version,V", _("Output version information and exit."))
 
1317
  N_("-v vvv implies that verbose= 3, Used to specify verbose"))
 
1318
  ("version,V", N_("Output version information and exit."))
1364
1319
  ("secure-auth", po::value<bool>(&opt_secure_auth)->default_value(false)->zero_tokens(),
1365
 
  _("Refuse client connecting to server if it uses old (pre-4.1.1) protocol"))
 
1320
  N_("Refuse client connecting to server if it uses old (pre-4.1.1) protocol"))
1366
1321
  ("show-warnings", po::value<bool>(&show_warnings)->default_value(false)->zero_tokens(),
1367
 
  _("Show warnings after every statement."))
 
1322
  N_("Show warnings after every statement."))
1368
1323
  ("show-progress-size", po::value<uint32_t>(&show_progress_size)->default_value(0),
1369
 
  _("Number of lines before each import progress report."))
 
1324
  N_("Number of lines before each import progress report."))
1370
1325
  ("ping", po::value<bool>(&opt_ping)->default_value(false)->zero_tokens(),
1371
 
  _("Ping the server to check if it's alive."))
 
1326
  N_("Ping the server to check if it's alive."))
1372
1327
  ("no-defaults", po::value<bool>()->default_value(false)->zero_tokens(),
1373
 
  _("Configuration file defaults are not used if no-defaults is set"))
 
1328
  N_("Configuration file defaults are not used if no-defaults is set"))
1374
1329
  ;
1375
1330
 
1376
 
  po::options_description drizzle_options(_("Options specific to the drizzle client"));
 
1331
  po::options_description drizzle_options(N_("Options specific to the drizzle client"));
1377
1332
  drizzle_options.add_options()
1378
1333
  ("disable-auto-rehash,A",
1379
 
  _("Disable automatic rehashing. One doesn't need to use 'rehash' to get table and field completion, but startup and reconnecting may take a longer time."))
 
1334
  N_("Disable automatic rehashing. One doesn't need to use 'rehash' to get table and field completion, but startup and reconnecting may take a longer time."))
1380
1335
  ("auto-vertical-output", po::value<bool>(&auto_vertical_output)->default_value(false)->zero_tokens(),
1381
 
  _("Automatically switch to vertical output mode if the result is wider than the terminal width."))
 
1336
  N_("Automatically switch to vertical output mode if the result is wider than the terminal width."))
1382
1337
  ("database,D", po::value<string>(&current_db)->default_value(""),
1383
 
  _("Database to use."))
 
1338
  N_("Database to use."))
1384
1339
  ("default-character-set",po::value<string>(),
1385
 
  _("(not used)"))
 
1340
  N_("(not used)"))
1386
1341
  ("delimiter", po::value<string>(&delimiter_str)->default_value(";"),
1387
 
  _("Delimiter to be used."))
 
1342
  N_("Delimiter to be used."))
1388
1343
  ("execute,e", po::value<string>(),
1389
 
  _("Execute command and quit. (Disables --force and history file)"))
 
1344
  N_("Execute command and quit. (Disables --force and history file)"))
1390
1345
  ("local-infile", po::value<bool>(&opt_local_infile)->default_value(false)->zero_tokens(),
1391
 
  _("Enable LOAD DATA LOCAL INFILE."))
 
1346
  N_("Enable LOAD DATA LOCAL INFILE."))
1392
1347
  ("unbuffered,n", po::value<bool>(&unbuffered)->default_value(false)->zero_tokens(),
1393
 
  _("Flush buffer after each query."))
 
1348
  N_("Flush buffer after each query."))
1394
1349
  ("sigint-ignore", po::value<bool>(&opt_sigint_ignore)->default_value(false)->zero_tokens(),
1395
 
  _("Ignore SIGINT (CTRL-C)"))
 
1350
  N_("Ignore SIGINT (CTRL-C)"))
1396
1351
  ("one-database,o", po::value<bool>(&one_database)->default_value(false)->zero_tokens(),
1397
 
  _("Only update the default database. This is useful for skipping updates to other database in the update log."))
 
1352
  N_("Only update the default database. This is useful for skipping updates to other database in the update log."))
1398
1353
  ("pager", po::value<string>(),
1399
 
  _("Pager to use to display results. If you don't supply an option the default pager is taken from your ENV variable PAGER. Valid pagers are less, more, cat [> filename], etc. See interactive help (\\h) also. This option does not work in batch mode. Disable with --disable-pager. This option is disabled by default."))
 
1354
  N_("Pager to use to display results. If you don't supply an option the default pager is taken from your ENV variable PAGER. Valid pagers are less, more, cat [> filename], etc. See interactive help (\\h) also. This option does not work in batch mode. Disable with --disable-pager. This option is disabled by default."))
1400
1355
  ("disable-pager", po::value<bool>(&opt_nopager)->default_value(false)->zero_tokens(),
1401
 
  _("Disable pager and print to stdout. See interactive help (\\h) also."))
 
1356
  N_("Disable pager and print to stdout. See interactive help (\\h) also."))
1402
1357
  ("prompt", po::value<string>(&current_prompt)->default_value(""),  
1403
 
  _("Set the drizzle prompt to this value."))
 
1358
  N_("Set the drizzle prompt to this value."))
1404
1359
  ("quick,q", po::value<bool>(&quick)->default_value(false)->zero_tokens(),
1405
 
  _("Don't cache result, print it row by row. This may slow down the server if the output is suspended. Doesn't use history file."))
 
1360
  N_("Don't cache result, print it row by row. This may slow down the server if the output is suspended. Doesn't use history file."))
1406
1361
  ("raw,r", po::value<bool>(&opt_raw_data)->default_value(false)->zero_tokens(),
1407
 
  _("Write fields without conversion. Used with --batch.")) 
1408
 
  ("disable-reconnect", _("Do not reconnect if the connection is lost."))
 
1362
  N_("Write fields without conversion. Used with --batch.")) 
 
1363
  ("disable-reconnect", N_("Do not reconnect if the connection is lost."))
1409
1364
  ("shutdown", po::value<bool>()->zero_tokens(),
1410
 
  _("Shutdown the server"))
1411
 
  ("silent,s", _("Be more silent. Print results with a tab as separator, each row on new line."))
 
1365
  N_("Shutdown the server"))
 
1366
  ("silent,s", N_("Be more silent. Print results with a tab as separator, each row on new line."))
1412
1367
  ("tee", po::value<string>(),
1413
 
  _("Append everything into outfile. See interactive help (\\h) also. Does not work in batch mode. Disable with --disable-tee. This option is disabled by default."))
 
1368
  N_("Append everything into outfile. See interactive help (\\h) also. Does not work in batch mode. Disable with --disable-tee. This option is disabled by default."))
1414
1369
  ("disable-tee", po::value<bool>()->default_value(false)->zero_tokens(), 
1415
 
  _("Disable outfile. See interactive help (\\h) also."))
 
1370
  N_("Disable outfile. See interactive help (\\h) also."))
1416
1371
  ("connect-timeout", po::value<uint32_t>(&opt_connect_timeout)->default_value(0)->notifier(&check_timeout_value),
1417
 
  _("Number of seconds before connection timeout."))
 
1372
  N_("Number of seconds before connection timeout."))
1418
1373
  ("max-input-line", po::value<uint32_t>(&opt_max_input_line)->default_value(16*1024L*1024L)->notifier(&check_max_input_line),
1419
 
  _("Max length of input line"))
 
1374
  N_("Max length of input line"))
1420
1375
  ("select-limit", po::value<uint32_t>(&select_limit)->default_value(1000L),
1421
 
  _("Automatic limit for SELECT when using --safe-updates"))
 
1376
  N_("Automatic limit for SELECT when using --safe-updates"))
1422
1377
  ("max-join-size", po::value<uint32_t>(&max_join_size)->default_value(1000000L),
1423
 
  _("Automatic limit for rows in a join when using --safe-updates"))
 
1378
  N_("Automatic limit for rows in a join when using --safe-updates"))
1424
1379
  ;
1425
1380
 
1426
 
  po::options_description client_options(_("Options specific to the client"));
 
1381
  po::options_description client_options(N_("Options specific to the client"));
1427
1382
  client_options.add_options()
1428
1383
  ("host,h", po::value<string>(&current_host)->default_value("localhost"),
1429
 
  _("Connect to host"))
 
1384
  N_("Connect to host"))
1430
1385
  ("password,P", po::value<string>(&current_password)->default_value(PASSWORD_SENTINEL),
1431
 
  _("Password to use when connecting to server. If password is not given it's asked from the tty."))
 
1386
  N_("Password to use when connecting to server. If password is not given it's asked from the tty."))
1432
1387
  ("port,p", po::value<uint32_t>()->default_value(0),
1433
 
  _("Port number to use for connection or 0 for default to, in order of preference, drizzle.cnf, $DRIZZLE_TCP_PORT, built-in default"))
1434
 
#ifdef DRIZZLE_ADMIN_TOOL
1435
 
  ("user,u", po::value<string>(&current_user)->default_value("root"),
1436
 
#else
 
1388
  N_("Port number to use for connection or 0 for default to, in order of preference, drizzle.cnf, $DRIZZLE_TCP_PORT, built-in default"))
1437
1389
  ("user,u", po::value<string>(&current_user)->default_value(""),
1438
 
#endif
1439
 
  _("User for login if not current user."))
 
1390
  N_("User for login if not current user."))
1440
1391
  ("protocol",po::value<string>(&opt_protocol)->default_value("mysql"),
1441
 
  _("The protocol of connection (mysql or drizzle)."))
 
1392
  N_("The protocol of connection (mysql or drizzle)."))
1442
1393
  ;
1443
1394
 
1444
 
  po::options_description long_options(_("Allowed Options"));
 
1395
  po::options_description long_options(N_("Allowed Options"));
1445
1396
  long_options.add(commandline_options).add(drizzle_options).add(client_options);
1446
1397
 
1447
1398
  std::string system_config_dir_drizzle(SYSCONFDIR); 
1495
1446
 
1496
1447
  po::notify(vm);
1497
1448
 
1498
 
#ifdef DRIZZLE_ADMIN_TOOL
1499
 
  default_prompt= strdup(getenv("DRIZZLE_PS1") ?
1500
 
                         getenv("DRIZZLE_PS1") :
1501
 
                         "drizzleadmin> ");
1502
 
#else
1503
1449
  default_prompt= strdup(getenv("DRIZZLE_PS1") ?
1504
1450
                         getenv("DRIZZLE_PS1") :
1505
1451
                         "drizzle> ");
1506
 
#endif
1507
1452
  if (default_prompt == NULL)
1508
1453
  {
1509
1454
    fprintf(stderr, _("Memory allocation error while constructing initial "
1510
1455
                      "prompt. Aborting.\n"));
1511
1456
    exit(ENOMEM);
1512
1457
  }
1513
 
 
1514
 
  if (current_prompt.empty())
1515
 
    current_prompt= strdup(default_prompt);
1516
 
 
 
1458
  current_prompt= strdup(default_prompt);
1517
1459
  if (current_prompt.empty())
1518
1460
  {
1519
1461
    fprintf(stderr, _("Memory allocation error while constructing initial "
1538
1480
  if (! isatty(0) || ! isatty(1))
1539
1481
  {
1540
1482
    status.setBatch(1); opt_silent=1;
 
1483
    ignore_errors=0;
1541
1484
  }
1542
1485
  else
1543
1486
    status.setAddToHistory(1);
1714
1657
  }
1715
1658
  if (vm.count("silent"))
1716
1659
  {
1717
 
    opt_silent= 2;
 
1660
    opt_silent++;
1718
1661
  }
1719
1662
  
1720
1663
  if (vm.count("help") || vm.count("version"))
1730
1673
           "This is free software,\n"
1731
1674
           "and you are welcome to modify and redistribute it "
1732
1675
           "under the GPL license\n"));
1733
 
    printf(_("Usage: drizzle [OPTIONS] [schema]\n"));
 
1676
    printf(_("Usage: drizzle [OPTIONS] [database]\n"));
1734
1677
    cout << long_options;
1735
1678
    exit(0);
1736
1679
  }
1742
1685
  }
1743
1686
 
1744
1687
  memset(&drizzle, 0, sizeof(drizzle));
1745
 
  if (sql_connect(current_host, current_db, current_user, opt_password))
 
1688
  if (sql_connect(current_host, current_db, current_user, opt_password,opt_silent))
1746
1689
  {
1747
1690
    quick= 1;          // Avoid history
1748
1691
    status.setExitStatus(1);
2584
2527
  drizzle_return_t ret;
2585
2528
  drizzle_result_st databases,tables,fields;
2586
2529
  drizzle_row_t database_row,table_row;
 
2530
  drizzle_column_st *sql_field;
2587
2531
  string tmp_str, tmp_str_lower;
2588
 
  std::string query;
2589
2532
 
2590
2533
  if (status.getBatch() || quick || current_db.empty())
2591
2534
    return;      // We don't need completion in batches
2605
2548
  /* hash Drizzle functions (to be implemented) */
2606
2549
 
2607
2550
  /* hash all database names */
2608
 
  if (drizzle_query_str(&con, &databases, "select schema_name from information_schema.schemata", &ret) != NULL)
 
2551
  if (drizzle_query_str(&con, &databases, "show databases", &ret) != NULL)
2609
2552
  {
2610
2553
    if (ret == DRIZZLE_RETURN_OK)
2611
2554
    {
2625
2568
    drizzle_result_free(&databases);
2626
2569
  }
2627
2570
 
2628
 
  query= "select table_name, column_name from information_schema.columns where table_schema='";
2629
 
  query.append(current_db);
2630
 
  query.append("' order by table_name");
2631
 
  
2632
 
  if (drizzle_query(&con, &fields, query.c_str(), query.length(),
2633
 
                    &ret) != NULL)
 
2571
  /* hash all table names */
 
2572
  if (drizzle_query_str(&con, &tables, "show tables", &ret) != NULL)
2634
2573
  {
2635
 
    if (ret == DRIZZLE_RETURN_OK &&
2636
 
        drizzle_result_buffer(&fields) == DRIZZLE_RETURN_OK)
 
2574
    if (ret != DRIZZLE_RETURN_OK)
 
2575
    {
 
2576
      drizzle_result_free(&tables);
 
2577
      return;
 
2578
    }
 
2579
 
 
2580
    if (drizzle_result_buffer(&tables) != DRIZZLE_RETURN_OK)
 
2581
      put_info(drizzle_error(&drizzle),INFO_INFO,0,0);
 
2582
    else
2637
2583
    {
2638
2584
      if (drizzle_result_row_count(&tables) > 0 && !opt_silent && write_info)
2639
2585
      {
2643
2589
                      "You can turn off this feature to get a quicker "
2644
2590
                      "startup with -A\n\n"));
2645
2591
      }
2646
 
 
2647
 
      std::string table_name;
2648
 
      while ((table_row=drizzle_row_next(&fields)))
 
2592
      while ((table_row=drizzle_row_next(&tables)))
2649
2593
      {
2650
 
        if (table_name.compare(table_row[0]) != 0)
2651
 
        {
2652
 
          tmp_str= table_row[0];
2653
 
          tmp_str_lower= lower_string(tmp_str);
2654
 
          completion_map[tmp_str_lower]= tmp_str;
2655
 
          table_name= table_row[0];
2656
 
        }
2657
2594
        tmp_str= table_row[0];
2658
 
        tmp_str.append(".");
2659
 
        tmp_str.append(table_row[1]);
2660
 
        tmp_str_lower= lower_string(tmp_str);
2661
 
        completion_map[tmp_str_lower]= tmp_str;
2662
 
 
2663
 
        tmp_str= table_row[1];
2664
 
        tmp_str_lower= lower_string(tmp_str);
2665
 
        completion_map[tmp_str_lower]= tmp_str;
2666
 
      }
2667
 
    }
2668
 
  }
2669
 
  drizzle_result_free(&fields);
 
2595
        tmp_str_lower= lower_string(tmp_str);
 
2596
        completion_map[tmp_str_lower]= tmp_str;
 
2597
      }
 
2598
    }
 
2599
  }
 
2600
  else
 
2601
    return;
 
2602
 
 
2603
  /* hash all field names, both with the table prefix and without it */
 
2604
  if (drizzle_result_row_count(&tables) == 0)
 
2605
  {
 
2606
    drizzle_result_free(&tables);
 
2607
    return;
 
2608
  }
 
2609
 
 
2610
  drizzle_row_seek(&tables, 0);
 
2611
 
 
2612
  while ((table_row=drizzle_row_next(&tables)))
 
2613
  {
 
2614
    string query;
 
2615
 
 
2616
    query.append("show fields in `");
 
2617
    query.append(table_row[0]);
 
2618
    query.append("`");
 
2619
    
 
2620
    if (drizzle_query(&con, &fields, query.c_str(), query.length(),
 
2621
                      &ret) != NULL)
 
2622
    {
 
2623
      if (ret == DRIZZLE_RETURN_OK &&
 
2624
          drizzle_result_buffer(&fields) == DRIZZLE_RETURN_OK)
 
2625
      {
 
2626
        while ((sql_field=drizzle_column_next(&fields)))
 
2627
        {
 
2628
          tmp_str=table_row[0];
 
2629
          tmp_str.append(".");
 
2630
          tmp_str.append(drizzle_column_name(sql_field));
 
2631
          tmp_str_lower= lower_string(tmp_str);
 
2632
          completion_map[tmp_str_lower]= tmp_str;
 
2633
 
 
2634
          tmp_str=drizzle_column_name(sql_field);
 
2635
          tmp_str_lower= lower_string(tmp_str);
 
2636
          completion_map[tmp_str_lower]= tmp_str;
 
2637
        }
 
2638
      }
 
2639
      drizzle_result_free(&fields);
 
2640
    }
 
2641
  }
 
2642
  drizzle_result_free(&tables);
2670
2643
  completion_iter= completion_map.begin();
2671
2644
}
2672
2645
 
2762
2735
static int
2763
2736
com_help(string *buffer, const char *)
2764
2737
{
2765
 
  int i, j;
 
2738
  register int i, j;
2766
2739
  char buff[32], *end;
2767
2740
  std::vector<char> output_buff;
2768
2741
  output_buff.resize(512);
2811
2784
com_go(string *buffer, const char *)
2812
2785
{
2813
2786
  char          buff[200]; /* about 110 chars used so far */
 
2787
  char          time_buff[52+3+1]; /* time max + space&parens + NUL */
2814
2788
  drizzle_result_st result;
2815
2789
  drizzle_return_t ret;
2816
 
  uint32_t      warnings= 0;
2817
 
  boost::posix_time::ptime timer;
 
2790
  uint32_t      timer, warnings= 0;
2818
2791
  uint32_t      error= 0;
2819
2792
  uint32_t      error_code= 0;
2820
2793
  int           err= 0;
2883
2856
        goto end;
2884
2857
    }
2885
2858
 
2886
 
    string time_buff("");
2887
2859
    if (verbose >= 3 || !opt_silent)
2888
2860
      drizzle_end_timer(timer,time_buff);
 
2861
    else
 
2862
      time_buff[0]= '\0';
2889
2863
 
2890
2864
    /* Every branch must truncate  buff . */
2891
2865
    if (drizzle_result_column_count(&result) > 0)
2936
2910
      if (warnings != 1)
2937
2911
        *pos++= 's';
2938
2912
    }
2939
 
    strcpy(pos, time_buff.c_str());
 
2913
    strcpy(pos, time_buff);
2940
2914
    put_info(buff,INFO_RESULT,0,0);
2941
2915
    if (strcmp(drizzle_result_info(&result), ""))
2942
2916
      put_info(drizzle_result_info(&result),INFO_RESULT,0,0);
3102
3076
  {
3103
3077
    tee_fprintf(PAGER, _("Field %3u:  `%s`\n"
3104
3078
                "Catalog:    `%s`\n"
3105
 
                "Schema:     `%s`\n"
 
3079
                "Database:   `%s`\n"
3106
3080
                "Table:      `%s`\n"
3107
3081
                "Org_table:  `%s`\n"
3108
3082
                "Type:       UTF-8\n"
3130
3104
  drizzle_return_t ret;
3131
3105
  drizzle_column_st *field;
3132
3106
  std::vector<bool> num_flag;
3133
 
  std::vector<bool> boolean_flag;
3134
 
  std::vector<bool> ansi_boolean_flag;
3135
3107
  string separator;
3136
3108
 
3137
3109
  separator.reserve(256);
3138
3110
 
3139
3111
  num_flag.resize(drizzle_result_column_count(result));
3140
 
  boolean_flag.resize(drizzle_result_column_count(result));
3141
 
  ansi_boolean_flag.resize(drizzle_result_column_count(result));
3142
3112
  if (column_types_flag)
3143
3113
  {
3144
3114
    print_field_types(result);
3181
3151
      // Room for "NULL"
3182
3152
      length=4;
3183
3153
    }
3184
 
    if ((length < 5) and 
3185
 
      (server_type == ServerDetect::SERVER_DRIZZLE_FOUND) and
3186
 
      (drizzle_column_type(field) == DRIZZLE_COLUMN_TYPE_TINY) and
3187
 
      (drizzle_column_type(field) & DRIZZLE_COLUMN_FLAGS_UNSIGNED))
3188
 
    {
3189
 
      // Room for "FALSE"
3190
 
      length= 5;
3191
 
    }
3192
3154
    drizzle_column_set_max_size(field, length);
3193
3155
 
3194
3156
    for (x=0; x< (length+2); x++)
3212
3174
                  drizzle_column_name(field));
3213
3175
      num_flag[off]= ((drizzle_column_type(field) <= DRIZZLE_COLUMN_TYPE_LONGLONG) ||
3214
3176
                      (drizzle_column_type(field) == DRIZZLE_COLUMN_TYPE_NEWDECIMAL));
3215
 
      if ((server_type == ServerDetect::SERVER_DRIZZLE_FOUND) and
3216
 
        (drizzle_column_type(field) == DRIZZLE_COLUMN_TYPE_TINY))
3217
 
      {
3218
 
        if ((drizzle_column_flags(field) & DRIZZLE_COLUMN_FLAGS_UNSIGNED))
3219
 
        {
3220
 
          ansi_boolean_flag[off]= true;
3221
 
        }
3222
 
        else
3223
 
        {
3224
 
          ansi_boolean_flag[off]= false;
3225
 
        }
3226
 
        boolean_flag[off]= true;
3227
 
        num_flag[off]= false;
3228
 
      }
3229
 
      else
3230
 
      {
3231
 
        boolean_flag[off]= false;
3232
 
      }
3233
3177
    }
3234
3178
    (void) tee_fputs("\n", PAGER);
3235
3179
    tee_puts((char*) separator.c_str(), PAGER);
3268
3212
        buffer= "NULL";
3269
3213
        data_length= 4;
3270
3214
      }
3271
 
      else if (boolean_flag[off])
3272
 
      {
3273
 
        if (strncmp(cur[off],"1", 1) == 0)
3274
 
        {
3275
 
          if (ansi_boolean_flag[off])
3276
 
          {
3277
 
            buffer= "YES";
3278
 
            data_length= 3;
3279
 
          }
3280
 
          else
3281
 
          {
3282
 
            buffer= "TRUE";
3283
 
            data_length= 4;
3284
 
          }
3285
 
        }
3286
 
        else
3287
 
        {
3288
 
          if (ansi_boolean_flag[off])
3289
 
          {
3290
 
            buffer= "NO";
3291
 
            data_length= 2;
3292
 
          }
3293
 
          else
3294
 
          {
3295
 
            buffer= "FALSE";
3296
 
            data_length= 5;
3297
 
          }
3298
 
        }
3299
 
      }
3300
3215
      else
3301
3216
      {
3302
3217
        buffer= cur[off];
3570
3485
  drizzle_return_t ret;
3571
3486
  drizzle_column_st *field;
3572
3487
  size_t *lengths;
3573
 
  std::vector<bool> boolean_flag;
3574
 
  std::vector<bool> ansi_boolean_flag;
3575
 
 
3576
 
  boolean_flag.resize(drizzle_result_column_count(result));
3577
 
  ansi_boolean_flag.resize(drizzle_result_column_count(result));
3578
 
 
3579
 
  int first=0;
3580
 
  for (uint32_t off= 0; (field = drizzle_column_next(result)); off++)
 
3488
 
 
3489
  if (opt_silent < 2 && column_names)
3581
3490
  {
3582
 
    if (opt_silent < 2 && column_names)
 
3491
    int first=0;
 
3492
    while ((field = drizzle_column_next(result)))
3583
3493
    {
3584
3494
      if (first++)
3585
3495
        (void) tee_fputs("\t", PAGER);
3586
3496
      (void) tee_fputs(drizzle_column_name(field), PAGER);
3587
3497
    }
3588
 
    if ((server_type == ServerDetect::SERVER_DRIZZLE_FOUND) and
3589
 
      (drizzle_column_type(field) == DRIZZLE_COLUMN_TYPE_TINY))
3590
 
    {
3591
 
      if ((drizzle_column_flags(field) & DRIZZLE_COLUMN_FLAGS_UNSIGNED))
3592
 
      {
3593
 
        ansi_boolean_flag[off]= true;
3594
 
      }
3595
 
      else
3596
 
      {
3597
 
        ansi_boolean_flag[off]= false;
3598
 
      }
3599
 
      boolean_flag[off]= true;
3600
 
    }
3601
 
    else
3602
 
    {
3603
 
      boolean_flag[off]= false;
3604
 
    }
3605
 
  }
3606
 
  if (opt_silent < 2 && column_names)
3607
 
  {
3608
3498
    (void) tee_fputs("\n", PAGER);
3609
3499
  }
3610
3500
  while (1)
3625
3515
      break;
3626
3516
 
3627
3517
    lengths= drizzle_row_field_sizes(result);
3628
 
    drizzle_column_seek(result, 0);
3629
 
    for (uint32_t off=0 ; off < drizzle_result_column_count(result); off++)
 
3518
    safe_put_field(cur[0],lengths[0]);
 
3519
    for (uint32_t off=1 ; off < drizzle_result_column_count(result); off++)
3630
3520
    {
3631
 
      if (off != 0)
3632
 
        (void) tee_fputs("\t", PAGER);
3633
 
      if (boolean_flag[off])
3634
 
      {
3635
 
        if (strncmp(cur[off],"1", 1) == 0)
3636
 
        {
3637
 
          if (ansi_boolean_flag[off])
3638
 
          {
3639
 
            safe_put_field("YES", 3);
3640
 
          }
3641
 
          else
3642
 
          {
3643
 
            safe_put_field("TRUE", 4);
3644
 
          }
3645
 
        }
3646
 
        else
3647
 
        {
3648
 
          if (ansi_boolean_flag[off])
3649
 
          {
3650
 
            safe_put_field("NO", 2);
3651
 
          }
3652
 
          else
3653
 
          {
3654
 
            safe_put_field("FALSE", 5);
3655
 
          }
3656
 
        }
3657
 
      }
3658
 
      else
3659
 
      {
3660
 
        safe_put_field(cur[off], lengths[off]);
3661
 
      }
 
3521
      (void) tee_fputs("\t", PAGER);
 
3522
      safe_put_field(cur[off], lengths[off]);
3662
3523
    }
3663
3524
    (void) tee_fputs("\n", PAGER);
3664
3525
    if (quick)
3854
3715
  }
3855
3716
  else
3856
3717
    opt_rehash= 0;
3857
 
  error=sql_connect(current_host, current_db, current_user, opt_password);
 
3718
  error=sql_connect(current_host, current_db, current_user, opt_password,0);
3858
3719
  opt_rehash= save_rehash;
3859
3720
 
3860
3721
  if (connected)
3861
3722
  {
3862
3723
    sprintf(buff, _("Connection id:    %u"), drizzle_con_thread_id(&con));
3863
3724
    put_info(buff,INFO_INFO,0,0);
3864
 
    sprintf(buff, _("Current schema: %.128s\n"),
 
3725
    sprintf(buff, _("Current database: %.128s\n"),
3865
3726
            !current_db.empty() ? current_db.c_str() : _("*** NONE ***"));
3866
3727
    put_info(buff,INFO_INFO,0,0);
3867
3728
  }
3974
3835
  tmp= get_arg(buff, 0);
3975
3836
  if (!tmp || !*tmp)
3976
3837
  {
3977
 
    put_info(_("USE must be followed by a schema name"), INFO_ERROR, 0, 0);
 
3838
    put_info(_("USE must be followed by a database name"), INFO_ERROR, 0, 0);
3978
3839
    return 0;
3979
3840
  }
3980
3841
  /*
4042
3903
      build_completion_hash(opt_rehash, 1);
4043
3904
  }
4044
3905
 
4045
 
  put_info(_("Schema changed"),INFO_INFO, 0, 0);
 
3906
  put_info(_("Database changed"),INFO_INFO, 0, 0);
4046
3907
  return 0;
4047
3908
}
4048
3909
 
4163
4024
 
4164
4025
 
4165
4026
static int
4166
 
sql_connect(const string &host, const string &database, const string &user, const string &password)
 
4027
sql_connect(const string &host, const string &database, const string &user, const string &password,
 
4028
                 uint32_t silent)
4167
4029
{
4168
4030
  drizzle_return_t ret;
4169
4031
  if (connected)
4173
4035
    drizzle_free(&drizzle);
4174
4036
  }
4175
4037
  drizzle_create(&drizzle);
4176
 
 
4177
 
#ifdef DRIZZLE_ADMIN_TOOL
4178
 
  drizzle_con_options_t options= (drizzle_con_options_t) (DRIZZLE_CON_ADMIN | (use_drizzle_protocol ? DRIZZLE_CON_EXPERIMENTAL : DRIZZLE_CON_MYSQL));
4179
 
#else
4180
 
  drizzle_con_options_t options= (drizzle_con_options_t) (use_drizzle_protocol ? DRIZZLE_CON_EXPERIMENTAL : DRIZZLE_CON_MYSQL);
4181
 
#endif
4182
 
 
4183
4038
  if (drizzle_con_add_tcp(&drizzle, &con, (char *)host.c_str(),
4184
4039
    opt_drizzle_port, (char *)user.c_str(),
4185
4040
    (char *)password.c_str(), (char *)database.c_str(),
4186
 
    options) == NULL)
 
4041
    use_drizzle_protocol ? DRIZZLE_CON_EXPERIMENTAL : DRIZZLE_CON_MYSQL) == NULL)
4187
4042
  {
4188
4043
    (void) put_error(&con, NULL);
4189
4044
    (void) fflush(stdout);
4212
4067
*/
4213
4068
  if ((ret= drizzle_con_connect(&con)) != DRIZZLE_RETURN_OK)
4214
4069
  {
4215
 
 
4216
 
    if (opt_silent < 2)
 
4070
    if (!silent || (ret != DRIZZLE_RETURN_GETADDRINFO &&
 
4071
                    ret != DRIZZLE_RETURN_COULD_NOT_CONNECT))
4217
4072
    {
4218
4073
      (void) put_error(&con, NULL);
4219
4074
      (void) fflush(stdout);
4223
4078
  }
4224
4079
  connected=1;
4225
4080
 
4226
 
  ServerDetect server_detect(&con);
4227
 
  server_type= server_detect.getServerType();
4228
 
 
4229
4081
  build_completion_hash(opt_rehash, 1);
4230
4082
  return 0;
4231
4083
}
4261
4113
      drizzle_row_t cur=drizzle_row_next(&result);
4262
4114
      if (cur)
4263
4115
      {
4264
 
        tee_fprintf(stdout, _("Current schema:\t%s\n"), cur[0] ? cur[0] : "");
 
4116
        tee_fprintf(stdout, _("Current database:\t%s\n"), cur[0] ? cur[0] : "");
4265
4117
        tee_fprintf(stdout, _("Current user:\t\t%s\n"), cur[1]);
4266
4118
      }
4267
4119
      drizzle_result_free(&result);
4280
4132
  if (skip_updates)
4281
4133
  {
4282
4134
    vidattr(A_BOLD);
4283
 
    tee_fprintf(stdout, _("\nAll updates ignored to this schema\n"));
 
4135
    tee_fprintf(stdout, _("\nAll updates ignored to this database\n"));
4284
4136
    vidattr(A_NORMAL);
4285
4137
  }
4286
4138
  tee_fprintf(stdout, _("Current pager:\t\t%s\n"), pager.c_str());
4506
4358
}
4507
4359
 
4508
4360
#include <sys/times.h>
 
4361
#ifdef _SC_CLK_TCK        // For mit-pthreads
 
4362
#undef CLOCKS_PER_SEC
 
4363
#define CLOCKS_PER_SEC (sysconf(_SC_CLK_TCK))
 
4364
#endif
4509
4365
 
4510
 
static boost::posix_time::ptime start_timer(void)
 
4366
static uint32_t start_timer(void)
4511
4367
{
4512
 
  return boost::posix_time::microsec_clock::universal_time();
 
4368
  struct tms tms_tmp;
 
4369
  return times(&tms_tmp);
4513
4370
}
4514
4371
 
4515
 
static void nice_time(boost::posix_time::time_duration duration, string &buff)
 
4372
 
 
4373
/**
 
4374
   Write as many as 52+1 bytes to buff, in the form of a legible
 
4375
   duration of time.
 
4376
 
 
4377
   len("4294967296 days, 23 hours, 59 minutes, 60.00 seconds")  ->  52
 
4378
*/
 
4379
static void nice_time(double sec,char *buff,bool part_second)
4516
4380
{
 
4381
  uint32_t tmp;
4517
4382
  ostringstream tmp_buff_str;
4518
4383
 
4519
 
  if (duration.hours() > 0)
4520
 
  {
4521
 
    tmp_buff_str << duration.hours();
4522
 
    if (duration.hours() > 1)
 
4384
  if (sec >= 3600.0*24)
 
4385
  {
 
4386
    tmp=(uint32_t) floor(sec/(3600.0*24));
 
4387
    sec-= 3600.0*24*tmp;
 
4388
    tmp_buff_str << tmp;
 
4389
 
 
4390
    if (tmp > 1)
 
4391
      tmp_buff_str << " days ";
 
4392
    else
 
4393
      tmp_buff_str << " day ";
 
4394
 
 
4395
  }
 
4396
  if (sec >= 3600.0)
 
4397
  {
 
4398
    tmp=(uint32_t) floor(sec/3600.0);
 
4399
    sec-=3600.0*tmp;
 
4400
    tmp_buff_str << tmp;
 
4401
 
 
4402
    if (tmp > 1)
4523
4403
      tmp_buff_str << _(" hours ");
4524
4404
    else
4525
4405
      tmp_buff_str << _(" hour ");
4526
4406
  }
4527
 
  if (duration.hours() > 0 || duration.minutes() > 0)
 
4407
  if (sec >= 60.0)
4528
4408
  {
4529
 
    tmp_buff_str << duration.minutes() << _(" min ");
 
4409
    tmp=(uint32_t) floor(sec/60.0);
 
4410
    sec-=60.0*tmp;
 
4411
    tmp_buff_str << tmp << _(" min ");
4530
4412
  }
4531
 
 
4532
 
  tmp_buff_str.precision(duration.num_fractional_digits());
4533
 
 
4534
 
  double seconds= duration.fractional_seconds();
4535
 
 
4536
 
  seconds/= pow(10.0,duration.num_fractional_digits());
4537
 
 
4538
 
  seconds+= duration.seconds();
4539
 
  tmp_buff_str << seconds << _(" sec");
4540
 
 
4541
 
  buff.append(tmp_buff_str.str());
4542
 
}
4543
 
 
4544
 
static void end_timer(boost::posix_time::ptime start_time, string &buff)
4545
 
{
4546
 
  boost::posix_time::ptime end_time= start_timer();
4547
 
  boost::posix_time::time_period duration(start_time, end_time);
4548
 
 
4549
 
  nice_time(duration.length(), buff);
4550
 
}
4551
 
 
4552
 
 
4553
 
static void drizzle_end_timer(boost::posix_time::ptime start_time, string &buff)
4554
 
{
4555
 
  buff.append(" (");
4556
 
  end_timer(start_time,buff);
4557
 
  buff.append(")");
 
4413
  if (part_second)
 
4414
    tmp_buff_str.precision(2);
 
4415
  else
 
4416
    tmp_buff_str.precision(0);
 
4417
  tmp_buff_str << sec << _(" sec");
 
4418
  strcpy(buff, tmp_buff_str.str().c_str());
 
4419
}
 
4420
 
 
4421
 
 
4422
static void end_timer(uint32_t start_time,char *buff)
 
4423
{
 
4424
  nice_time((double) (start_timer() - start_time) /
 
4425
            CLOCKS_PER_SEC,buff,1);
 
4426
}
 
4427
 
 
4428
 
 
4429
static void drizzle_end_timer(uint32_t start_time,char *buff)
 
4430
{
 
4431
  buff[0]=' ';
 
4432
  buff[1]='(';
 
4433
  end_timer(start_time,buff+2);
 
4434
  strcpy(strchr(buff, '\0'),")");
4558
4435
}
4559
4436
 
4560
4437
static const char * construct_prompt()
4693
4570
        add_int_to_prompt(t->tm_sec);
4694
4571
        break;
4695
4572
      case 'w':
4696
 
        processed_prompt->append(get_day_name(t->tm_wday));
 
4573
        processed_prompt->append(day_names[t->tm_wday]);
4697
4574
        break;
4698
4575
      case 'P':
4699
4576
        processed_prompt->append(t->tm_hour < 12 ? "am" : "pm");
4702
4579
        add_int_to_prompt(t->tm_mon+1);
4703
4580
        break;
4704
4581
      case 'O':
4705
 
        processed_prompt->append(get_month_name(t->tm_mon));
 
4582
        processed_prompt->append(month_names[t->tm_mon]);
4706
4583
        break;
4707
4584
      case '\'':
4708
4585
        processed_prompt->append("'");
4779
4656
    if there isn't anything found.
4780
4657
*/
4781
4658
 
4782
 
static const char * strcont(const char *str, const char *set)
 
4659
static const char * strcont(register const char *str, register const char *set)
4783
4660
{
4784
 
  const char * start = (const char *) set;
 
4661
  register const char * start = (const char *) set;
4785
4662
 
4786
4663
  while (*str)
4787
4664
  {