~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzle.cc

edit

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
 
430
384
static void add_int_to_prompt(int toadd);
431
385
static int get_result_width(drizzle_result_st *res);
432
386
static int get_field_disp_length(drizzle_column_st * field);
433
 
static const char * strcont(const char *str, const char *set);
 
387
static const char * strcont(register const char *str, register const char *set);
434
388
 
435
389
/* A class which contains information on the commands this program
436
390
   can understand. */
1167
1121
static void print_tab_data(drizzle_result_st *result);
1168
1122
static void print_table_data_vertically(drizzle_result_st *result);
1169
1123
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);
 
1124
static uint32_t start_timer(void);
 
1125
static void end_timer(uint32_t start_time,char *buff);
 
1126
static void drizzle_end_timer(uint32_t start_time,char *buff);
 
1127
static void nice_time(double sec,char *buff,bool part_second);
1174
1128
extern "C" void drizzle_end(int sig);
1175
1129
extern "C" void handle_sigint(int sig);
1176
1130
#if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
1510
1464
                      "prompt. Aborting.\n"));
1511
1465
    exit(ENOMEM);
1512
1466
  }
1513
 
 
1514
 
  if (current_prompt.empty())
1515
 
    current_prompt= strdup(default_prompt);
1516
 
 
 
1467
  current_prompt= strdup(default_prompt);
1517
1468
  if (current_prompt.empty())
1518
1469
  {
1519
1470
    fprintf(stderr, _("Memory allocation error while constructing initial "
2762
2713
static int
2763
2714
com_help(string *buffer, const char *)
2764
2715
{
2765
 
  int i, j;
 
2716
  register int i, j;
2766
2717
  char buff[32], *end;
2767
2718
  std::vector<char> output_buff;
2768
2719
  output_buff.resize(512);
2811
2762
com_go(string *buffer, const char *)
2812
2763
{
2813
2764
  char          buff[200]; /* about 110 chars used so far */
 
2765
  char          time_buff[52+3+1]; /* time max + space&parens + NUL */
2814
2766
  drizzle_result_st result;
2815
2767
  drizzle_return_t ret;
2816
 
  uint32_t      warnings= 0;
2817
 
  boost::posix_time::ptime timer;
 
2768
  uint32_t      timer, warnings= 0;
2818
2769
  uint32_t      error= 0;
2819
2770
  uint32_t      error_code= 0;
2820
2771
  int           err= 0;
2883
2834
        goto end;
2884
2835
    }
2885
2836
 
2886
 
    string time_buff("");
2887
2837
    if (verbose >= 3 || !opt_silent)
2888
2838
      drizzle_end_timer(timer,time_buff);
 
2839
    else
 
2840
      time_buff[0]= '\0';
2889
2841
 
2890
2842
    /* Every branch must truncate  buff . */
2891
2843
    if (drizzle_result_column_count(&result) > 0)
2936
2888
      if (warnings != 1)
2937
2889
        *pos++= 's';
2938
2890
    }
2939
 
    strcpy(pos, time_buff.c_str());
 
2891
    strcpy(pos, time_buff);
2940
2892
    put_info(buff,INFO_RESULT,0,0);
2941
2893
    if (strcmp(drizzle_result_info(&result), ""))
2942
2894
      put_info(drizzle_result_info(&result),INFO_RESULT,0,0);
3130
3082
  drizzle_return_t ret;
3131
3083
  drizzle_column_st *field;
3132
3084
  std::vector<bool> num_flag;
3133
 
  std::vector<bool> boolean_flag;
3134
 
  std::vector<bool> ansi_boolean_flag;
3135
3085
  string separator;
3136
3086
 
3137
3087
  separator.reserve(256);
3138
3088
 
3139
3089
  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
3090
  if (column_types_flag)
3143
3091
  {
3144
3092
    print_field_types(result);
3181
3129
      // Room for "NULL"
3182
3130
      length=4;
3183
3131
    }
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
3132
    drizzle_column_set_max_size(field, length);
3193
3133
 
3194
3134
    for (x=0; x< (length+2); x++)
3212
3152
                  drizzle_column_name(field));
3213
3153
      num_flag[off]= ((drizzle_column_type(field) <= DRIZZLE_COLUMN_TYPE_LONGLONG) ||
3214
3154
                      (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
3155
    }
3234
3156
    (void) tee_fputs("\n", PAGER);
3235
3157
    tee_puts((char*) separator.c_str(), PAGER);
3268
3190
        buffer= "NULL";
3269
3191
        data_length= 4;
3270
3192
      }
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
3193
      else
3301
3194
      {
3302
3195
        buffer= cur[off];
3570
3463
  drizzle_return_t ret;
3571
3464
  drizzle_column_st *field;
3572
3465
  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++)
 
3466
 
 
3467
  if (opt_silent < 2 && column_names)
3581
3468
  {
3582
 
    if (opt_silent < 2 && column_names)
 
3469
    int first=0;
 
3470
    while ((field = drizzle_column_next(result)))
3583
3471
    {
3584
3472
      if (first++)
3585
3473
        (void) tee_fputs("\t", PAGER);
3586
3474
      (void) tee_fputs(drizzle_column_name(field), PAGER);
3587
3475
    }
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
3476
    (void) tee_fputs("\n", PAGER);
3609
3477
  }
3610
3478
  while (1)
3625
3493
      break;
3626
3494
 
3627
3495
    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++)
 
3496
    safe_put_field(cur[0],lengths[0]);
 
3497
    for (uint32_t off=1 ; off < drizzle_result_column_count(result); off++)
3630
3498
    {
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
 
      }
 
3499
      (void) tee_fputs("\t", PAGER);
 
3500
      safe_put_field(cur[off], lengths[off]);
3662
3501
    }
3663
3502
    (void) tee_fputs("\n", PAGER);
3664
3503
    if (quick)
4223
4062
  }
4224
4063
  connected=1;
4225
4064
 
4226
 
  ServerDetect server_detect(&con);
4227
 
  server_type= server_detect.getServerType();
4228
 
 
4229
4065
  build_completion_hash(opt_rehash, 1);
4230
4066
  return 0;
4231
4067
}
4506
4342
}
4507
4343
 
4508
4344
#include <sys/times.h>
 
4345
#ifdef _SC_CLK_TCK        // For mit-pthreads
 
4346
#undef CLOCKS_PER_SEC
 
4347
#define CLOCKS_PER_SEC (sysconf(_SC_CLK_TCK))
 
4348
#endif
4509
4349
 
4510
 
static boost::posix_time::ptime start_timer(void)
 
4350
static uint32_t start_timer(void)
4511
4351
{
4512
 
  return boost::posix_time::microsec_clock::universal_time();
 
4352
  struct tms tms_tmp;
 
4353
  return times(&tms_tmp);
4513
4354
}
4514
4355
 
4515
 
static void nice_time(boost::posix_time::time_duration duration, string &buff)
 
4356
 
 
4357
/**
 
4358
   Write as many as 52+1 bytes to buff, in the form of a legible
 
4359
   duration of time.
 
4360
 
 
4361
   len("4294967296 days, 23 hours, 59 minutes, 60.00 seconds")  ->  52
 
4362
*/
 
4363
static void nice_time(double sec,char *buff,bool part_second)
4516
4364
{
 
4365
  uint32_t tmp;
4517
4366
  ostringstream tmp_buff_str;
4518
4367
 
4519
 
  if (duration.hours() > 0)
4520
 
  {
4521
 
    tmp_buff_str << duration.hours();
4522
 
    if (duration.hours() > 1)
 
4368
  if (sec >= 3600.0*24)
 
4369
  {
 
4370
    tmp=(uint32_t) floor(sec/(3600.0*24));
 
4371
    sec-= 3600.0*24*tmp;
 
4372
    tmp_buff_str << tmp;
 
4373
 
 
4374
    if (tmp > 1)
 
4375
      tmp_buff_str << " days ";
 
4376
    else
 
4377
      tmp_buff_str << " day ";
 
4378
 
 
4379
  }
 
4380
  if (sec >= 3600.0)
 
4381
  {
 
4382
    tmp=(uint32_t) floor(sec/3600.0);
 
4383
    sec-=3600.0*tmp;
 
4384
    tmp_buff_str << tmp;
 
4385
 
 
4386
    if (tmp > 1)
4523
4387
      tmp_buff_str << _(" hours ");
4524
4388
    else
4525
4389
      tmp_buff_str << _(" hour ");
4526
4390
  }
4527
 
  if (duration.hours() > 0 || duration.minutes() > 0)
 
4391
  if (sec >= 60.0)
4528
4392
  {
4529
 
    tmp_buff_str << duration.minutes() << _(" min ");
 
4393
    tmp=(uint32_t) floor(sec/60.0);
 
4394
    sec-=60.0*tmp;
 
4395
    tmp_buff_str << tmp << _(" min ");
4530
4396
  }
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(")");
 
4397
  if (part_second)
 
4398
    tmp_buff_str.precision(2);
 
4399
  else
 
4400
    tmp_buff_str.precision(0);
 
4401
  tmp_buff_str << sec << _(" sec");
 
4402
  strcpy(buff, tmp_buff_str.str().c_str());
 
4403
}
 
4404
 
 
4405
 
 
4406
static void end_timer(uint32_t start_time,char *buff)
 
4407
{
 
4408
  nice_time((double) (start_timer() - start_time) /
 
4409
            CLOCKS_PER_SEC,buff,1);
 
4410
}
 
4411
 
 
4412
 
 
4413
static void drizzle_end_timer(uint32_t start_time,char *buff)
 
4414
{
 
4415
  buff[0]=' ';
 
4416
  buff[1]='(';
 
4417
  end_timer(start_time,buff+2);
 
4418
  strcpy(strchr(buff, '\0'),")");
4558
4419
}
4559
4420
 
4560
4421
static const char * construct_prompt()
4693
4554
        add_int_to_prompt(t->tm_sec);
4694
4555
        break;
4695
4556
      case 'w':
4696
 
        processed_prompt->append(get_day_name(t->tm_wday));
 
4557
        processed_prompt->append(day_names[t->tm_wday]);
4697
4558
        break;
4698
4559
      case 'P':
4699
4560
        processed_prompt->append(t->tm_hour < 12 ? "am" : "pm");
4702
4563
        add_int_to_prompt(t->tm_mon+1);
4703
4564
        break;
4704
4565
      case 'O':
4705
 
        processed_prompt->append(get_month_name(t->tm_mon));
 
4566
        processed_prompt->append(month_names[t->tm_mon]);
4706
4567
        break;
4707
4568
      case '\'':
4708
4569
        processed_prompt->append("'");
4779
4640
    if there isn't anything found.
4780
4641
*/
4781
4642
 
4782
 
static const char * strcont(const char *str, const char *set)
 
4643
static const char * strcont(register const char *str, register const char *set)
4783
4644
{
4784
 
  const char * start = (const char *) set;
 
4645
  register const char * start = (const char *) set;
4785
4646
 
4786
4647
  while (*str)
4787
4648
  {