~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzle.cc

  • Committer: Brian Aker
  • Date: 2010-05-28 01:36:09 UTC
  • Revision ID: brian@gaz-20100528013609-lvsd6znyufrpmddk
Rollup patch for hiding tableshare.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
 
 *  Copyright (C) 2010 Vijay Samuel
5
4
 *  Copyright (C) 2008 MySQL
6
5
 *
7
6
 *  This program is free software; you can redistribute it and/or modify
34
33
 *
35
34
 **/
36
35
 
37
 
#include <config.h>
38
 
#include <libdrizzle/drizzle_client.h>
39
 
 
40
 
#include "server_detect.h"
41
 
#include "get_password.h"
42
 
 
43
 
#include <boost/date_time/posix_time/posix_time.hpp>
44
 
 
45
 
#include <cerrno>
 
36
#include "client_priv.h"
46
37
#include <string>
47
38
#include <drizzled/gettext.h>
48
39
#include <iostream>
49
 
#include <fstream>
50
40
#include <map>
51
41
#include <algorithm>
52
42
#include <limits.h>
53
43
#include <cassert>
 
44
#include "drizzled/charset_info.h"
54
45
#include <stdarg.h>
55
46
#include <math.h>
56
 
#include <memory>
57
 
#include <client/linebuffer.h>
 
47
#include "client/linebuffer.h"
58
48
#include <signal.h>
59
49
#include <sys/ioctl.h>
60
50
#include <drizzled/configmake.h>
61
 
#include <drizzled/utf8/utf8.h>
62
 
#include <cstdlib>
 
51
#include "drizzled/charset.h"
63
52
 
64
53
#if defined(HAVE_CURSES_H) && defined(HAVE_TERM_H)
65
54
#include <curses.h>
150
139
#undef vidattr
151
140
#define vidattr(A) {}      // Can't get this to work
152
141
#endif
153
 
#include <boost/program_options.hpp>
154
 
#include <boost/scoped_ptr.hpp>
155
 
#include <drizzled/program_options/config_file.h>
156
142
 
 
143
using namespace drizzled;
157
144
using namespace std;
158
 
namespace po=boost::program_options;
159
 
namespace dpo=drizzled::program_options;
160
145
 
 
146
const string VER("14.14");
161
147
/* Don't try to make a nice table if the data is too big */
162
148
const uint32_t MAX_COLUMN_LENGTH= 1024;
163
149
 
165
151
const int MAX_SERVER_VERSION_LENGTH= 128;
166
152
 
167
153
#define PROMPT_CHAR '\\'
 
154
#define DEFAULT_DELIMITER ";"
168
155
 
169
156
class Status
170
157
{
172
159
 
173
160
  Status(int in_exit_status, 
174
161
         uint32_t in_query_start_line,
175
 
         char *in_file_name,
 
162
         char *in_file_name,
176
163
         LineBuffer *in_line_buff,
177
 
         bool in_batch,
178
 
         bool in_add_to_history)
 
164
         bool in_batch,
 
165
         bool in_add_to_history)
179
166
    :
180
167
    exit_status(in_exit_status),
181
168
    query_start_line(in_query_start_line),
185
172
    add_to_history(in_add_to_history)
186
173
    {}
187
174
 
188
 
  Status() :
189
 
    exit_status(0),
190
 
    query_start_line(0),
191
 
    file_name(NULL),
192
 
    line_buff(NULL),
193
 
    batch(false),        
194
 
    add_to_history(false)
195
 
  {}
 
175
  Status()
 
176
    :
 
177
    exit_status(),
 
178
    query_start_line(),
 
179
    file_name(),
 
180
    line_buff(),
 
181
    batch(),        
 
182
    add_to_history()
 
183
    {}
196
184
  
197
185
  int getExitStatus() const
198
186
  {
272
260
static map<string, string> completion_map;
273
261
static string completion_string;
274
262
 
 
263
static char **defaults_argv;
275
264
 
276
265
enum enum_info_type { INFO_INFO,INFO_ERROR,INFO_RESULT};
277
266
typedef enum enum_info_type INFO_TYPE;
282
271
  connected= false, opt_raw_data= false, unbuffered= false,
283
272
  output_tables= false, opt_rehash= true, skip_updates= false,
284
273
  safe_updates= false, one_database= false,
285
 
  opt_shutdown= false, opt_ping= false,
 
274
  opt_compress= false, opt_shutdown= false, opt_ping= false,
286
275
  vertical= false, line_numbers= true, column_names= true,
287
276
  opt_nopager= true, opt_outfile= false, named_cmds= false,
288
 
  opt_nobeep= false, opt_reconnect= true,
289
 
  opt_secure_auth= false,
 
277
  tty_password= false, opt_nobeep= false, opt_reconnect= true,
 
278
  default_charset_used= false, opt_secure_auth= false,
290
279
  default_pager_set= false, opt_sigint_ignore= false,
291
280
  auto_vertical_output= false,
292
281
  show_warnings= false, executing_query= false, interrupted_query= false,
293
 
  use_drizzle_protocol= false, opt_local_infile;
294
 
static uint32_t show_progress_size= 0;
 
282
  opt_mysql= false;
 
283
static uint32_t  show_progress_size= 0;
295
284
static bool column_types_flag;
296
285
static bool preserve_comments= false;
297
 
static uint32_t opt_max_input_line;
298
 
static uint32_t opt_drizzle_port= 0;
299
 
static int  opt_silent, verbose= 0;
 
286
static uint32_t opt_max_input_line, opt_drizzle_port= 0;
 
287
static int verbose= 0, opt_silent= 0, opt_local_infile= 0;
300
288
static drizzle_capabilities_t connect_flag= DRIZZLE_CAPABILITIES_NONE;
 
289
static char *current_host, *current_db, *current_user= NULL,
 
290
  *opt_password= NULL, *delimiter_str= NULL, *current_prompt= NULL;
301
291
static char *histfile;
302
292
static char *histfile_tmp;
303
293
static string *glob_buffer;
308
298
static uint32_t select_limit;
309
299
static uint32_t max_join_size;
310
300
static uint32_t opt_connect_timeout= 0;
311
 
static ServerDetect::server_type server_type= ServerDetect::SERVER_UNKNOWN_FOUND;
312
 
std::string current_db,
313
 
  delimiter_str,  
314
 
  current_host,
315
 
  current_prompt,
316
 
  current_user,
317
 
  opt_verbose,
318
 
  current_password,
319
 
  opt_password,
320
 
  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
 
 
378
 
/* @TODO: Remove this */
379
 
#define FN_REFLEN 512
380
 
 
381
 
static string default_pager("");
382
 
static string pager("");
383
 
static string outfile("");
 
301
// TODO: Need to i18n these
 
302
static const char *day_names[]= {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
 
303
static const char *month_names[]= {"Jan","Feb","Mar","Apr","May","Jun","Jul",
 
304
                                  "Aug","Sep","Oct","Nov","Dec"};
 
305
static char default_pager[FN_REFLEN];
 
306
static char pager[FN_REFLEN], outfile[FN_REFLEN];
384
307
static FILE *PAGER, *OUTFILE;
385
308
static uint32_t prompt_counter;
386
 
static char *delimiter= NULL;
 
309
static char delimiter[16]= DEFAULT_DELIMITER;
387
310
static uint32_t delimiter_length= 1;
388
311
unsigned short terminal_width= 80;
389
312
 
390
 
int drizzleclient_real_query_for_lazy(const char *buf, size_t length,
 
313
static const CHARSET_INFO *charset_info= &my_charset_utf8_general_ci;
 
314
 
 
315
int drizzleclient_real_query_for_lazy(const char *buf, int length,
391
316
                                      drizzle_result_st *result,
392
317
                                      uint32_t *error_code);
393
318
int drizzleclient_store_result_for_lazy(drizzle_result_st *result);
399
324
void tee_putc(int c, FILE *file);
400
325
static void tee_print_sized_data(const char *, unsigned int, unsigned int, bool);
401
326
/* The names of functions that actually do the manipulation. */
402
 
static int process_options(void);
 
327
static int get_options(int argc,char **argv);
403
328
static int com_quit(string *str,const char*),
404
329
  com_go(string *str,const char*), com_ego(string *str,const char*),
405
330
  com_print(string *str,const char*),
406
331
  com_help(string *str,const char*), com_clear(string *str,const char*),
407
332
  com_connect(string *str,const char*), com_status(string *str,const char*),
408
333
  com_use(string *str,const char*), com_source(string *str, const char*),
409
 
  com_shutdown(string *str,const char*),
410
334
  com_rehash(string *str, const char*), com_tee(string *str, const char*),
411
335
  com_notee(string *str, const char*),
412
336
  com_prompt(string *str, const char*), com_delimiter(string *str, const char*),
414
338
  com_nopager(string *str, const char*), com_pager(string *str, const char*);
415
339
 
416
340
static int read_and_execute(bool interactive);
417
 
static int sql_connect(const string &host, const string &database, const string &user, const string &password);
 
341
static int sql_connect(char *host,char *database,char *user,char *password,
 
342
                       uint32_t silent);
418
343
static const char *server_version_string(drizzle_con_st *con);
419
344
static int put_info(const char *str,INFO_TYPE info,uint32_t error,
420
345
                    const char *sql_state);
430
355
static void add_int_to_prompt(int toadd);
431
356
static int get_result_width(drizzle_result_st *res);
432
357
static int get_field_disp_length(drizzle_column_st * field);
433
 
static const char * strcont(const char *str, const char *set);
 
358
static const char * strcont(register const char *str, register const char *set);
434
359
 
435
360
/* A class which contains information on the commands this program
436
361
   can understand. */
536
461
  Commands( "tee",    'T', com_tee,    1,
537
462
    N_("Set outfile [to_outfile]. Append everything into given outfile.") ),
538
463
  Commands( "use",    'u', com_use,    1,
539
 
    N_("Use another schema. Takes schema name as argument.") ),
540
 
  Commands( "shutdown",    'u', com_shutdown,    1,
541
 
    N_("Shutdown the instance you are connected too.") ),
 
464
    N_("Use another database. Takes database name as argument.") ),
542
465
  Commands( "warnings", 'W', com_warnings,  0,
543
466
    N_("Show warnings after every statement.") ),
544
467
  Commands( "nowarning", 'w', com_nowarnings, 0,
574
497
  Commands( "AUTO_INCREMENT", 0, 0, 0, ""),
575
498
  Commands( "AVG", 0, 0, 0, ""),
576
499
  Commands( "AVG_ROW_LENGTH", 0, 0, 0, ""),
 
500
  Commands( "BACKUP", 0, 0, 0, ""),
 
501
  Commands( "BDB", 0, 0, 0, ""),
577
502
  Commands( "BEFORE", 0, 0, 0, ""),
578
503
  Commands( "BEGIN", 0, 0, 0, ""),
 
504
  Commands( "BERKELEYDB", 0, 0, 0, ""),
579
505
  Commands( "BETWEEN", 0, 0, 0, ""),
580
506
  Commands( "BIGINT", 0, 0, 0, ""),
581
507
  Commands( "BINARY", 0, 0, 0, ""),
 
508
  Commands( "BINLOG", 0, 0, 0, ""),
582
509
  Commands( "BIT", 0, 0, 0, ""),
583
510
  Commands( "BLOB", 0, 0, 0, ""),
584
511
  Commands( "BOOL", 0, 0, 0, ""),
597
524
  Commands( "CHANGED", 0, 0, 0, ""),
598
525
  Commands( "CHAR", 0, 0, 0, ""),
599
526
  Commands( "CHARACTER", 0, 0, 0, ""),
 
527
  Commands( "CHARSET", 0, 0, 0, ""),
600
528
  Commands( "CHECK", 0, 0, 0, ""),
601
529
  Commands( "CHECKSUM", 0, 0, 0, ""),
 
530
  Commands( "CIPHER", 0, 0, 0, ""),
602
531
  Commands( "CLIENT", 0, 0, 0, ""),
603
532
  Commands( "CLOSE", 0, 0, 0, ""),
 
533
  Commands( "CODE", 0, 0, 0, ""),
604
534
  Commands( "COLLATE", 0, 0, 0, ""),
605
535
  Commands( "COLLATION", 0, 0, 0, ""),
606
536
  Commands( "COLUMN", 0, 0, 0, ""),
642
572
  Commands( "DEFAULT", 0, 0, 0, ""),
643
573
  Commands( "DEFINER", 0, 0, 0, ""),
644
574
  Commands( "DELAYED", 0, 0, 0, ""),
 
575
  Commands( "DELAY_KEY_WRITE", 0, 0, 0, ""),
645
576
  Commands( "DELETE", 0, 0, 0, ""),
646
577
  Commands( "DESC", 0, 0, 0, ""),
647
578
  Commands( "DESCRIBE", 0, 0, 0, ""),
 
579
  Commands( "DES_KEY_FILE", 0, 0, 0, ""),
648
580
  Commands( "DETERMINISTIC", 0, 0, 0, ""),
 
581
  Commands( "DIRECTORY", 0, 0, 0, ""),
649
582
  Commands( "DISABLE", 0, 0, 0, ""),
650
583
  Commands( "DISCARD", 0, 0, 0, ""),
651
584
  Commands( "DISTINCT", 0, 0, 0, ""),
652
585
  Commands( "DISTINCTROW", 0, 0, 0, ""),
653
586
  Commands( "DIV", 0, 0, 0, ""),
 
587
  Commands( "DO", 0, 0, 0, ""),
654
588
  Commands( "DOUBLE", 0, 0, 0, ""),
655
589
  Commands( "DROP", 0, 0, 0, ""),
 
590
  Commands( "DUAL", 0, 0, 0, ""),
656
591
  Commands( "DUMPFILE", 0, 0, 0, ""),
657
592
  Commands( "DUPLICATE", 0, 0, 0, ""),
658
593
  Commands( "DYNAMIC", 0, 0, 0, ""),
668
603
  Commands( "ERRORS", 0, 0, 0, ""),
669
604
  Commands( "ESCAPE", 0, 0, 0, ""),
670
605
  Commands( "ESCAPED", 0, 0, 0, ""),
 
606
  Commands( "EVENTS", 0, 0, 0, ""),
 
607
  Commands( "EXECUTE", 0, 0, 0, ""),
671
608
  Commands( "EXISTS", 0, 0, 0, ""),
672
609
  Commands( "EXIT", 0, 0, 0, ""),
 
610
  Commands( "EXPANSION", 0, 0, 0, ""),
673
611
  Commands( "EXPLAIN", 0, 0, 0, ""),
674
612
  Commands( "EXTENDED", 0, 0, 0, ""),
675
613
  Commands( "FALSE", 0, 0, 0, ""),
690
628
  Commands( "FRAC_SECOND", 0, 0, 0, ""),
691
629
  Commands( "FROM", 0, 0, 0, ""),
692
630
  Commands( "FULL", 0, 0, 0, ""),
 
631
  Commands( "FULLTEXT", 0, 0, 0, ""),
693
632
  Commands( "FUNCTION", 0, 0, 0, ""),
694
633
  Commands( "GLOBAL", 0, 0, 0, ""),
695
634
  Commands( "GRANT", 0, 0, 0, ""),
757
696
  Commands( "LOCKS", 0, 0, 0, ""),
758
697
  Commands( "LOGS", 0, 0, 0, ""),
759
698
  Commands( "LONG", 0, 0, 0, ""),
 
699
  Commands( "LONGTEXT", 0, 0, 0, ""),
760
700
  Commands( "LOOP", 0, 0, 0, ""),
 
701
  Commands( "LOW_PRIORITY", 0, 0, 0, ""),
 
702
  Commands( "MASTER", 0, 0, 0, ""),
 
703
  Commands( "MASTER_CONNECT_RETRY", 0, 0, 0, ""),
 
704
  Commands( "MASTER_HOST", 0, 0, 0, ""),
 
705
  Commands( "MASTER_LOG_FILE", 0, 0, 0, ""),
 
706
  Commands( "MASTER_LOG_POS", 0, 0, 0, ""),
 
707
  Commands( "MASTER_PASSWORD", 0, 0, 0, ""),
 
708
  Commands( "MASTER_PORT", 0, 0, 0, ""),
 
709
  Commands( "MASTER_SERVER_ID", 0, 0, 0, ""),
 
710
  Commands( "MASTER_SSL", 0, 0, 0, ""),
 
711
  Commands( "MASTER_SSL_CA", 0, 0, 0, ""),
 
712
  Commands( "MASTER_SSL_CAPATH", 0, 0, 0, ""),
 
713
  Commands( "MASTER_SSL_CERT", 0, 0, 0, ""),
 
714
  Commands( "MASTER_SSL_CIPHER", 0, 0, 0, ""),
 
715
  Commands( "MASTER_SSL_KEY", 0, 0, 0, ""),
 
716
  Commands( "MASTER_USER", 0, 0, 0, ""),
761
717
  Commands( "MATCH", 0, 0, 0, ""),
762
718
  Commands( "MAX_CONNECTIONS_PER_HOUR", 0, 0, 0, ""),
763
719
  Commands( "MAX_QUERIES_PER_HOUR", 0, 0, 0, ""),
765
721
  Commands( "MAX_UPDATES_PER_HOUR", 0, 0, 0, ""),
766
722
  Commands( "MAX_USER_CONNECTIONS", 0, 0, 0, ""),
767
723
  Commands( "MEDIUM", 0, 0, 0, ""),
 
724
  Commands( "MEDIUMTEXT", 0, 0, 0, ""),
768
725
  Commands( "MERGE", 0, 0, 0, ""),
769
726
  Commands( "MICROSECOND", 0, 0, 0, ""),
 
727
  Commands( "MIDDLEINT", 0, 0, 0, ""),
770
728
  Commands( "MIGRATE", 0, 0, 0, ""),
771
729
  Commands( "MINUTE", 0, 0, 0, ""),
772
730
  Commands( "MINUTE_MICROSECOND", 0, 0, 0, ""),
785
743
  Commands( "NAMES", 0, 0, 0, ""),
786
744
  Commands( "NATIONAL", 0, 0, 0, ""),
787
745
  Commands( "NATURAL", 0, 0, 0, ""),
 
746
  Commands( "NDB", 0, 0, 0, ""),
 
747
  Commands( "NDBCLUSTER", 0, 0, 0, ""),
788
748
  Commands( "NCHAR", 0, 0, 0, ""),
789
749
  Commands( "NEW", 0, 0, 0, ""),
790
750
  Commands( "NEXT", 0, 0, 0, ""),
791
751
  Commands( "NO", 0, 0, 0, ""),
792
752
  Commands( "NONE", 0, 0, 0, ""),
793
753
  Commands( "NOT", 0, 0, 0, ""),
 
754
  Commands( "NO_WRITE_TO_BINLOG", 0, 0, 0, ""),
794
755
  Commands( "NULL", 0, 0, 0, ""),
795
756
  Commands( "NUMERIC", 0, 0, 0, ""),
796
757
  Commands( "NVARCHAR", 0, 0, 0, ""),
797
758
  Commands( "OFFSET", 0, 0, 0, ""),
 
759
  Commands( "OLD_PASSWORD", 0, 0, 0, ""),
798
760
  Commands( "ON", 0, 0, 0, ""),
799
761
  Commands( "ONE", 0, 0, 0, ""),
800
762
  Commands( "ONE_SHOT", 0, 0, 0, ""),
811
773
  Commands( "PARTIAL", 0, 0, 0, ""),
812
774
  Commands( "PASSWORD", 0, 0, 0, ""),
813
775
  Commands( "PHASE", 0, 0, 0, ""),
 
776
  Commands( "POINT", 0, 0, 0, ""),
 
777
  Commands( "POLYGON", 0, 0, 0, ""),
814
778
  Commands( "PRECISION", 0, 0, 0, ""),
815
779
  Commands( "PREPARE", 0, 0, 0, ""),
816
780
  Commands( "PREV", 0, 0, 0, ""),
830
794
  Commands( "REDUNDANT", 0, 0, 0, ""),
831
795
  Commands( "REFERENCES", 0, 0, 0, ""),
832
796
  Commands( "REGEXP", 0, 0, 0, ""),
 
797
  Commands( "RELAY_LOG_FILE", 0, 0, 0, ""),
 
798
  Commands( "RELAY_LOG_POS", 0, 0, 0, ""),
 
799
  Commands( "RELAY_THREAD", 0, 0, 0, ""),
833
800
  Commands( "RELEASE", 0, 0, 0, ""),
834
801
  Commands( "RELOAD", 0, 0, 0, ""),
835
802
  Commands( "RENAME", 0, 0, 0, ""),
836
803
  Commands( "REPAIR", 0, 0, 0, ""),
837
804
  Commands( "REPEATABLE", 0, 0, 0, ""),
838
805
  Commands( "REPLACE", 0, 0, 0, ""),
 
806
  Commands( "REPLICATION", 0, 0, 0, ""),
839
807
  Commands( "REPEAT", 0, 0, 0, ""),
840
808
  Commands( "REQUIRE", 0, 0, 0, ""),
841
809
  Commands( "RESET", 0, 0, 0, ""),
874
842
  Commands( "SIMPLE", 0, 0, 0, ""),
875
843
  Commands( "SLAVE", 0, 0, 0, ""),
876
844
  Commands( "SNAPSHOT", 0, 0, 0, ""),
 
845
  Commands( "SMALLINT", 0, 0, 0, ""),
877
846
  Commands( "SOME", 0, 0, 0, ""),
878
847
  Commands( "SONAME", 0, 0, 0, ""),
879
848
  Commands( "SOUNDS", 0, 0, 0, ""),
922
891
  Commands( "TIMESTAMP", 0, 0, 0, ""),
923
892
  Commands( "TIMESTAMPADD", 0, 0, 0, ""),
924
893
  Commands( "TIMESTAMPDIFF", 0, 0, 0, ""),
 
894
  Commands( "TINYTEXT", 0, 0, 0, ""),
925
895
  Commands( "TO", 0, 0, 0, ""),
926
896
  Commands( "TRAILING", 0, 0, 0, ""),
927
897
  Commands( "TRANSACTION", 0, 0, 0, ""),
 
898
  Commands( "TRIGGER", 0, 0, 0, ""),
 
899
  Commands( "TRIGGERS", 0, 0, 0, ""),
928
900
  Commands( "TRUE", 0, 0, 0, ""),
929
901
  Commands( "TRUNCATE", 0, 0, 0, ""),
930
902
  Commands( "TYPE", 0, 0, 0, ""),
937
909
  Commands( "UNIQUE", 0, 0, 0, ""),
938
910
  Commands( "UNKNOWN", 0, 0, 0, ""),
939
911
  Commands( "UNLOCK", 0, 0, 0, ""),
 
912
  Commands( "UNSIGNED", 0, 0, 0, ""),
940
913
  Commands( "UNTIL", 0, 0, 0, ""),
941
914
  Commands( "UPDATE", 0, 0, 0, ""),
942
915
  Commands( "UPGRADE", 0, 0, 0, ""),
944
917
  Commands( "USE", 0, 0, 0, ""),
945
918
  Commands( "USER", 0, 0, 0, ""),
946
919
  Commands( "USER_RESOURCES", 0, 0, 0, ""),
 
920
  Commands( "USE_FRM", 0, 0, 0, ""),
947
921
  Commands( "USING", 0, 0, 0, ""),
948
922
  Commands( "UTC_DATE", 0, 0, 0, ""),
949
923
  Commands( "UTC_TIMESTAMP", 0, 0, 0, ""),
963
937
  Commands( "WITH", 0, 0, 0, ""),
964
938
  Commands( "WORK", 0, 0, 0, ""),
965
939
  Commands( "WRITE", 0, 0, 0, ""),
 
940
  Commands( "X509", 0, 0, 0, ""),
966
941
  Commands( "XOR", 0, 0, 0, ""),
967
942
  Commands( "XA", 0, 0, 0, ""),
968
943
  Commands( "YEAR", 0, 0, 0, ""),
971
946
  Commands( "ABS", 0, 0, 0, ""),
972
947
  Commands( "ACOS", 0, 0, 0, ""),
973
948
  Commands( "ADDDATE", 0, 0, 0, ""),
 
949
  Commands( "AES_ENCRYPT", 0, 0, 0, ""),
 
950
  Commands( "AES_DECRYPT", 0, 0, 0, ""),
974
951
  Commands( "AREA", 0, 0, 0, ""),
975
952
  Commands( "ASIN", 0, 0, 0, ""),
976
953
  Commands( "ASBINARY", 0, 0, 0, ""),
977
954
  Commands( "ASTEXT", 0, 0, 0, ""),
 
955
  Commands( "ASWKB", 0, 0, 0, ""),
 
956
  Commands( "ASWKT", 0, 0, 0, ""),
978
957
  Commands( "ATAN", 0, 0, 0, ""),
979
958
  Commands( "ATAN2", 0, 0, 0, ""),
980
959
  Commands( "BENCHMARK", 0, 0, 0, ""),
1040
1019
  Commands( "GROUP_UNIQUE_USERS", 0, 0, 0, ""),
1041
1020
  Commands( "HEX", 0, 0, 0, ""),
1042
1021
  Commands( "IFNULL", 0, 0, 0, ""),
 
1022
  Commands( "INET_ATON", 0, 0, 0, ""),
 
1023
  Commands( "INET_NTOA", 0, 0, 0, ""),
1043
1024
  Commands( "INSTR", 0, 0, 0, ""),
1044
1025
  Commands( "INTERIORRINGN", 0, 0, 0, ""),
1045
1026
  Commands( "INTERSECTS", 0, 0, 0, ""),
1055
1036
  Commands( "LEAST", 0, 0, 0, ""),
1056
1037
  Commands( "LENGTH", 0, 0, 0, ""),
1057
1038
  Commands( "LN", 0, 0, 0, ""),
 
1039
  Commands( "LINEFROMTEXT", 0, 0, 0, ""),
 
1040
  Commands( "LINEFROMWKB", 0, 0, 0, ""),
 
1041
  Commands( "LINESTRINGFROMTEXT", 0, 0, 0, ""),
 
1042
  Commands( "LINESTRINGFROMWKB", 0, 0, 0, ""),
1058
1043
  Commands( "LOAD_FILE", 0, 0, 0, ""),
1059
1044
  Commands( "LOCATE", 0, 0, 0, ""),
1060
1045
  Commands( "LOG", 0, 0, 0, ""),
1077
1062
  Commands( "MD5", 0, 0, 0, ""),
1078
1063
  Commands( "MID", 0, 0, 0, ""),
1079
1064
  Commands( "MIN", 0, 0, 0, ""),
 
1065
  Commands( "MLINEFROMTEXT", 0, 0, 0, ""),
 
1066
  Commands( "MLINEFROMWKB", 0, 0, 0, ""),
 
1067
  Commands( "MPOINTFROMTEXT", 0, 0, 0, ""),
 
1068
  Commands( "MPOINTFROMWKB", 0, 0, 0, ""),
 
1069
  Commands( "MPOLYFROMTEXT", 0, 0, 0, ""),
 
1070
  Commands( "MPOLYFROMWKB", 0, 0, 0, ""),
1080
1071
  Commands( "MONTHNAME", 0, 0, 0, ""),
 
1072
  Commands( "MULTILINESTRINGFROMTEXT", 0, 0, 0, ""),
 
1073
  Commands( "MULTILINESTRINGFROMWKB", 0, 0, 0, ""),
 
1074
  Commands( "MULTIPOINTFROMTEXT", 0, 0, 0, ""),
 
1075
  Commands( "MULTIPOINTFROMWKB", 0, 0, 0, ""),
 
1076
  Commands( "MULTIPOLYGONFROMTEXT", 0, 0, 0, ""),
 
1077
  Commands( "MULTIPOLYGONFROMWKB", 0, 0, 0, ""),
1081
1078
  Commands( "NAME_CONST", 0, 0, 0, ""),
1082
1079
  Commands( "NOW", 0, 0, 0, ""),
1083
1080
  Commands( "NULLIF", 0, 0, 0, ""),
 
1081
  Commands( "NUMINTERIORRINGS", 0, 0, 0, ""),
1084
1082
  Commands( "NUMPOINTS", 0, 0, 0, ""),
1085
1083
  Commands( "OCTET_LENGTH", 0, 0, 0, ""),
1086
1084
  Commands( "OCT", 0, 0, 0, ""),
1089
1087
  Commands( "PERIOD_ADD", 0, 0, 0, ""),
1090
1088
  Commands( "PERIOD_DIFF", 0, 0, 0, ""),
1091
1089
  Commands( "PI", 0, 0, 0, ""),
 
1090
  Commands( "POINTFROMTEXT", 0, 0, 0, ""),
 
1091
  Commands( "POINTFROMWKB", 0, 0, 0, ""),
1092
1092
  Commands( "POINTN", 0, 0, 0, ""),
 
1093
  Commands( "POLYFROMTEXT", 0, 0, 0, ""),
 
1094
  Commands( "POLYFROMWKB", 0, 0, 0, ""),
 
1095
  Commands( "POLYGONFROMTEXT", 0, 0, 0, ""),
 
1096
  Commands( "POLYGONFROMWKB", 0, 0, 0, ""),
1093
1097
  Commands( "POSITION", 0, 0, 0, ""),
1094
1098
  Commands( "POW", 0, 0, 0, ""),
1095
1099
  Commands( "POWER", 0, 0, 0, ""),
1153
1157
  Commands((char *)NULL,       0, 0, 0, "")
1154
1158
};
1155
1159
 
 
1160
static const char *load_default_groups[]= { "drizzle","client",0 };
1156
1161
 
1157
1162
int history_length;
1158
1163
static int not_in_history(const char *line);
1167
1172
static void print_tab_data(drizzle_result_st *result);
1168
1173
static void print_table_data_vertically(drizzle_result_st *result);
1169
1174
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);
 
1175
static uint32_t start_timer(void);
 
1176
static void end_timer(uint32_t start_time,char *buff);
 
1177
static void drizzle_end_timer(uint32_t start_time,char *buff);
 
1178
static void nice_time(double sec,char *buff,bool part_second);
1174
1179
extern "C" void drizzle_end(int sig);
1175
1180
extern "C" void handle_sigint(int sig);
1176
1181
#if defined(HAVE_TERMIOS_H) && defined(GWINSZ_IN_SYS_IOCTL)
1192
1197
 
1193
1198
  if (verbose)
1194
1199
  {
1195
 
    printf(_("shutting down drizzled"));
 
1200
    printf("shutting down drizzled");
1196
1201
    if (opt_drizzle_port > 0)
1197
 
      printf(_(" on port %d"), opt_drizzle_port);
 
1202
      printf(" on port %d", opt_drizzle_port);
1198
1203
    printf("... ");
1199
1204
  }
1200
1205
 
1203
1208
  {
1204
1209
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
1205
1210
    {
1206
 
      fprintf(stderr, _("shutdown failed; error: '%s'"),
 
1211
      fprintf(stderr, "shutdown failed; error: '%s'",
1207
1212
              drizzle_result_error(&result));
1208
1213
      drizzle_result_free(&result);
1209
1214
    }
1210
1215
    else
1211
1216
    {
1212
 
      fprintf(stderr, _("shutdown failed; error: '%s'"),
 
1217
      fprintf(stderr, "shutdown failed; error: '%s'",
1213
1218
              drizzle_con_error(&con));
1214
1219
    }
1215
1220
    return false;
1218
1223
  drizzle_result_free(&result);
1219
1224
 
1220
1225
  if (verbose)
1221
 
    printf(_("done\n"));
 
1226
    printf("done\n");
1222
1227
 
1223
1228
  return true;
1224
1229
}
1239
1244
  if (drizzle_ping(&con, &result, &ret) != NULL && ret == DRIZZLE_RETURN_OK)
1240
1245
  {
1241
1246
    if (opt_silent < 2)
1242
 
      printf(_("drizzled is alive\n"));
 
1247
      printf("drizzled is alive\n");
1243
1248
  }
1244
1249
  else
1245
1250
  {
1246
1251
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
1247
1252
    {
1248
 
      fprintf(stderr, _("ping failed; error: '%s'"),
 
1253
      fprintf(stderr, "ping failed; error: '%s'",
1249
1254
              drizzle_result_error(&result));
1250
1255
      drizzle_result_free(&result);
1251
1256
    }
1252
1257
    else
1253
1258
    {
1254
 
      fprintf(stderr, _("drizzled won't answer to ping, error: '%s'"),
 
1259
      fprintf(stderr, "drizzled won't answer to ping, error: '%s'",
1255
1260
              drizzle_con_error(&con));
1256
1261
    }
1257
1262
    return false;
1295
1300
  return executed;
1296
1301
}
1297
1302
 
1298
 
static void check_timeout_value(uint32_t in_connect_timeout)
1299
 
{
1300
 
  opt_connect_timeout= 0;
1301
 
  if (in_connect_timeout > 3600*12)
1302
 
  {
1303
 
    cout << _("Error: Invalid Value for connect_timeout"); 
1304
 
    exit(-1);
1305
 
  }
1306
 
  opt_connect_timeout= in_connect_timeout;
1307
 
}
1308
 
 
1309
 
static void check_max_input_line(uint32_t in_max_input_line)
1310
 
{
1311
 
  opt_max_input_line= 0;
1312
 
  if (in_max_input_line < 4096 || in_max_input_line > (int64_t)2*1024L*1024L*1024L)
1313
 
  {
1314
 
    cout << _("Error: Invalid Value for max_input_line");
1315
 
    exit(-1);
1316
 
  }
1317
 
  opt_max_input_line= in_max_input_line - (in_max_input_line % 1024);
1318
 
}
1319
 
 
1320
1303
int main(int argc,char *argv[])
1321
1304
{
1322
 
try
1323
 
{
1324
 
 
1325
1305
#if defined(ENABLE_NLS)
1326
1306
# if defined(HAVE_LOCALE_H)
1327
1307
  setlocale(LC_ALL, "");
1328
1308
# endif
1329
 
  bindtextdomain("drizzle7", LOCALEDIR);
1330
 
  textdomain("drizzle7");
1331
 
#endif
1332
 
 
1333
 
  po::options_description commandline_options(_("Options used only in command line"));
1334
 
  commandline_options.add_options()
1335
 
  ("help,?",_("Displays this help and exit."))
1336
 
  ("batch,B",_("Don't use history file. Disable interactive behavior. (Enables --silent)"))
1337
 
  ("column-type-info", po::value<bool>(&column_types_flag)->default_value(false)->zero_tokens(),
1338
 
  _("Display column type information."))
1339
 
  ("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"))
1341
 
  ("vertical,E", po::value<bool>(&vertical)->default_value(false)->zero_tokens(),
1342
 
  _("Print the output of a query (rows) vertically."))
1343
 
  ("force,f", po::value<bool>(&ignore_errors)->default_value(false)->zero_tokens(),
1344
 
  _("Continue even if we get an sql error."))
1345
 
  ("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."))
1347
 
  ("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."))
1351
 
  ("skip-column-names,N", 
1352
 
  _("Don't write column names in results. WARNING: -N is deprecated, use long version of this options instead."))
1353
 
  ("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."))
1355
 
  ("table,t", po::value<bool>(&output_tables)->default_value(false)->zero_tokens(),
1356
 
  _("Output in table format.")) 
1357
 
  ("safe-updates,U", po::value<bool>(&safe_updates)->default_value(false)->zero_tokens(),
1358
 
  _("Only allow UPDATE and DELETE that uses keys."))
1359
 
  ("i-am-a-dummy,U", po::value<bool>(&safe_updates)->default_value(false)->zero_tokens(),
1360
 
  _("Synonym for option --safe-updates, -U."))
1361
 
  ("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."))
1364
 
  ("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"))
1366
 
  ("show-warnings", po::value<bool>(&show_warnings)->default_value(false)->zero_tokens(),
1367
 
  _("Show warnings after every statement."))
1368
 
  ("show-progress-size", po::value<uint32_t>(&show_progress_size)->default_value(0),
1369
 
  _("Number of lines before each import progress report."))
1370
 
  ("ping", po::value<bool>(&opt_ping)->default_value(false)->zero_tokens(),
1371
 
  _("Ping the server to check if it's alive."))
1372
 
  ("no-defaults", po::value<bool>()->default_value(false)->zero_tokens(),
1373
 
  _("Configuration file defaults are not used if no-defaults is set"))
1374
 
  ;
1375
 
 
1376
 
  po::options_description drizzle_options(_("Options specific to the drizzle client"));
1377
 
  drizzle_options.add_options()
1378
 
  ("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."))
1380
 
  ("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."))
1382
 
  ("database,D", po::value<string>(&current_db)->default_value(""),
1383
 
  _("Database to use."))
1384
 
  ("default-character-set",po::value<string>(),
1385
 
  _("(not used)"))
1386
 
  ("delimiter", po::value<string>(&delimiter_str)->default_value(";"),
1387
 
  _("Delimiter to be used."))
1388
 
  ("execute,e", po::value<string>(),
1389
 
  _("Execute command and quit. (Disables --force and history file)"))
1390
 
  ("local-infile", po::value<bool>(&opt_local_infile)->default_value(false)->zero_tokens(),
1391
 
  _("Enable LOAD DATA LOCAL INFILE."))
1392
 
  ("unbuffered,n", po::value<bool>(&unbuffered)->default_value(false)->zero_tokens(),
1393
 
  _("Flush buffer after each query."))
1394
 
  ("sigint-ignore", po::value<bool>(&opt_sigint_ignore)->default_value(false)->zero_tokens(),
1395
 
  _("Ignore SIGINT (CTRL-C)"))
1396
 
  ("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."))
1398
 
  ("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."))
1400
 
  ("disable-pager", po::value<bool>(&opt_nopager)->default_value(false)->zero_tokens(),
1401
 
  _("Disable pager and print to stdout. See interactive help (\\h) also."))
1402
 
  ("prompt", po::value<string>(&current_prompt)->default_value(""),  
1403
 
  _("Set the drizzle prompt to this value."))
1404
 
  ("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."))
1406
 
  ("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."))
1409
 
  ("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."))
1412
 
  ("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."))
1414
 
  ("disable-tee", po::value<bool>()->default_value(false)->zero_tokens(), 
1415
 
  _("Disable outfile. See interactive help (\\h) also."))
1416
 
  ("connect-timeout", po::value<uint32_t>(&opt_connect_timeout)->default_value(0)->notifier(&check_timeout_value),
1417
 
  _("Number of seconds before connection timeout."))
1418
 
  ("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"))
1420
 
  ("select-limit", po::value<uint32_t>(&select_limit)->default_value(1000L),
1421
 
  _("Automatic limit for SELECT when using --safe-updates"))
1422
 
  ("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"))
1424
 
  ;
1425
 
 
1426
 
  po::options_description client_options(_("Options specific to the client"));
1427
 
  client_options.add_options()
1428
 
  ("host,h", po::value<string>(&current_host)->default_value("localhost"),
1429
 
  _("Connect to host"))
1430
 
  ("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."))
1432
 
  ("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
1437
 
  ("user,u", po::value<string>(&current_user)->default_value(""),
1438
 
#endif
1439
 
  _("User for login if not current user."))
1440
 
  ("protocol",po::value<string>(&opt_protocol)->default_value("mysql"),
1441
 
  _("The protocol of connection (mysql or drizzle)."))
1442
 
  ;
1443
 
 
1444
 
  po::options_description long_options(_("Allowed Options"));
1445
 
  long_options.add(commandline_options).add(drizzle_options).add(client_options);
1446
 
 
1447
 
  std::string system_config_dir_drizzle(SYSCONFDIR); 
1448
 
  system_config_dir_drizzle.append("/drizzle/drizzle.cnf");
1449
 
 
1450
 
  std::string system_config_dir_client(SYSCONFDIR); 
1451
 
  system_config_dir_client.append("/drizzle/client.cnf");
1452
 
 
1453
 
  std::string user_config_dir((getenv("XDG_CONFIG_HOME")? getenv("XDG_CONFIG_HOME"):"~/.config"));
1454
 
 
1455
 
  if (user_config_dir.compare(0, 2, "~/") == 0)
1456
 
  {
1457
 
    char *homedir;
1458
 
    homedir= getenv("HOME");
1459
 
    if (homedir != NULL)
1460
 
      user_config_dir.replace(0, 1, homedir);
1461
 
  }
1462
 
 
1463
 
  po::variables_map vm;
1464
 
 
1465
 
  po::positional_options_description p;
1466
 
  p.add("database", 1);
1467
 
 
1468
 
  // Disable allow_guessing
1469
 
  int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
1470
 
 
1471
 
  po::store(po::command_line_parser(argc, argv).options(long_options).
1472
 
            style(style).positional(p).extra_parser(parse_password_arg).run(),
1473
 
            vm);
1474
 
 
1475
 
  if (! vm["no-defaults"].as<bool>())
1476
 
  {
1477
 
    std::string user_config_dir_drizzle(user_config_dir);
1478
 
    user_config_dir_drizzle.append("/drizzle/drizzle.cnf"); 
1479
 
 
1480
 
    std::string user_config_dir_client(user_config_dir);
1481
 
    user_config_dir_client.append("/drizzle/client.cnf");
1482
 
 
1483
 
    ifstream user_drizzle_ifs(user_config_dir_drizzle.c_str());
1484
 
    po::store(dpo::parse_config_file(user_drizzle_ifs, drizzle_options), vm);
1485
 
 
1486
 
    ifstream user_client_ifs(user_config_dir_client.c_str());
1487
 
    po::store(dpo::parse_config_file(user_client_ifs, client_options), vm);
1488
 
 
1489
 
    ifstream system_drizzle_ifs(system_config_dir_drizzle.c_str());
1490
 
    store(dpo::parse_config_file(system_drizzle_ifs, drizzle_options), vm);
1491
 
 
1492
 
    ifstream system_client_ifs(system_config_dir_client.c_str());
1493
 
    po::store(dpo::parse_config_file(system_client_ifs, client_options), vm);
1494
 
  }
1495
 
 
1496
 
  po::notify(vm);
1497
 
 
1498
 
#ifdef DRIZZLE_ADMIN_TOOL
1499
 
  default_prompt= strdup(getenv("DRIZZLE_PS1") ?
1500
 
                         getenv("DRIZZLE_PS1") :
1501
 
                         "drizzleadmin> ");
1502
 
#else
 
1309
  bindtextdomain("drizzle", LOCALEDIR);
 
1310
  textdomain("drizzle");
 
1311
#endif
 
1312
 
 
1313
  MY_INIT(argv[0]);
 
1314
  delimiter_str= delimiter;
1503
1315
  default_prompt= strdup(getenv("DRIZZLE_PS1") ?
1504
1316
                         getenv("DRIZZLE_PS1") :
1505
1317
                         "drizzle> ");
1506
 
#endif
 
1318
  
1507
1319
  if (default_prompt == NULL)
1508
1320
  {
1509
1321
    fprintf(stderr, _("Memory allocation error while constructing initial "
1510
1322
                      "prompt. Aborting.\n"));
1511
1323
    exit(ENOMEM);
1512
1324
  }
1513
 
 
1514
 
  if (current_prompt.empty())
1515
 
    current_prompt= strdup(default_prompt);
1516
 
 
1517
 
  if (current_prompt.empty())
 
1325
  current_prompt= strdup(default_prompt);
 
1326
  if (current_prompt == NULL)
1518
1327
  {
1519
1328
    fprintf(stderr, _("Memory allocation error while constructing initial "
1520
1329
                      "prompt. Aborting.\n"));
1525
1334
 
1526
1335
  prompt_counter=0;
1527
1336
 
1528
 
  outfile.clear();      // no (default) outfile
1529
 
  pager.assign("stdout");  // the default, if --pager wasn't given
 
1337
  outfile[0]=0;      // no (default) outfile
 
1338
  strcpy(pager, "stdout");  // the default, if --pager wasn't given
1530
1339
  {
1531
 
    const char *tmp= getenv("PAGER");
 
1340
    char *tmp=getenv("PAGER");
1532
1341
    if (tmp && strlen(tmp))
1533
1342
    {
1534
1343
      default_pager_set= 1;
1535
 
      default_pager.assign(tmp);
 
1344
      strcpy(default_pager, tmp);
1536
1345
    }
1537
1346
  }
1538
 
  if (! isatty(0) || ! isatty(1))
 
1347
  if (!isatty(0) || !isatty(1))
1539
1348
  {
1540
1349
    status.setBatch(1); opt_silent=1;
 
1350
    ignore_errors=0;
1541
1351
  }
1542
1352
  else
1543
1353
    status.setAddToHistory(1);
1557
1367
      close(stdout_fileno_copy);             /* Clean up dup(). */
1558
1368
  }
1559
1369
 
1560
 
  /* Inverted Booleans */
1561
 
 
1562
 
  line_numbers= (vm.count("disable-line-numbers")) ? false : true;
1563
 
  column_names= (vm.count("disable-column-names")) ? false : true;
1564
 
  opt_rehash= (vm.count("disable-auto-rehash")) ? false : true;
1565
 
  opt_reconnect= (vm.count("disable-reconnect")) ? false : true;
1566
 
 
1567
 
  /* Don't rehash with --shutdown */
1568
 
  if (vm.count("shutdown"))
1569
 
  {
1570
 
    opt_rehash= false;
1571
 
    opt_shutdown= true;
1572
 
  }
1573
 
 
1574
 
  if (vm.count("delimiter"))
1575
 
  {
1576
 
    /* Check that delimiter does not contain a backslash */
1577
 
    if (! strstr(delimiter_str.c_str(), "\\"))
1578
 
    {
1579
 
      delimiter= (char *)delimiter_str.c_str();  
1580
 
    }
1581
 
    else
1582
 
    {
1583
 
      put_info(_("DELIMITER cannot contain a backslash character"),
1584
 
      INFO_ERROR,0,0);
1585
 
      exit(-1);
1586
 
    }
1587
 
   
1588
 
    delimiter_length= (uint32_t)strlen(delimiter);
1589
 
  }
1590
 
  if (vm.count("tee"))
1591
 
  { 
1592
 
    if (vm["tee"].as<string>().empty())
1593
 
    {
1594
 
      if (opt_outfile)
1595
 
        end_tee();
1596
 
    }
1597
 
    else
1598
 
      init_tee(vm["tee"].as<string>().c_str());
1599
 
  }
1600
 
  if (vm["disable-tee"].as<bool>() == true)
1601
 
  {
1602
 
    if (opt_outfile)
1603
 
      end_tee();
1604
 
  }
1605
 
  if (vm.count("pager"))
1606
 
  {
1607
 
    if (vm["pager"].as<string>().empty())
1608
 
      opt_nopager= 1;
1609
 
    else
1610
 
    {
1611
 
      opt_nopager= 0;
1612
 
      if (vm[pager].as<string>().length())
1613
 
      {
1614
 
        default_pager_set= 1;
1615
 
        pager.assign(vm["pager"].as<string>());
1616
 
        default_pager.assign(pager);
1617
 
      }
1618
 
      else if (default_pager_set)
1619
 
        pager.assign(default_pager);
1620
 
      else
1621
 
        opt_nopager= 1;
1622
 
    }
1623
 
  }
1624
 
  if (vm.count("disable-pager"))
1625
 
  {
1626
 
    opt_nopager= 1;
1627
 
  }
1628
 
 
1629
 
  if (vm.count("no-auto-rehash"))
1630
 
    opt_rehash= 0;
1631
 
 
1632
 
  if (vm.count("skip-column-names"))
1633
 
    column_names= 0;
1634
 
    
1635
 
  if (vm.count("execute"))
1636
 
  {  
1637
 
    status.setBatch(1);
1638
 
    status.setAddToHistory(1);
1639
 
    if (status.getLineBuff() == NULL)
1640
 
      status.setLineBuff(opt_max_input_line,NULL);
1641
 
    if (status.getLineBuff() == NULL)
1642
 
    {
1643
 
      exit(1);
1644
 
    }
1645
 
    status.getLineBuff()->addString(vm["execute"].as<string>().c_str());
1646
 
  }
1647
 
 
1648
 
  if (one_database)
1649
 
    skip_updates= true;
1650
 
 
1651
 
  if (vm.count("protocol"))
1652
 
  {
1653
 
    std::transform(opt_protocol.begin(), opt_protocol.end(), 
1654
 
      opt_protocol.begin(), ::tolower);
1655
 
 
1656
 
    if (not opt_protocol.compare("mysql"))
1657
 
      use_drizzle_protocol=false;
1658
 
    else if (not opt_protocol.compare("drizzle"))
1659
 
      use_drizzle_protocol=true;
1660
 
    else
1661
 
    {
1662
 
      cout << _("Error: Unknown protocol") << " '" << opt_protocol << "'" << endl;
1663
 
      exit(-1);
1664
 
    }
1665
 
  }
1666
 
 
1667
 
  if (vm.count("port"))
1668
 
  {
1669
 
    opt_drizzle_port= vm["port"].as<uint32_t>();
1670
 
 
1671
 
    /* If the port number is > 65535 it is not a valid port
1672
 
       This also helps with potential data loss casting unsigned long to a
1673
 
       uint32_t. */
1674
 
    if (opt_drizzle_port > 65535)
1675
 
    {
1676
 
      printf(_("Error: Value of %" PRIu32 " supplied for port is not valid.\n"), opt_drizzle_port);
1677
 
      exit(-1);
1678
 
    }
1679
 
  }
1680
 
 
1681
 
  if (vm.count("password"))
1682
 
  {
1683
 
    if (!opt_password.empty())
1684
 
      opt_password.erase();
1685
 
    if (current_password == PASSWORD_SENTINEL)
1686
 
    {
1687
 
      opt_password= "";
1688
 
    }
1689
 
    else
1690
 
    {
1691
 
      opt_password= current_password;
1692
 
      tty_password= false;
1693
 
    }
1694
 
  }
1695
 
  else
1696
 
  {
1697
 
      tty_password= true;
1698
 
  }
1699
 
  
1700
 
 
1701
 
  if (!opt_verbose.empty())
1702
 
  {
1703
 
    verbose= opt_verbose.length();
1704
 
  }
1705
 
 
1706
 
  if (vm.count("batch"))
1707
 
  {
1708
 
    status.setBatch(1);
1709
 
    status.setAddToHistory(0);
1710
 
    if (opt_silent < 1)
1711
 
    {
1712
 
      opt_silent= 1;
1713
 
    }
1714
 
  }
1715
 
  if (vm.count("silent"))
1716
 
  {
1717
 
    opt_silent= 2;
1718
 
  }
1719
 
  
1720
 
  if (vm.count("help") || vm.count("version"))
1721
 
  {
1722
 
    printf(_("Drizzle client %s build %s, for %s-%s (%s) using readline %s\n"),
1723
 
           drizzle_version(), VERSION,
1724
 
           HOST_VENDOR, HOST_OS, HOST_CPU,
1725
 
           rl_library_version);
1726
 
    if (vm.count("version"))
1727
 
      exit(0);
1728
 
    printf(_("Copyright (C) 2008 Sun Microsystems\n"
1729
 
           "This software comes with ABSOLUTELY NO WARRANTY. "
1730
 
           "This is free software,\n"
1731
 
           "and you are welcome to modify and redistribute it "
1732
 
           "under the GPL license\n"));
1733
 
    printf(_("Usage: drizzle [OPTIONS] [schema]\n"));
1734
 
    cout << long_options;
1735
 
    exit(0);
1736
 
  }
1737
 
 
1738
 
 
1739
 
  if (process_options())
1740
 
  {
 
1370
  internal::load_defaults("drizzle",load_default_groups,&argc,&argv);
 
1371
  defaults_argv=argv;
 
1372
  if (get_options(argc, (char **) argv))
 
1373
  {
 
1374
    internal::free_defaults(defaults_argv);
 
1375
    internal::my_end();
1741
1376
    exit(1);
1742
1377
  }
1743
1378
 
1744
1379
  memset(&drizzle, 0, sizeof(drizzle));
1745
 
  if (sql_connect(current_host, current_db, current_user, opt_password))
 
1380
  if (sql_connect(current_host,current_db,current_user,opt_password,
 
1381
                  opt_silent))
1746
1382
  {
1747
1383
    quick= 1;          // Avoid history
1748
1384
    status.setExitStatus(1);
1753
1389
  if (execute_commands(&command_error) != false)
1754
1390
  {
1755
1391
    /* we've executed a command so exit before we go into readline mode */
 
1392
    internal::free_defaults(defaults_argv);
 
1393
    internal::my_end();
1756
1394
    exit(command_error);
1757
1395
  }
1758
1396
 
1761
1399
    status.setLineBuff(opt_max_input_line, stdin);
1762
1400
    if (status.getLineBuff() == NULL)
1763
1401
    {
 
1402
      internal::free_defaults(defaults_argv);
 
1403
      internal::my_end();
1764
1404
      exit(1);
1765
1405
    }
1766
1406
  }
1780
1420
  /* call the SIGWINCH handler to get the default term width */
1781
1421
  window_resize(0);
1782
1422
#endif
1783
 
  std::vector<char> output_buff;
1784
 
  output_buff.resize(512);
1785
 
 
1786
 
  snprintf(&output_buff[0], output_buff.size(), 
1787
 
           _("Welcome to the Drizzle client..  Commands end with %s or \\g."), 
1788
 
           delimiter);
1789
 
 
1790
 
  put_info(&output_buff[0], INFO_INFO, 0, 0);
 
1423
 
 
1424
  put_info(_("Welcome to the Drizzle client..  Commands end with ; or \\g."),
 
1425
           INFO_INFO,0,0);
1791
1426
 
1792
1427
  glob_buffer= new string();
1793
1428
  glob_buffer->reserve(512);
1794
1429
 
1795
 
  snprintf(&output_buff[0], output_buff.size(),
1796
 
          _("Your Drizzle connection id is %u\nConnection protocol: %s\nServer version: %s\n"),
 
1430
  char * output_buff= (char *)malloc(512);
 
1431
  memset(output_buff, '\0', 512);
 
1432
 
 
1433
  sprintf(output_buff,
 
1434
          _("Your Drizzle connection id is %u\nServer version: %s\n"),
1797
1435
          drizzle_con_thread_id(&con),
1798
 
          opt_protocol.c_str(),
1799
1436
          server_version_string(&con));
1800
 
  put_info(&output_buff[0], INFO_INFO, 0, 0);
1801
 
 
1802
 
 
1803
 
  initialize_readline((char *)current_prompt.c_str());
 
1437
  put_info(output_buff, INFO_INFO, 0, 0);
 
1438
 
 
1439
  initialize_readline(current_prompt);
1804
1440
  if (!status.getBatch() && !quick)
1805
1441
  {
1806
1442
    /* read-history from file, default ~/.drizzle_history*/
1844
1480
  if (opt_outfile)
1845
1481
    end_tee();
1846
1482
  drizzle_end(0);
1847
 
}
1848
1483
 
1849
 
  catch(exception &err)
1850
 
  {
1851
 
    cerr << _("Error:") << err.what() << endl;
1852
 
  }
1853
1484
  return(0);        // Keep compiler happy
1854
1485
}
1855
1486
 
1863
1494
    if (verbose)
1864
1495
      tee_fprintf(stdout, _("Writing history-file %s\n"),histfile);
1865
1496
    if (!write_history(histfile_tmp))
1866
 
      rename(histfile_tmp, histfile);
 
1497
      internal::my_rename(histfile_tmp, histfile, MYF(MY_WME));
1867
1498
  }
1868
1499
  delete status.getLineBuff();
1869
1500
  status.setLineBuff(0);
1870
1501
 
1871
1502
  if (sig >= 0)
1872
1503
    put_info(sig ? _("Aborted") : _("Bye"), INFO_RESULT,0,0);
1873
 
  delete glob_buffer;
1874
 
  delete processed_prompt;
1875
 
  opt_password.erase();
 
1504
  if (glob_buffer)
 
1505
    delete glob_buffer;
 
1506
  if (processed_prompt)
 
1507
    delete processed_prompt;
 
1508
  free(opt_password);
1876
1509
  free(histfile);
1877
1510
  free(histfile_tmp);
1878
 
  current_db.erase();
1879
 
  current_host.erase();
1880
 
  current_user.erase();
 
1511
  free(current_db);
 
1512
  free(current_host);
 
1513
  free(current_user);
1881
1514
  free(full_username);
1882
1515
  free(part_username);
1883
1516
  free(default_prompt);
1884
 
  current_prompt.erase();
 
1517
  free(current_prompt);
 
1518
  internal::free_defaults(defaults_argv);
 
1519
  internal::my_end();
1885
1520
  exit(status.getExitStatus());
1886
1521
}
1887
1522
 
1895
1530
void handle_sigint(int sig)
1896
1531
{
1897
1532
  char kill_buffer[40];
1898
 
  boost::scoped_ptr<drizzle_con_st> kill_drizzle(new drizzle_con_st);
 
1533
  drizzle_con_st kill_drizzle;
1899
1534
  drizzle_result_st res;
1900
1535
  drizzle_return_t ret;
1901
1536
 
1904
1539
    goto err;
1905
1540
  }
1906
1541
 
1907
 
  if (drizzle_con_add_tcp(&drizzle, kill_drizzle.get(), current_host.c_str(),
1908
 
    opt_drizzle_port, current_user.c_str(), opt_password.c_str(), NULL,
1909
 
    use_drizzle_protocol ? DRIZZLE_CON_EXPERIMENTAL : DRIZZLE_CON_MYSQL) == NULL)
 
1542
  if (drizzle_con_add_tcp(&drizzle, &kill_drizzle, current_host,
 
1543
                          opt_drizzle_port, current_user, opt_password, NULL,
 
1544
                          opt_mysql ? DRIZZLE_CON_MYSQL : DRIZZLE_CON_NONE) == NULL)
1910
1545
  {
1911
1546
    goto err;
1912
1547
  }
1915
1550
  sprintf(kill_buffer, "KILL /*!50000 QUERY */ %u",
1916
1551
          drizzle_con_thread_id(&con));
1917
1552
 
1918
 
  if (drizzle_query_str(kill_drizzle.get(), &res, kill_buffer, &ret) != NULL)
 
1553
  if (drizzle_query_str(&kill_drizzle, &res, kill_buffer, &ret) != NULL)
1919
1554
    drizzle_result_free(&res);
1920
1555
 
1921
 
  drizzle_con_free(kill_drizzle.get());
 
1556
  drizzle_con_free(&kill_drizzle);
1922
1557
  tee_fprintf(stdout, _("Query aborted by Ctrl+C\n"));
1923
1558
 
1924
1559
  interrupted_query= 1;
1940
1575
}
1941
1576
#endif
1942
1577
 
1943
 
 
1944
 
 
1945
 
static int process_options(void)
 
1578
static struct option my_long_options[] =
 
1579
{
 
1580
  {"help", '?', N_("Display this help and exit."), 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
 
1581
   0, 0, 0, 0, 0},
 
1582
  {"help", 'I', N_("Synonym for -?"), 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
 
1583
   0, 0, 0, 0, 0},
 
1584
  {"auto-rehash", OPT_AUTO_REHASH,
 
1585
   N_("Enable automatic rehashing. One doesn't need to use 'rehash' to get table and field completion, but startup and reconnecting may take a longer time. Disable with --disable-auto-rehash."),
 
1586
   (char**) &opt_rehash, (char**) &opt_rehash, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0,
 
1587
   0, 0},
 
1588
  {"no-auto-rehash", 'A',
 
1589
   N_("No automatic rehashing. One has to use 'rehash' to get table and field completion. This gives a quicker start of drizzle_st and disables rehashing on reconnect. WARNING: options deprecated; use --disable-auto-rehash instead."),
 
1590
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1591
  {"auto-vertical-output", OPT_AUTO_VERTICAL_OUTPUT,
 
1592
   N_("Automatically switch to vertical output mode if the result is wider than the terminal width."),
 
1593
   (char**) &auto_vertical_output, (char**) &auto_vertical_output, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1594
  {"batch", 'B',
 
1595
   N_("Don't use history file. Disable interactive behavior. (Enables --silent)"), 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1596
  {"column-type-info", OPT_COLUMN_TYPES, N_("Display column type information."),
 
1597
   (char**) &column_types_flag, (char**) &column_types_flag,
 
1598
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1599
  {"comments", 'c', N_("Preserve comments. Send comments to the server. The default is --skip-comments (discard comments), enable with --comments"),
 
1600
   (char**) &preserve_comments, (char**) &preserve_comments,
 
1601
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1602
  {"compress", 'C', N_("Use compression in server/client protocol."),
 
1603
   (char**) &opt_compress, (char**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
 
1604
   0, 0, 0},
 
1605
  {"database", 'D', N_("Database to use."), (char**) &current_db,
 
1606
   (char**) &current_db, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1607
  {"default-character-set", OPT_DEFAULT_CHARSET,
 
1608
   N_("(not used)"), 0,
 
1609
   0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1610
  {"delimiter", OPT_DELIMITER, N_("Delimiter to be used."), (char**) &delimiter_str,
 
1611
   (char**) &delimiter_str, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1612
  {"execute", 'e', N_("Execute command and quit. (Disables --force and history file)"), 0,
 
1613
   0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1614
  {"vertical", 'E', N_("Print the output of a query (rows) vertically."),
 
1615
   (char**) &vertical, (char**) &vertical, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
 
1616
   0},
 
1617
  {"force", 'f', N_("Continue even if we get an sql error."),
 
1618
   (char**) &ignore_errors, (char**) &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0,
 
1619
   0, 0, 0, 0},
 
1620
  {"named-commands", 'G',
 
1621
   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. Disable with --disable-named-commands. This option is disabled by default."),
 
1622
   (char**) &named_cmds, (char**) &named_cmds, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
 
1623
   0, 0},
 
1624
  {"no-named-commands", 'g',
 
1625
   N_("Named commands are disabled. Use \\* form only, or use named commands only in the beginning of a line ending with a semicolon (;) Since version 10.9 the client now starts with this option ENABLED by default! Disable with '-G'. Long format commands still work from the first line. WARNING: option deprecated; use --disable-named-commands instead."),
 
1626
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1627
  {"ignore-spaces", 'i', N_("Ignore space after function names."), 0, 0, 0,
 
1628
   GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1629
  {"local-infile", OPT_LOCAL_INFILE, N_("Enable/disable LOAD DATA LOCAL INFILE."),
 
1630
   (char**) &opt_local_infile,
 
1631
   (char**) &opt_local_infile, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
1632
  {"no-beep", 'b', N_("Turn off beep on error."), (char**) &opt_nobeep,
 
1633
   (char**) &opt_nobeep, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1634
  {"host", 'h', N_("Connect to host."), (char**) &current_host,
 
1635
   (char**) &current_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1636
  {"line-numbers", OPT_LINE_NUMBERS, N_("Write line numbers for errors."),
 
1637
   (char**) &line_numbers, (char**) &line_numbers, 0, GET_BOOL,
 
1638
   NO_ARG, 1, 0, 0, 0, 0, 0},
 
1639
  {"skip-line-numbers", 'L', N_("Don't write line number for errors. WARNING: -L is deprecated, use long version of this option instead."), 0, 0, 0, GET_NO_ARG,
 
1640
   NO_ARG, 0, 0, 0, 0, 0, 0},
 
1641
  {"unbuffered", 'n', N_("Flush buffer after each query."), (char**) &unbuffered,
 
1642
   (char**) &unbuffered, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1643
  {"column-names", OPT_COLUMN_NAMES, N_("Write column names in results."),
 
1644
   (char**) &column_names, (char**) &column_names, 0, GET_BOOL,
 
1645
   NO_ARG, 1, 0, 0, 0, 0, 0},
 
1646
  {"skip-column-names", 'N',
 
1647
   N_("Don't write column names in results. WARNING: -N is deprecated, use long version of this options instead."),
 
1648
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1649
  {"set-variable", 'O',
 
1650
   N_("Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value."),
 
1651
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1652
  {"sigint-ignore", OPT_SIGINT_IGNORE, N_("Ignore SIGINT (CTRL-C)"),
 
1653
   (char**) &opt_sigint_ignore,  (char**) &opt_sigint_ignore, 0, GET_BOOL,
 
1654
   NO_ARG, 0, 0, 0, 0, 0, 0},
 
1655
  {"one-database", 'o',
 
1656
   N_("Only update the default database. This is useful for skipping updates to other database in the update log."),
 
1657
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1658
  {"pager", OPT_PAGER,
 
1659
   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."),
 
1660
   0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
1661
  {"no-pager", OPT_NOPAGER,
 
1662
   N_("Disable pager and print to stdout. See interactive help (\\h) also. WARNING: option deprecated; use --disable-pager instead."),
 
1663
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1664
  {"password", 'P',
 
1665
   N_("Password to use when connecting to server. If password is not given it's asked from the tty."),
 
1666
   0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
1667
  {"port", 'p', N_("Port number to use for connection or 0 for default to, in order of preference, drizzle.cnf, $DRIZZLE_TCP_PORT, ")
 
1668
   N_("built-in default") " (" STRINGIFY_ARG(DRIZZLE_PORT) ").",
 
1669
   0, 0, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1670
  {"prompt", OPT_PROMPT, N_("Set the drizzle prompt to this value."),
 
1671
   (char**) &current_prompt, (char**) &current_prompt, 0, GET_STR_ALLOC,
 
1672
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1673
  {"quick", 'q',
 
1674
   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."),
 
1675
   (char**) &quick, (char**) &quick, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1676
  {"raw", 'r', N_("Write fields without conversion. Used with --batch."),
 
1677
   (char**) &opt_raw_data, (char**) &opt_raw_data, 0, GET_BOOL, NO_ARG, 0, 0, 0,
 
1678
   0, 0, 0},
 
1679
  {"reconnect", OPT_RECONNECT, N_("Reconnect if the connection is lost. Disable with --disable-reconnect. This option is enabled by default."),
 
1680
   (char**) &opt_reconnect, (char**) &opt_reconnect, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
 
1681
  {"shutdown", OPT_SHUTDOWN, N_("Shutdown the server."),
 
1682
   (char**) &opt_shutdown, (char**) &opt_shutdown, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1683
  {"silent", 's', N_("Be more silent. Print results with a tab as separator, each row on new line."), 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0,
 
1684
   0, 0},
 
1685
  {"table", 't', N_("Output in table format."), (char**) &output_tables,
 
1686
   (char**) &output_tables, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1687
  {"tee", OPT_TEE,
 
1688
   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."),
 
1689
   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1690
  {"no-tee", OPT_NOTEE, N_("Disable outfile. See interactive help (\\h) also. WARNING: option deprecated; use --disable-tee instead"), 0, 0, 0, GET_NO_ARG,
 
1691
   NO_ARG, 0, 0, 0, 0, 0, 0},
 
1692
  {"user", 'u', N_("User for login if not current user."), (char**) &current_user,
 
1693
   (char**) &current_user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
1694
  {"safe-updates", 'U', N_("Only allow UPDATE and DELETE that uses keys."),
 
1695
   (char**) &safe_updates, (char**) &safe_updates, 0, GET_BOOL, NO_ARG, 0, 0,
 
1696
   0, 0, 0, 0},
 
1697
  {"i-am-a-dummy", 'U', N_("Synonym for option --safe-updates, -U."),
 
1698
   (char**) &safe_updates, (char**) &safe_updates, 0, GET_BOOL, NO_ARG, 0, 0,
 
1699
   0, 0, 0, 0},
 
1700
  {"verbose", 'v', N_("Write more. (-v -v -v gives the table output format)."), 0,
 
1701
   0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1702
  {"version", 'V', N_("Output version information and exit."), 0, 0, 0,
 
1703
   GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1704
  {"wait", 'w', N_("Wait and retry if connection is down."), 0, 0, 0, GET_NO_ARG,
 
1705
   NO_ARG, 0, 0, 0, 0, 0, 0},
 
1706
  {"connect_timeout", OPT_CONNECT_TIMEOUT,
 
1707
   N_("Number of seconds before connection timeout."),
 
1708
   (char**) &opt_connect_timeout,
 
1709
   (char**) &opt_connect_timeout, 0, GET_UINT32, REQUIRED_ARG, 0, 0, 3600*12, 0,
 
1710
   0, 0},
 
1711
  {"max_input_line", OPT_MAX_INPUT_LINE,
 
1712
   N_("Max length of input line"),
 
1713
   (char**) &opt_max_input_line, (char**) &opt_max_input_line, 0,
 
1714
   GET_UINT32, REQUIRED_ARG, 16 *1024L*1024L, 4096,
 
1715
   (int64_t) 2*1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
 
1716
  {"select_limit", OPT_SELECT_LIMIT,
 
1717
   N_("Automatic limit for SELECT when using --safe-updates"),
 
1718
   (char**) &select_limit,
 
1719
   (char**) &select_limit, 0, GET_UINT32, REQUIRED_ARG, 1000L, 1, ULONG_MAX,
 
1720
   0, 1, 0},
 
1721
  {"max_join_size", OPT_MAX_JOIN_SIZE,
 
1722
   N_("Automatic limit for rows in a join when using --safe-updates"),
 
1723
   (char**) &max_join_size,
 
1724
   (char**) &max_join_size, 0, GET_UINT32, REQUIRED_ARG, 1000000L, 1, ULONG_MAX,
 
1725
   0, 1, 0},
 
1726
  {"secure-auth", OPT_SECURE_AUTH, N_("Refuse client connecting to server if it uses old (pre-4.1.1) protocol"), (char**) &opt_secure_auth,
 
1727
   (char**) &opt_secure_auth, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1728
  {"show-warnings", OPT_SHOW_WARNINGS, N_("Show warnings after every statement."),
 
1729
   (char**) &show_warnings, (char**) &show_warnings, 0, GET_BOOL, NO_ARG,
 
1730
   0, 0, 0, 0, 0, 0},
 
1731
  {"show-progress-size", OPT_SHOW_PROGRESS_SIZE, N_("Number of lines before each import progress report."),
 
1732
   (char**) &show_progress_size, (char**) &show_progress_size, 0, GET_UINT32, REQUIRED_ARG,
 
1733
   0, 0, 0, 0, 0, 0},
 
1734
  {"ping", OPT_PING, N_("Ping the server to check if it's alive."),
 
1735
   (char**) &opt_ping, (char**) &opt_ping, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
1736
  {"mysql", 'm', N_("Use MySQL Protocol."),
 
1737
   (char**) &opt_mysql, (char**) &opt_mysql, 0, GET_BOOL, NO_ARG, 1, 0, 0,
 
1738
   0, 0, 0},
 
1739
  { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
 
1740
};
 
1741
 
 
1742
 
 
1743
static void usage(int version)
 
1744
{
 
1745
  const char* readline= "readline";
 
1746
 
 
1747
  printf(_("%s  Ver %s Distrib %s, for %s-%s (%s) using %s %s\n"),
 
1748
         internal::my_progname, VER.c_str(), drizzle_version(),
 
1749
         HOST_VENDOR, HOST_OS, HOST_CPU,
 
1750
         readline, rl_library_version);
 
1751
 
 
1752
  if (version)
 
1753
    return;
 
1754
  printf(_("Copyright (C) 2008 Sun Microsystems\n"
 
1755
           "This software comes with ABSOLUTELY NO WARRANTY. "
 
1756
           "This is free software,\n"
 
1757
           "and you are welcome to modify and redistribute it "
 
1758
           "under the GPL license\n"));
 
1759
  printf(_("Usage: %s [OPTIONS] [database]\n"), internal::my_progname);
 
1760
  my_print_help(my_long_options);
 
1761
  internal::print_defaults("drizzle", load_default_groups);
 
1762
  my_print_variables(my_long_options);
 
1763
}
 
1764
 
 
1765
 
 
1766
static int get_one_option(int optid, const struct option *, char *argument)
 
1767
{
 
1768
  char *endchar= NULL;
 
1769
  uint64_t temp_drizzle_port= 0;
 
1770
 
 
1771
  switch(optid) {
 
1772
  case  OPT_DEFAULT_CHARSET:
 
1773
    default_charset_used= 1;
 
1774
    break;
 
1775
  case OPT_DELIMITER:
 
1776
    if (argument == disabled_my_option)
 
1777
    {
 
1778
      strcpy(delimiter, DEFAULT_DELIMITER);
 
1779
    }
 
1780
    else
 
1781
    {
 
1782
      /* Check that delimiter does not contain a backslash */
 
1783
      if (!strstr(argument, "\\"))
 
1784
      {
 
1785
        strncpy(delimiter, argument, sizeof(delimiter) - 1);
 
1786
      }
 
1787
      else
 
1788
      {
 
1789
        put_info(_("DELIMITER cannot contain a backslash character"),
 
1790
                 INFO_ERROR,0,0);
 
1791
        return false;
 
1792
      }
 
1793
    }
 
1794
    delimiter_length= (uint32_t)strlen(delimiter);
 
1795
    delimiter_str= delimiter;
 
1796
    break;
 
1797
  case OPT_TEE:
 
1798
    if (argument == disabled_my_option)
 
1799
    {
 
1800
      if (opt_outfile)
 
1801
        end_tee();
 
1802
    }
 
1803
    else
 
1804
      init_tee(argument);
 
1805
    break;
 
1806
  case OPT_NOTEE:
 
1807
    printf(_("WARNING: option deprecated; use --disable-tee instead.\n"));
 
1808
    if (opt_outfile)
 
1809
      end_tee();
 
1810
    break;
 
1811
  case OPT_PAGER:
 
1812
    if (argument == disabled_my_option)
 
1813
      opt_nopager= 1;
 
1814
    else
 
1815
    {
 
1816
      opt_nopager= 0;
 
1817
      if (argument && strlen(argument))
 
1818
      {
 
1819
        default_pager_set= 1;
 
1820
        strncpy(pager, argument, sizeof(pager) - 1);
 
1821
        strcpy(default_pager, pager);
 
1822
      }
 
1823
      else if (default_pager_set)
 
1824
        strcpy(pager, default_pager);
 
1825
      else
 
1826
        opt_nopager= 1;
 
1827
    }
 
1828
    break;
 
1829
  case OPT_NOPAGER:
 
1830
    printf(_("WARNING: option deprecated; use --disable-pager instead.\n"));
 
1831
    opt_nopager= 1;
 
1832
    break;
 
1833
  case OPT_SERVER_ARG:
 
1834
    printf(_("WARNING: --server-arg option not supported in this configuration.\n"));
 
1835
    break;
 
1836
  case 'A':
 
1837
    opt_rehash= 0;
 
1838
    break;
 
1839
  case 'N':
 
1840
    column_names= 0;
 
1841
    break;
 
1842
  case 'e':
 
1843
    status.setBatch(1);
 
1844
    status.setAddToHistory(1);
 
1845
    if (status.getLineBuff() == NULL)
 
1846
      status.setLineBuff(opt_max_input_line,NULL);
 
1847
    if (status.getLineBuff() == NULL)
 
1848
    {
 
1849
      internal::my_end();
 
1850
      exit(1);
 
1851
    }
 
1852
    status.getLineBuff()->addString(argument);
 
1853
    break;
 
1854
  case 'o':
 
1855
    if (argument == disabled_my_option)
 
1856
      one_database= 0;
 
1857
    else
 
1858
      one_database= skip_updates= 1;
 
1859
    break;
 
1860
  case 'p':
 
1861
    temp_drizzle_port= (uint64_t) strtoul(argument, &endchar, 10);
 
1862
    /* if there is an alpha character this is not a valid port */
 
1863
    if (strlen(endchar) != 0)
 
1864
    {
 
1865
      put_info(_("Non-integer value supplied for port.  If you are trying to enter a password please use --password instead."), INFO_ERROR, 0, 0);
 
1866
      return false;
 
1867
    }
 
1868
    /* If the port number is > 65535 it is not a valid port
 
1869
       This also helps with potential data loss casting unsigned long to a
 
1870
       uint32_t. */
 
1871
    if ((temp_drizzle_port == 0) || (temp_drizzle_port > 65535))
 
1872
    {
 
1873
      put_info(_("Value supplied for port is not valid."), INFO_ERROR, 0, 0);
 
1874
      return false;
 
1875
    }
 
1876
    else
 
1877
    {
 
1878
      opt_drizzle_port= (uint32_t) temp_drizzle_port;
 
1879
    }
 
1880
    break;
 
1881
  case 'P':
 
1882
    /* Don't require password */
 
1883
    if (argument == disabled_my_option)
 
1884
    {
 
1885
      argument= (char*) "";
 
1886
    }
 
1887
    if (argument)
 
1888
    {
 
1889
      char *start= argument;
 
1890
      free(opt_password);
 
1891
      opt_password= strdup(argument);
 
1892
      while (*argument)
 
1893
      {
 
1894
        /* Overwriting password with 'x' */
 
1895
        *argument++= 'x';
 
1896
      }
 
1897
      if (*start)
 
1898
      {
 
1899
        start[1]= 0;
 
1900
      }
 
1901
      tty_password= 0;
 
1902
    }
 
1903
    else
 
1904
    {
 
1905
      tty_password= 1;
 
1906
    }
 
1907
    break;
 
1908
  case 's':
 
1909
    if (argument == disabled_my_option)
 
1910
      opt_silent= 0;
 
1911
    else
 
1912
      opt_silent++;
 
1913
    break;
 
1914
  case 'v':
 
1915
    if (argument == disabled_my_option)
 
1916
      verbose= 0;
 
1917
    else
 
1918
      verbose++;
 
1919
    break;
 
1920
  case 'B':
 
1921
    status.setBatch(1);
 
1922
    status.setAddToHistory(0);
 
1923
    set_if_bigger(opt_silent,1);                         // more silent
 
1924
    break;
 
1925
  case 'V':
 
1926
    usage(1);
 
1927
    exit(0);
 
1928
  case 'I':
 
1929
  case '?':
 
1930
    usage(0);
 
1931
    exit(0);
 
1932
  }
 
1933
  return 0;
 
1934
}
 
1935
 
 
1936
 
 
1937
static int get_options(int argc, char **argv)
1946
1938
{
1947
1939
  char *tmp, *pagpoint;
1948
 
  
 
1940
  int ho_error;
1949
1941
 
1950
1942
  tmp= (char *) getenv("DRIZZLE_HOST");
1951
1943
  if (tmp)
1952
 
    current_host.assign(tmp);
 
1944
    current_host= strdup(tmp);
1953
1945
 
1954
1946
  pagpoint= getenv("PAGER");
1955
1947
  if (!((char*) (pagpoint)))
1956
1948
  {
1957
 
    pager.assign("stdout");
 
1949
    strcpy(pager, "stdout");
1958
1950
    opt_nopager= 1;
1959
1951
  }
1960
1952
  else
1961
 
  {
1962
 
    pager.assign(pagpoint);
1963
 
  }
1964
 
  default_pager.assign(pager);
 
1953
    strcpy(pager, pagpoint);
 
1954
  strcpy(default_pager, pager);
1965
1955
 
1966
 
  //
 
1956
  if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
 
1957
    exit(ho_error);
1967
1958
 
1968
1959
  if (status.getBatch()) /* disable pager and outfile in this case */
1969
1960
  {
1970
 
    default_pager.assign("stdout");
1971
 
    pager.assign("stdout");
 
1961
    strcpy(default_pager, "stdout");
 
1962
    strcpy(pager, "stdout");
1972
1963
    opt_nopager= 1;
1973
1964
    default_pager_set= 0;
1974
1965
    opt_outfile= 0;
1976
1967
    connect_flag= DRIZZLE_CAPABILITIES_NONE; /* Not in interactive mode */
1977
1968
  }
1978
1969
 
 
1970
  if (argc > 1)
 
1971
  {
 
1972
    usage(0);
 
1973
    exit(1);
 
1974
  }
 
1975
  if (argc == 1)
 
1976
  {
 
1977
    skip_updates= 0;
 
1978
    free(current_db);
 
1979
    current_db= strdup(*argv);
 
1980
  }
1979
1981
  if (tty_password)
1980
1982
    opt_password= client_get_tty_password(NULL);
 
1983
 
1981
1984
  return(0);
1982
1985
}
1983
1986
 
2010
2013
    }
2011
2014
    else
2012
2015
    {
2013
 
      string prompt(ml_comment
2014
 
                      ? "   /*> " 
2015
 
                      : glob_buffer->empty()
2016
 
                        ? construct_prompt()
2017
 
                        : not in_string
2018
 
                          ? "    -> "
2019
 
                          : in_string == '\''
2020
 
                            ? "    '> "
2021
 
                            : in_string == '`'
2022
 
                              ? "    `> "
2023
 
                              : "    \"> ");
 
2016
      const char *prompt= (const char*) (ml_comment ? "   /*> " :
 
2017
                                         (glob_buffer->empty())
 
2018
                                         ?  construct_prompt()
 
2019
                                         : !in_string ? "    -> " :
 
2020
                                         in_string == '\'' ?
 
2021
                                         "    '> " : (in_string == '`' ?
 
2022
                                                      "    `> " :
 
2023
                                                      "    \"> "));
2024
2024
      if (opt_outfile && glob_buffer->empty())
2025
2025
        fflush(OUTFILE);
2026
2026
 
2027
2027
      if (opt_outfile)
2028
 
        fputs(prompt.c_str(), OUTFILE);
2029
 
      line= readline(prompt.c_str());
 
2028
        fputs(prompt, OUTFILE);
 
2029
      line= readline(prompt);
2030
2030
      /*
2031
2031
        When Ctrl+d or Ctrl+z is pressed, the line may be NULL on some OS
2032
2032
        which may cause coredump.
2089
2089
  }
2090
2090
  else
2091
2091
  {
2092
 
    while (isspace(*name))
 
2092
    while (my_isspace(charset_info,*name))
2093
2093
      name++;
2094
2094
    /*
2095
2095
      If there is an \\g in the row or if the row has a delimiter but
2098
2098
    */
2099
2099
    if (strstr(name, "\\g") || (strstr(name, delimiter) &&
2100
2100
                                !(strlen(name) >= 9 &&
2101
 
                                  !strcmp(name, "delimiter"))))
 
2101
                                  !my_strnncoll(charset_info,
 
2102
                                                (unsigned char*) name, 9,
 
2103
                                                (const unsigned char*) "delimiter",
 
2104
                                                9))))
2102
2105
      return(NULL);
2103
2106
    if ((end=strcont(name," \t")))
2104
2107
    {
2105
2108
      len=(uint32_t) (end - name);
2106
 
      while (isspace(*end))
 
2109
      while (my_isspace(charset_info,*end))
2107
2110
        end++;
2108
2111
      if (!*end)
2109
2112
        end=0;          // no arguments to function
2115
2118
  for (uint32_t i= 0; commands[i].getName(); i++)
2116
2119
  {
2117
2120
    if (commands[i].func &&
2118
 
        ((name && !strncmp(name, commands[i].getName(), len)
2119
 
          && !commands[i].getName()[len] && (!end || (end && commands[i].getTakesParams()))) || (!name && commands[i].getCmdChar() == cmd_char)))
 
2121
        ((name && !my_strnncoll(charset_info,(const unsigned char*)name,len, (const unsigned char*)commands[i].getName(),len) && !commands[i].getName()[len] && (!end || (end && commands[i].getTakesParams()))) || (!name && commands[i].getCmdChar() == cmd_char)))
2120
2122
    {
2121
2123
      return(&commands[i]);
2122
2124
    }
2146
2148
    if (!preserve_comments)
2147
2149
    {
2148
2150
      // Skip spaces at the beggining of a statement
2149
 
      if (isspace(inchar) && (out == line) &&
 
2151
      if (my_isspace(charset_info,inchar) && (out == line) &&
2150
2152
          (buffer->empty()))
2151
2153
        continue;
2152
2154
    }
2153
2155
 
2154
2156
    // Accept multi-byte characters as-is
2155
 
    if (not drizzled::utf8::is_single(*pos))
 
2157
    int length;
 
2158
    if (use_mb(charset_info) &&
 
2159
        (length= my_ismbchar(charset_info, pos, end_of_line)))
2156
2160
    {
2157
 
      int length;
2158
 
      if ((length= drizzled::utf8::sequence_length(*pos)))
 
2161
      if (!*ml_comment || preserve_comments)
2159
2162
      {
2160
 
        if (!*ml_comment || preserve_comments)
2161
 
        {
2162
 
          while (length--)
2163
 
            *out++ = *pos++;
2164
 
          pos--;
2165
 
        }
2166
 
        else
2167
 
          pos+= length - 1;
2168
 
        continue;
 
2163
        while (length--)
 
2164
          *out++ = *pos++;
 
2165
        pos--;
2169
2166
      }
 
2167
      else
 
2168
        pos+= length - 1;
 
2169
      continue;
2170
2170
    }
2171
2171
    if (!*ml_comment && inchar == '\\' &&
2172
2172
        !(*in_string && (drizzle_con_status(&con) & DRIZZLE_CON_STATUS_NO_BACKSLASH_ESCAPES)))
2235
2235
    }
2236
2236
    else if (!*ml_comment && !*in_string &&
2237
2237
             (end_of_line - pos) >= 10 &&
2238
 
             !strncmp(pos, "delimiter ", 10))
 
2238
             !my_strnncoll(charset_info, (unsigned char*) pos, 10,
 
2239
                           (const unsigned char*) "delimiter ", 10))
2239
2240
    {
2240
2241
      // Flush previously accepted characters
2241
2242
      if (out != line)
2272
2273
 
2273
2274
      if (preserve_comments)
2274
2275
      {
2275
 
        while (isspace(*pos))
 
2276
        while (my_isspace(charset_info, *pos))
2276
2277
          *out++= *pos++;
2277
2278
      }
2278
2279
      // Flush previously accepted characters
2285
2286
      if (preserve_comments && ((*pos == '#') ||
2286
2287
                                ((*pos == '-') &&
2287
2288
                                 (pos[1] == '-') &&
2288
 
                                 isspace(pos[2]))))
 
2289
                                 my_isspace(charset_info, pos[2]))))
2289
2290
      {
2290
2291
        // Add trailing single line comments to this statement
2291
2292
        buffer->append(pos);
2312
2313
                 && (inchar == '#'
2313
2314
                     || (inchar == '-'
2314
2315
                         && pos[1] == '-'
2315
 
                         && isspace(pos[2])))))
 
2316
                         && my_isspace(charset_info,pos[2])))))
2316
2317
    {
2317
2318
      // Flush previously accepted characters
2318
2319
      if (out != line)
2378
2379
        *in_string= (char) inchar;
2379
2380
      if (!*ml_comment || preserve_comments)
2380
2381
      {
2381
 
        if (need_space && !isspace((char)inchar))
 
2382
        if (need_space && !my_isspace(charset_info, (char)inchar))
2382
2383
          *out++= ' ';
2383
2384
        need_space= 0;
2384
2385
        *out++= (char) inchar;
2389
2390
  {
2390
2391
    *out++='\n';
2391
2392
    uint32_t length=(uint32_t) (out-line);
2392
 
    if ((buffer->length() + length) > opt_max_input_line)
2393
 
    {
2394
 
      status.setExitStatus(1);
2395
 
      put_info(_("Not found a delimiter within max_input_line of input"), INFO_ERROR, 0, 0);
2396
 
      return 1;
2397
 
    }
2398
2393
    if ((!*ml_comment || preserve_comments))
2399
2394
      buffer->append(line, length);
2400
2395
  }
2584
2579
  drizzle_return_t ret;
2585
2580
  drizzle_result_st databases,tables,fields;
2586
2581
  drizzle_row_t database_row,table_row;
 
2582
  drizzle_column_st *sql_field;
2587
2583
  string tmp_str, tmp_str_lower;
2588
 
  std::string query;
2589
2584
 
2590
 
  if (status.getBatch() || quick || current_db.empty())
 
2585
  if (status.getBatch() || quick || !current_db)
2591
2586
    return;      // We don't need completion in batches
2592
2587
  if (!rehash)
2593
2588
    return;
2605
2600
  /* hash Drizzle functions (to be implemented) */
2606
2601
 
2607
2602
  /* hash all database names */
2608
 
  if (drizzle_query_str(&con, &databases, "select schema_name from information_schema.schemata", &ret) != NULL)
 
2603
  if (drizzle_query_str(&con, &databases, "show databases", &ret) != NULL)
2609
2604
  {
2610
2605
    if (ret == DRIZZLE_RETURN_OK)
2611
2606
    {
2625
2620
    drizzle_result_free(&databases);
2626
2621
  }
2627
2622
 
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)
 
2623
  /* hash all table names */
 
2624
  if (drizzle_query_str(&con, &tables, "show tables", &ret) != NULL)
2634
2625
  {
2635
 
    if (ret == DRIZZLE_RETURN_OK &&
2636
 
        drizzle_result_buffer(&fields) == DRIZZLE_RETURN_OK)
 
2626
    if (ret != DRIZZLE_RETURN_OK)
 
2627
    {
 
2628
      drizzle_result_free(&tables);
 
2629
      return;
 
2630
    }
 
2631
 
 
2632
    if (drizzle_result_buffer(&tables) != DRIZZLE_RETURN_OK)
 
2633
      put_info(drizzle_error(&drizzle),INFO_INFO,0,0);
 
2634
    else
2637
2635
    {
2638
2636
      if (drizzle_result_row_count(&tables) > 0 && !opt_silent && write_info)
2639
2637
      {
2643
2641
                      "You can turn off this feature to get a quicker "
2644
2642
                      "startup with -A\n\n"));
2645
2643
      }
2646
 
 
2647
 
      std::string table_name;
2648
 
      while ((table_row=drizzle_row_next(&fields)))
 
2644
      while ((table_row=drizzle_row_next(&tables)))
2649
2645
      {
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
2646
        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);
 
2647
        tmp_str_lower= lower_string(tmp_str);
 
2648
        completion_map[tmp_str_lower]= tmp_str;
 
2649
      }
 
2650
    }
 
2651
  }
 
2652
  else
 
2653
    return;
 
2654
 
 
2655
  /* hash all field names, both with the table prefix and without it */
 
2656
  if (drizzle_result_row_count(&tables) == 0)
 
2657
  {
 
2658
    drizzle_result_free(&tables);
 
2659
    return;
 
2660
  }
 
2661
 
 
2662
  drizzle_row_seek(&tables, 0);
 
2663
 
 
2664
  while ((table_row=drizzle_row_next(&tables)))
 
2665
  {
 
2666
    string query;
 
2667
 
 
2668
    query.append("show fields in '");
 
2669
    query.append(table_row[0]);
 
2670
    query.append("'");
 
2671
    
 
2672
    if (drizzle_query(&con, &fields, query.c_str(), query.length(),
 
2673
                      &ret) != NULL)
 
2674
    {
 
2675
      if (ret == DRIZZLE_RETURN_OK &&
 
2676
          drizzle_result_buffer(&fields) == DRIZZLE_RETURN_OK)
 
2677
      {
 
2678
        while ((sql_field=drizzle_column_next(&fields)))
 
2679
        {
 
2680
          tmp_str=table_row[0];
 
2681
          tmp_str.append(".");
 
2682
          tmp_str.append(drizzle_column_name(sql_field));
 
2683
          tmp_str_lower= lower_string(tmp_str);
 
2684
          completion_map[tmp_str_lower]= tmp_str;
 
2685
 
 
2686
          tmp_str=drizzle_column_name(sql_field);
 
2687
          tmp_str_lower= lower_string(tmp_str);
 
2688
          completion_map[tmp_str_lower]= tmp_str;
 
2689
        }
 
2690
      }
 
2691
      drizzle_result_free(&fields);
 
2692
    }
 
2693
  }
 
2694
  drizzle_result_free(&tables);
2670
2695
  completion_iter= completion_map.begin();
2671
2696
}
2672
2697
 
2692
2717
  drizzle_return_t ret;
2693
2718
  drizzle_result_st res;
2694
2719
 
2695
 
  current_db.erase();
2696
 
  current_db= "";
 
2720
  free(current_db);
 
2721
  current_db= NULL;
2697
2722
  /* In case of error below current_db will be NULL */
2698
2723
  if (drizzle_query_str(&con, &res, "SELECT DATABASE()", &ret) != NULL)
2699
2724
  {
2702
2727
    {
2703
2728
      drizzle_row_t row= drizzle_row_next(&res);
2704
2729
      if (row[0])
2705
 
        current_db.assign(row[0]);
 
2730
        current_db= strdup(row[0]);
2706
2731
      drizzle_result_free(&res);
2707
2732
    }
2708
2733
  }
2712
2737
 The different commands
2713
2738
***************************************************************************/
2714
2739
 
2715
 
int drizzleclient_real_query_for_lazy(const char *buf, size_t length,
 
2740
int drizzleclient_real_query_for_lazy(const char *buf, int length,
2716
2741
                                      drizzle_result_st *result,
2717
2742
                                      uint32_t *error_code)
2718
2743
{
2751
2776
    return 0;
2752
2777
 
2753
2778
  if (drizzle_con_error(&con)[0])
2754
 
  {
2755
 
    int ret= put_error(&con, result);
2756
 
    drizzle_result_free(result);
2757
 
    return ret;
2758
 
  }
 
2779
    return put_error(&con, result);
2759
2780
  return 0;
2760
2781
}
2761
2782
 
2762
2783
static int
2763
2784
com_help(string *buffer, const char *)
2764
2785
{
2765
 
  int i, j;
 
2786
  register int i, j;
2766
2787
  char buff[32], *end;
2767
 
  std::vector<char> output_buff;
2768
 
  output_buff.resize(512);
2769
2788
 
2770
2789
  put_info(_("List of all Drizzle commands:"), INFO_INFO,0,0);
2771
2790
  if (!named_cmds)
2772
 
  {
2773
 
    snprintf(&output_buff[0], output_buff.size(),
2774
 
             _("Note that all text commands must be first on line and end with '%s' or \\g"),
2775
 
             delimiter);
2776
 
    put_info(&output_buff[0], INFO_INFO, 0, 0);
2777
 
  }
 
2791
    put_info(_("Note that all text commands must be first on line and end with ';'"),INFO_INFO,0,0);
2778
2792
  for (i = 0; commands[i].getName(); i++)
2779
2793
  {
2780
2794
    end= strcpy(buff, commands[i].getName());
2811
2825
com_go(string *buffer, const char *)
2812
2826
{
2813
2827
  char          buff[200]; /* about 110 chars used so far */
 
2828
  char          time_buff[52+3+1]; /* time max + space&parens + NUL */
2814
2829
  drizzle_result_st result;
2815
2830
  drizzle_return_t ret;
2816
 
  uint32_t      warnings= 0;
2817
 
  boost::posix_time::ptime timer;
 
2831
  uint32_t      timer, warnings= 0;
2818
2832
  uint32_t      error= 0;
2819
2833
  uint32_t      error_code= 0;
2820
2834
  int           err= 0;
2883
2897
        goto end;
2884
2898
    }
2885
2899
 
2886
 
    string time_buff("");
2887
2900
    if (verbose >= 3 || !opt_silent)
2888
2901
      drizzle_end_timer(timer,time_buff);
 
2902
    else
 
2903
      time_buff[0]= '\0';
2889
2904
 
2890
2905
    /* Every branch must truncate  buff . */
2891
2906
    if (drizzle_result_column_count(&result) > 0)
2936
2951
      if (warnings != 1)
2937
2952
        *pos++= 's';
2938
2953
    }
2939
 
    strcpy(pos, time_buff.c_str());
 
2954
    strcpy(pos, time_buff);
2940
2955
    put_info(buff,INFO_RESULT,0,0);
2941
2956
    if (strcmp(drizzle_result_info(&result), ""))
2942
2957
      put_info(drizzle_result_info(&result),INFO_RESULT,0,0);
2987
3002
{
2988
3003
  if (!opt_nopager)
2989
3004
  {
2990
 
    if (!(PAGER= popen(pager.c_str(), "w")))
 
3005
    if (!(PAGER= popen(pager, "w")))
2991
3006
    {
2992
 
      tee_fprintf(stdout,_( "popen() failed! defaulting PAGER to stdout!\n"));
 
3007
      tee_fprintf(stdout, "popen() failed! defaulting PAGER to stdout!\n");
2993
3008
      PAGER= stdout;
2994
3009
    }
2995
3010
  }
3011
3026
    end_tee();
3012
3027
  if (!(new_outfile= fopen(file_name, "a")))
3013
3028
  {
3014
 
    tee_fprintf(stdout, _("Error logging to file '%s'\n"), file_name);
 
3029
    tee_fprintf(stdout, "Error logging to file '%s'\n", file_name);
3015
3030
    return;
3016
3031
  }
3017
3032
  OUTFILE = new_outfile;
3018
 
  outfile.assign(file_name);
3019
 
  tee_fprintf(stdout, _("Logging to file '%s'\n"), file_name);
 
3033
  strncpy(outfile, file_name, FN_REFLEN-1);
 
3034
  tee_fprintf(stdout, "Logging to file '%s'\n", file_name);
3020
3035
  opt_outfile= 1;
3021
3036
 
3022
3037
  return;
3100
3115
 
3101
3116
  while ((field = drizzle_column_next(result)))
3102
3117
  {
3103
 
    tee_fprintf(PAGER, _("Field %3u:  `%s`\n"
 
3118
    tee_fprintf(PAGER, "Field %3u:  `%s`\n"
3104
3119
                "Catalog:    `%s`\n"
3105
 
                "Schema:     `%s`\n"
 
3120
                "Database:   `%s`\n"
3106
3121
                "Table:      `%s`\n"
3107
3122
                "Org_table:  `%s`\n"
3108
 
                "Type:       UTF-8\n"
 
3123
                "Type:       %s\n"
3109
3124
                "Collation:  %s (%u)\n"
3110
3125
                "Length:     %lu\n"
3111
3126
                "Max_length: %lu\n"
3112
3127
                "Decimals:   %u\n"
3113
 
                "Flags:      %s\n\n"),
 
3128
                "Flags:      %s\n\n",
3114
3129
                ++i,
3115
3130
                drizzle_column_name(field), drizzle_column_catalog(field),
3116
3131
                drizzle_column_db(field), drizzle_column_table(field),
3117
3132
                drizzle_column_orig_table(field),
3118
3133
                fieldtype2str(drizzle_column_type(field)),
 
3134
                get_charset_name(drizzle_column_charset(field)),
3119
3135
                drizzle_column_charset(field), drizzle_column_size(field),
3120
3136
                drizzle_column_max_size(field), drizzle_column_decimals(field),
3121
3137
                fieldflags2str(drizzle_column_flags(field)));
3123
3139
  tee_puts("", PAGER);
3124
3140
}
3125
3141
 
 
3142
 
3126
3143
static void
3127
3144
print_table_data(drizzle_result_st *result)
3128
3145
{
3129
3146
  drizzle_row_t cur;
3130
3147
  drizzle_return_t ret;
3131
3148
  drizzle_column_st *field;
3132
 
  std::vector<bool> num_flag;
3133
 
  std::vector<bool> boolean_flag;
3134
 
  std::vector<bool> ansi_boolean_flag;
 
3149
  bool *num_flag;
3135
3150
  string separator;
3136
3151
 
3137
3152
  separator.reserve(256);
3138
3153
 
3139
 
  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));
 
3154
  num_flag=(bool*) malloc(sizeof(bool)*drizzle_result_column_count(result));
3142
3155
  if (column_types_flag)
3143
3156
  {
3144
3157
    print_field_types(result);
3158
3171
      /* Check if the max_byte value is really the maximum in terms
3159
3172
         of visual length since multibyte characters can affect the
3160
3173
         length of the separator. */
3161
 
      length= drizzled::utf8::char_length(drizzle_column_name(field));
 
3174
      length= charset_info->cset->numcells(charset_info,
 
3175
                                           drizzle_column_name(field),
 
3176
                                           drizzle_column_name(field) +
 
3177
                                           name_length);
3162
3178
 
3163
3179
      if (name_length == drizzle_column_max_size(field))
3164
3180
      {
3181
3197
      // Room for "NULL"
3182
3198
      length=4;
3183
3199
    }
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
3200
    drizzle_column_set_max_size(field, length);
3193
3201
 
3194
3202
    for (x=0; x< (length+2); x++)
3204
3212
    for (uint32_t off=0; (field = drizzle_column_next(result)) ; off++)
3205
3213
    {
3206
3214
      uint32_t name_length= (uint32_t) strlen(drizzle_column_name(field));
3207
 
      uint32_t numcells= drizzled::utf8::char_length(drizzle_column_name(field));
 
3215
      uint32_t numcells= charset_info->cset->numcells(charset_info,
 
3216
                                                  drizzle_column_name(field),
 
3217
                                                  drizzle_column_name(field) +
 
3218
                                                  name_length);
3208
3219
      uint32_t display_length= drizzle_column_max_size(field) + name_length -
3209
3220
                               numcells;
3210
3221
      tee_fprintf(PAGER, " %-*s |",(int) min(display_length,
3212
3223
                  drizzle_column_name(field));
3213
3224
      num_flag[off]= ((drizzle_column_type(field) <= DRIZZLE_COLUMN_TYPE_LONGLONG) ||
3214
3225
                      (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
3226
    }
3234
3227
    (void) tee_fputs("\n", PAGER);
3235
3228
    tee_puts((char*) separator.c_str(), PAGER);
3268
3261
        buffer= "NULL";
3269
3262
        data_length= 4;
3270
3263
      }
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
3264
      else
3301
3265
      {
3302
3266
        buffer= cur[off];
3314
3278
        We need to find how much screen real-estate we will occupy to know how
3315
3279
        many extra padding-characters we should send with the printing function.
3316
3280
      */
3317
 
      visible_length= drizzled::utf8::char_length(buffer);
 
3281
      visible_length= charset_info->cset->numcells(charset_info, buffer, buffer + data_length);
3318
3282
      extra_padding= data_length - visible_length;
3319
3283
 
3320
3284
      if (field_max_length > MAX_COLUMN_LENGTH)
3334
3298
      drizzle_row_free(result, cur);
3335
3299
  }
3336
3300
  tee_puts(separator.c_str(), PAGER);
 
3301
  free(num_flag);
3337
3302
}
3338
3303
 
3339
3304
/**
3541
3506
    else for (const char *end=pos+length ; pos != end ; pos++)
3542
3507
    {
3543
3508
      int l;
3544
 
      if ((l = drizzled::utf8::sequence_length(*pos)))
 
3509
      if (use_mb(charset_info) &&
 
3510
          (l = my_ismbchar(charset_info, pos, end)))
3545
3511
      {
3546
3512
        while (l--)
3547
3513
          tee_putc(*pos++, PAGER);
3570
3536
  drizzle_return_t ret;
3571
3537
  drizzle_column_st *field;
3572
3538
  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++)
 
3539
 
 
3540
  if (opt_silent < 2 && column_names)
3581
3541
  {
3582
 
    if (opt_silent < 2 && column_names)
 
3542
    int first=0;
 
3543
    while ((field = drizzle_column_next(result)))
3583
3544
    {
3584
3545
      if (first++)
3585
3546
        (void) tee_fputs("\t", PAGER);
3586
3547
      (void) tee_fputs(drizzle_column_name(field), PAGER);
3587
3548
    }
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
3549
    (void) tee_fputs("\n", PAGER);
3609
3550
  }
3610
3551
  while (1)
3625
3566
      break;
3626
3567
 
3627
3568
    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++)
 
3569
    safe_put_field(cur[0],lengths[0]);
 
3570
    for (uint32_t off=1 ; off < drizzle_result_column_count(result); off++)
3630
3571
    {
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
 
      }
 
3572
      (void) tee_fputs("\t", PAGER);
 
3573
      safe_put_field(cur[off], lengths[off]);
3662
3574
    }
3663
3575
    (void) tee_fputs("\n", PAGER);
3664
3576
    if (quick)
3674
3586
 
3675
3587
  if (status.getBatch())
3676
3588
    return 0;
3677
 
  while (isspace(*line))
 
3589
  while (my_isspace(charset_info,*line))
3678
3590
    line++;
3679
 
  if (!(param =strchr(line, ' '))) // if outfile wasn't given, use the default
 
3591
  if (!(param = strchr(line, ' '))) // if outfile wasn't given, use the default
3680
3592
  {
3681
 
    if (outfile.empty())
 
3593
    if (!strlen(outfile))
3682
3594
    {
3683
 
      printf(_("No previous outfile available, you must give a filename!\n"));
 
3595
      printf("No previous outfile available, you must give a filename!\n");
3684
3596
      return 0;
3685
3597
    }
3686
3598
    else if (opt_outfile)
3687
3599
    {
3688
 
      tee_fprintf(stdout, _("Currently logging to file '%s'\n"), outfile.c_str());
 
3600
      tee_fprintf(stdout, "Currently logging to file '%s'\n", outfile);
3689
3601
      return 0;
3690
3602
    }
3691
3603
    else
3692
 
      param= outfile.c_str();      //resume using the old outfile
 
3604
      param = outfile;      //resume using the old outfile
3693
3605
  }
3694
3606
 
3695
 
  /* @TODO: Replace this with string methods */
3696
3607
  /* eliminate the spaces before the parameters */
3697
 
  while (isspace(*param))
 
3608
  while (my_isspace(charset_info,*param))
3698
3609
    param++;
3699
3610
  strncpy(file_name, param, sizeof(file_name) - 1);
3700
3611
  end= file_name + strlen(file_name);
3701
3612
  /* remove end space from command line */
3702
 
  while (end > file_name && (isspace(end[-1]) ||
3703
 
                             iscntrl(end[-1])))
 
3613
  while (end > file_name && (my_isspace(charset_info,end[-1]) ||
 
3614
                             my_iscntrl(charset_info,end[-1])))
3704
3615
    end--;
3705
3616
  end[0]= 0;
3706
3617
  if (end == file_name)
3707
3618
  {
3708
 
    printf(_("No outfile specified!\n"));
 
3619
    printf("No outfile specified!\n");
3709
3620
    return 0;
3710
3621
  }
3711
3622
  init_tee(file_name);
3718
3629
{
3719
3630
  if (opt_outfile)
3720
3631
    end_tee();
3721
 
  tee_fprintf(stdout, _("Outfile disabled.\n"));
 
3632
  tee_fprintf(stdout, "Outfile disabled.\n");
3722
3633
  return 0;
3723
3634
}
3724
3635
 
3729
3640
static int
3730
3641
com_pager(string *, const char *line)
3731
3642
{
 
3643
  char pager_name[FN_REFLEN], *end;
3732
3644
  const char *param;
3733
3645
 
3734
3646
  if (status.getBatch())
3735
3647
    return 0;
3736
3648
  /* Skip spaces in front of the pager command */
3737
 
  while (isspace(*line))
 
3649
  while (my_isspace(charset_info, *line))
3738
3650
    line++;
3739
3651
  /* Skip the pager command */
3740
3652
  param= strchr(line, ' ');
3741
3653
  /* Skip the spaces between the command and the argument */
3742
 
  while (param && isspace(*param))
 
3654
  while (param && my_isspace(charset_info, *param))
3743
3655
    param++;
3744
 
  if (!param || (*param == '\0')) // if pager was not given, use the default
 
3656
  if (!param || !strlen(param)) // if pager was not given, use the default
3745
3657
  {
3746
3658
    if (!default_pager_set)
3747
3659
    {
3748
 
      tee_fprintf(stdout, _("Default pager wasn't set, using stdout.\n"));
 
3660
      tee_fprintf(stdout, "Default pager wasn't set, using stdout.\n");
3749
3661
      opt_nopager=1;
3750
 
      pager.assign("stdout");
 
3662
      strcpy(pager, "stdout");
3751
3663
      PAGER= stdout;
3752
3664
      return 0;
3753
3665
    }
3754
 
    pager.assign(default_pager);
 
3666
    strcpy(pager, default_pager);
3755
3667
  }
3756
3668
  else
3757
3669
  {
3758
 
    string pager_name(param);
3759
 
    string::iterator end= pager_name.end();
3760
 
    while (end > pager_name.begin() &&
3761
 
           (isspace(*(end-1)) || iscntrl(*(end-1))))
3762
 
      --end;
3763
 
    pager_name.erase(end, pager_name.end());
3764
 
    pager.assign(pager_name);
3765
 
    default_pager.assign(pager_name);
 
3670
    end= strncpy(pager_name, param, sizeof(pager_name)-1);
 
3671
    end+= strlen(pager_name);
 
3672
    while (end > pager_name && (my_isspace(charset_info,end[-1]) ||
 
3673
                                my_iscntrl(charset_info,end[-1])))
 
3674
      end--;
 
3675
    end[0]=0;
 
3676
    strcpy(pager, pager_name);
 
3677
    strcpy(default_pager, pager_name);
3766
3678
  }
3767
3679
  opt_nopager=0;
3768
 
  tee_fprintf(stdout, _("PAGER set to '%s'\n"), pager.c_str());
 
3680
  tee_fprintf(stdout, "PAGER set to '%s'\n", pager);
3769
3681
  return 0;
3770
3682
}
3771
3683
 
3773
3685
static int
3774
3686
com_nopager(string *, const char *)
3775
3687
{
3776
 
  pager.assign("stdout");
 
3688
  strcpy(pager, "stdout");
3777
3689
  opt_nopager=1;
3778
3690
  PAGER= stdout;
3779
 
  tee_fprintf(stdout, _("PAGER set to stdout\n"));
 
3691
  tee_fprintf(stdout, "PAGER set to stdout\n");
3780
3692
  return 0;
3781
3693
}
3782
3694
 
3834
3746
    tmp= get_arg(buff, 0);
3835
3747
    if (tmp && *tmp)
3836
3748
    {
3837
 
      current_db.erase();
3838
 
      current_db.assign(tmp);
 
3749
      free(current_db);
 
3750
      current_db= strdup(tmp);
3839
3751
      tmp= get_arg(buff, 1);
3840
3752
      if (tmp)
3841
3753
      {
3842
 
        current_host.erase();
 
3754
        free(current_host);
3843
3755
        current_host=strdup(tmp);
3844
3756
      }
3845
3757
    }
3854
3766
  }
3855
3767
  else
3856
3768
    opt_rehash= 0;
3857
 
  error=sql_connect(current_host, current_db, current_user, opt_password);
 
3769
  error=sql_connect(current_host,current_db,current_user,opt_password,0);
3858
3770
  opt_rehash= save_rehash;
3859
3771
 
3860
3772
  if (connected)
3861
3773
  {
3862
 
    sprintf(buff, _("Connection id:    %u"), drizzle_con_thread_id(&con));
 
3774
    sprintf(buff,"Connection id:    %u",drizzle_con_thread_id(&con));
3863
3775
    put_info(buff,INFO_INFO,0,0);
3864
 
    sprintf(buff, _("Current schema: %.128s\n"),
3865
 
            !current_db.empty() ? current_db.c_str() : _("*** NONE ***"));
 
3776
    sprintf(buff,"Current database: %.128s\n",
 
3777
            current_db ? current_db : "*** NONE ***");
3866
3778
    put_info(buff,INFO_INFO,0,0);
3867
3779
  }
3868
3780
  return error;
3879
3791
  FILE *sql_file;
3880
3792
 
3881
3793
  /* Skip space from file name */
3882
 
  while (isspace(*line))
 
3794
  while (my_isspace(charset_info,*line))
3883
3795
    line++;
3884
3796
  if (!(param = strchr(line, ' ')))    // Skip command name
3885
 
    return put_info(_("Usage: \\. <filename> | source <filename>"),
 
3797
    return put_info("Usage: \\. <filename> | source <filename>",
3886
3798
                    INFO_ERROR, 0,0);
3887
 
  while (isspace(*param))
 
3799
  while (my_isspace(charset_info,*param))
3888
3800
    param++;
3889
3801
  end= strncpy(source_name,param,sizeof(source_name)-1);
3890
3802
  end+= strlen(source_name);
3891
 
  while (end > source_name && (isspace(end[-1]) ||
3892
 
                               iscntrl(end[-1])))
 
3803
  while (end > source_name && (my_isspace(charset_info,end[-1]) ||
 
3804
                               my_iscntrl(charset_info,end[-1])))
3893
3805
    end--;
3894
3806
  end[0]=0;
3895
 
 
 
3807
  internal::unpack_filename(source_name,source_name);
3896
3808
  /* open file name */
3897
3809
  if (!(sql_file = fopen(source_name, "r")))
3898
3810
  {
3899
3811
    char buff[FN_REFLEN+60];
3900
 
    sprintf(buff, _("Failed to open file '%s', error: %d"), source_name,errno);
 
3812
    sprintf(buff,"Failed to open file '%s', error: %d", source_name,errno);
3901
3813
    return put_info(buff, INFO_ERROR, 0 ,0);
3902
3814
  }
3903
3815
 
3905
3817
  if (line_buff == NULL)
3906
3818
  {
3907
3819
    fclose(sql_file);
3908
 
    return put_info(_("Can't initialize LineBuffer"), INFO_ERROR, 0, 0);
 
3820
    return put_info("Can't initialize LineBuffer", INFO_ERROR, 0, 0);
3909
3821
  }
3910
3822
 
3911
3823
  /* Save old status */
3941
3853
 
3942
3854
  if (!tmp || !*tmp)
3943
3855
  {
3944
 
    put_info(_("DELIMITER must be followed by a 'delimiter' character or string"),
 
3856
    put_info("DELIMITER must be followed by a 'delimiter' character or string",
3945
3857
             INFO_ERROR, 0, 0);
3946
3858
    return 0;
3947
3859
  }
3949
3861
  {
3950
3862
    if (strstr(tmp, "\\"))
3951
3863
    {
3952
 
      put_info(_("DELIMITER cannot contain a backslash character"),
 
3864
      put_info("DELIMITER cannot contain a backslash character",
3953
3865
               INFO_ERROR, 0, 0);
3954
3866
      return 0;
3955
3867
    }
3974
3886
  tmp= get_arg(buff, 0);
3975
3887
  if (!tmp || !*tmp)
3976
3888
  {
3977
 
    put_info(_("USE must be followed by a schema name"), INFO_ERROR, 0, 0);
 
3889
    put_info("USE must be followed by a database name", INFO_ERROR, 0, 0);
3978
3890
    return 0;
3979
3891
  }
3980
3892
  /*
3984
3896
  */
3985
3897
  get_current_db();
3986
3898
 
3987
 
  if (current_db.empty() || strcmp(current_db.c_str(),tmp))
 
3899
  if (!current_db || strcmp(current_db,tmp))
3988
3900
  {
3989
3901
    if (one_database)
3990
3902
    {
4036
3948
      else
4037
3949
        drizzle_result_free(&result);
4038
3950
    }
4039
 
    current_db.erase();
4040
 
    current_db.assign(tmp);
 
3951
    free(current_db);
 
3952
    current_db= strdup(tmp);
4041
3953
    if (select_db > 1)
4042
3954
      build_completion_hash(opt_rehash, 1);
4043
3955
  }
4044
3956
 
4045
 
  put_info(_("Schema changed"),INFO_INFO, 0, 0);
 
3957
  put_info("Database changed",INFO_INFO, 0, 0);
4046
3958
  return 0;
4047
3959
}
4048
3960
 
4049
 
static int com_shutdown(string *, const char *)
4050
 
{
4051
 
  drizzle_result_st result;
4052
 
  drizzle_return_t ret;
4053
 
 
4054
 
  if (verbose)
4055
 
  {
4056
 
    printf(_("shutting down drizzled"));
4057
 
    if (opt_drizzle_port > 0)
4058
 
      printf(_(" on port %d"), opt_drizzle_port);
4059
 
    printf("... ");
4060
 
  }
4061
 
 
4062
 
  if (drizzle_shutdown(&con, &result, DRIZZLE_SHUTDOWN_DEFAULT,
4063
 
                       &ret) == NULL || ret != DRIZZLE_RETURN_OK)
4064
 
  {
4065
 
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
4066
 
    {
4067
 
      fprintf(stderr, _("shutdown failed; error: '%s'"),
4068
 
              drizzle_result_error(&result));
4069
 
      drizzle_result_free(&result);
4070
 
    }
4071
 
    else
4072
 
    {
4073
 
      fprintf(stderr, _("shutdown failed; error: '%s'"),
4074
 
              drizzle_con_error(&con));
4075
 
    }
4076
 
    return false;
4077
 
  }
4078
 
 
4079
 
  drizzle_result_free(&result);
4080
 
 
4081
 
  if (verbose)
4082
 
    printf(_("done\n"));
4083
 
 
4084
 
  return false;
4085
 
}
4086
 
 
4087
3961
static int
4088
3962
com_warnings(string *, const char *)
4089
3963
{
4090
3964
  show_warnings = 1;
4091
 
  put_info(_("Show warnings enabled."),INFO_INFO, 0, 0);
 
3965
  put_info("Show warnings enabled.",INFO_INFO, 0, 0);
4092
3966
  return 0;
4093
3967
}
4094
3968
 
4096
3970
com_nowarnings(string *, const char *)
4097
3971
{
4098
3972
  show_warnings = 0;
4099
 
  put_info(_("Show warnings disabled."),INFO_INFO, 0, 0);
 
3973
  put_info("Show warnings disabled.",INFO_INFO, 0, 0);
4100
3974
  return 0;
4101
3975
}
4102
3976
 
4126
4000
  else
4127
4001
  {
4128
4002
    /* skip leading white spaces */
4129
 
    while (isspace(*ptr))
 
4003
    while (my_isspace(charset_info, *ptr))
4130
4004
      ptr++;
4131
4005
    if (*ptr == '\\') // short command was used
4132
4006
      ptr+= 2;
4133
4007
    else
4134
 
      while (*ptr &&!isspace(*ptr)) // skip command
 
4008
      while (*ptr &&!my_isspace(charset_info, *ptr)) // skip command
4135
4009
        ptr++;
4136
4010
  }
4137
4011
  if (!*ptr)
4138
4012
    return NULL;
4139
 
  while (isspace(*ptr))
 
4013
  while (my_isspace(charset_info, *ptr))
4140
4014
    ptr++;
4141
4015
  if (*ptr == '\'' || *ptr == '\"' || *ptr == '`')
4142
4016
  {
4163
4037
 
4164
4038
 
4165
4039
static int
4166
 
sql_connect(const string &host, const string &database, const string &user, const string &password)
 
4040
sql_connect(char *host,char *database,char *user,char *password,
 
4041
                 uint32_t silent)
4167
4042
{
4168
4043
  drizzle_return_t ret;
 
4044
 
4169
4045
  if (connected)
4170
4046
  {
4171
4047
    connected= 0;
4173
4049
    drizzle_free(&drizzle);
4174
4050
  }
4175
4051
  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
 
  if (drizzle_con_add_tcp(&drizzle, &con, (char *)host.c_str(),
4184
 
    opt_drizzle_port, (char *)user.c_str(),
4185
 
    (char *)password.c_str(), (char *)database.c_str(),
4186
 
    options) == NULL)
 
4052
  if (drizzle_con_add_tcp(&drizzle, &con, host, opt_drizzle_port, user,
 
4053
                          password, database, opt_mysql ? DRIZZLE_CON_MYSQL : DRIZZLE_CON_NONE) == NULL)
4187
4054
  {
4188
4055
    (void) put_error(&con, NULL);
4189
4056
    (void) fflush(stdout);
4212
4079
*/
4213
4080
  if ((ret= drizzle_con_connect(&con)) != DRIZZLE_RETURN_OK)
4214
4081
  {
4215
 
 
4216
 
    if (opt_silent < 2)
 
4082
    if (!silent || (ret != DRIZZLE_RETURN_GETADDRINFO &&
 
4083
                    ret != DRIZZLE_RETURN_COULD_NOT_CONNECT))
4217
4084
    {
4218
4085
      (void) put_error(&con, NULL);
4219
4086
      (void) fflush(stdout);
4223
4090
  }
4224
4091
  connected=1;
4225
4092
 
4226
 
  ServerDetect server_detect(&con);
4227
 
  server_type= server_detect.getServerType();
4228
 
 
4229
4093
  build_completion_hash(opt_rehash, 1);
4230
4094
  return 0;
4231
4095
}
4242
4106
  drizzle_return_t ret;
4243
4107
 
4244
4108
  tee_puts("--------------", stdout);
4245
 
  printf(_("Drizzle client %s build %s, for %s-%s (%s) using readline %s\n"),
4246
 
         drizzle_version(), VERSION,
4247
 
         HOST_VENDOR, HOST_OS, HOST_CPU,
4248
 
         rl_library_version);
4249
 
 
 
4109
  usage(1);          /* Print version */
4250
4110
  if (connected)
4251
4111
  {
4252
 
    tee_fprintf(stdout, _("\nConnection id:\t\t%lu\n"),drizzle_con_thread_id(&con));
 
4112
    tee_fprintf(stdout, "\nConnection id:\t\t%lu\n",drizzle_con_thread_id(&con));
4253
4113
    /*
4254
4114
      Don't remove "limit 1",
4255
4115
      it is protection againts SQL_SELECT_LIMIT=0
4261
4121
      drizzle_row_t cur=drizzle_row_next(&result);
4262
4122
      if (cur)
4263
4123
      {
4264
 
        tee_fprintf(stdout, _("Current schema:\t%s\n"), cur[0] ? cur[0] : "");
4265
 
        tee_fprintf(stdout, _("Current user:\t\t%s\n"), cur[1]);
 
4124
        tee_fprintf(stdout, "Current database:\t%s\n", cur[0] ? cur[0] : "");
 
4125
        tee_fprintf(stdout, "Current user:\t\t%s\n", cur[1]);
4266
4126
      }
4267
4127
      drizzle_result_free(&result);
4268
4128
    }
4269
4129
    else if (ret == DRIZZLE_RETURN_ERROR_CODE)
4270
4130
      drizzle_result_free(&result);
4271
 
    tee_puts(_("SSL:\t\t\tNot in use"), stdout);
 
4131
    tee_puts("SSL:\t\t\tNot in use", stdout);
4272
4132
  }
4273
4133
  else
4274
4134
  {
4275
4135
    vidattr(A_BOLD);
4276
 
    tee_fprintf(stdout, _("\nNo connection\n"));
 
4136
    tee_fprintf(stdout, "\nNo connection\n");
4277
4137
    vidattr(A_NORMAL);
4278
4138
    return 0;
4279
4139
  }
4280
4140
  if (skip_updates)
4281
4141
  {
4282
4142
    vidattr(A_BOLD);
4283
 
    tee_fprintf(stdout, _("\nAll updates ignored to this schema\n"));
 
4143
    tee_fprintf(stdout, "\nAll updates ignored to this database\n");
4284
4144
    vidattr(A_NORMAL);
4285
4145
  }
4286
 
  tee_fprintf(stdout, _("Current pager:\t\t%s\n"), pager.c_str());
4287
 
  tee_fprintf(stdout, _("Using outfile:\t\t'%s'\n"), opt_outfile ? outfile.c_str() : "");
4288
 
  tee_fprintf(stdout, _("Using delimiter:\t%s\n"), delimiter);
4289
 
  tee_fprintf(stdout, _("Server version:\t\t%s\n"), server_version_string(&con));
4290
 
  tee_fprintf(stdout, _("Protocol:\t\t%s\n"), opt_protocol.c_str());
4291
 
  tee_fprintf(stdout, _("Protocol version:\t%d\n"), drizzle_con_protocol_version(&con));
4292
 
  tee_fprintf(stdout, _("Connection:\t\t%s\n"), drizzle_con_host(&con));
 
4146
  tee_fprintf(stdout, "Current pager:\t\t%s\n", pager);
 
4147
  tee_fprintf(stdout, "Using outfile:\t\t'%s'\n", opt_outfile ? outfile : "");
 
4148
  tee_fprintf(stdout, "Using delimiter:\t%s\n", delimiter);
 
4149
  tee_fprintf(stdout, "Server version:\t\t%s\n", server_version_string(&con));
 
4150
  tee_fprintf(stdout, "Protocol version:\t%d\n", drizzle_con_protocol_version(&con));
 
4151
  tee_fprintf(stdout, "Connection:\t\t%s\n", drizzle_con_host(&con));
4293
4152
/* XXX need to save this from result
4294
4153
  if ((id= drizzleclient_insert_id(&drizzle)))
4295
4154
    tee_fprintf(stdout, "Insert id:\t\t%s\n", internal::llstr(id, buff));
4296
4155
*/
4297
4156
 
4298
4157
  if (drizzle_con_uds(&con))
4299
 
    tee_fprintf(stdout, _("UNIX socket:\t\t%s\n"), drizzle_con_uds(&con));
 
4158
    tee_fprintf(stdout, "UNIX socket:\t\t%s\n", drizzle_con_uds(&con));
4300
4159
  else
4301
 
    tee_fprintf(stdout, _("TCP port:\t\t%d\n"), drizzle_con_port(&con));
 
4160
    tee_fprintf(stdout, "TCP port:\t\t%d\n", drizzle_con_port(&con));
4302
4161
 
4303
4162
  if (safe_updates)
4304
4163
  {
4305
4164
    vidattr(A_BOLD);
4306
 
    tee_fprintf(stdout, _("\nNote that you are running in safe_update_mode:\n"));
 
4165
    tee_fprintf(stdout, "\nNote that you are running in safe_update_mode:\n");
4307
4166
    vidattr(A_NORMAL);
4308
 
    tee_fprintf(stdout, _("\
 
4167
    tee_fprintf(stdout, "\
4309
4168
UPDATEs and DELETEs that don't use a key in the WHERE clause are not allowed.\n\
4310
4169
(One can force an UPDATE/DELETE by adding LIMIT # at the end of the command.)\n \
4311
4170
SELECT has an automatic 'LIMIT %lu' if LIMIT is not used.\n             \
4312
 
Max number of examined row combination in a join is set to: %lu\n\n"),
 
4171
Max number of examined row combination in a join is set to: %lu\n\n",
4313
4172
                select_limit, max_join_size);
4314
4173
  }
4315
4174
  tee_puts("--------------\n", stdout);
4367
4226
    if (info_type == INFO_ERROR)
4368
4227
    {
4369
4228
      (void) fflush(file);
4370
 
      fprintf(file,_("ERROR"));
 
4229
      fprintf(file,"ERROR");
4371
4230
      if (error)
4372
4231
      {
4373
4232
        if (sqlstate)
4410
4269
      if (error)
4411
4270
      {
4412
4271
        if (sqlstate)
4413
 
          (void) tee_fprintf(file, _("ERROR %d (%s): "), error, sqlstate);
 
4272
          (void) tee_fprintf(file, "ERROR %d (%s): ", error, sqlstate);
4414
4273
        else
4415
 
          (void) tee_fprintf(file, _("ERROR %d: "), error);
 
4274
          (void) tee_fprintf(file, "ERROR %d: ", error);
4416
4275
      }
4417
4276
      else
4418
 
        tee_puts(_("ERROR: "), file);
 
4277
        tee_puts("ERROR: ", file);
4419
4278
    }
4420
4279
    else
4421
4280
      vidattr(A_BOLD);
4454
4313
{
4455
4314
  const char *start=  buffer->c_str();
4456
4315
  const char *end= start + (buffer->length());
4457
 
  while (start < end && !isgraph(end[-1]))
 
4316
  while (start < end && !my_isgraph(charset_info,end[-1]))
4458
4317
    end--;
4459
4318
  uint32_t pos_to_truncate= (end-start);
4460
4319
  if (buffer->length() > pos_to_truncate)
4506
4365
}
4507
4366
 
4508
4367
#include <sys/times.h>
 
4368
#ifdef _SC_CLK_TCK        // For mit-pthreads
 
4369
#undef CLOCKS_PER_SEC
 
4370
#define CLOCKS_PER_SEC (sysconf(_SC_CLK_TCK))
 
4371
#endif
4509
4372
 
4510
 
static boost::posix_time::ptime start_timer(void)
 
4373
static uint32_t start_timer(void)
4511
4374
{
4512
 
  return boost::posix_time::microsec_clock::universal_time();
 
4375
  struct tms tms_tmp;
 
4376
  return times(&tms_tmp);
4513
4377
}
4514
4378
 
4515
 
static void nice_time(boost::posix_time::time_duration duration, string &buff)
 
4379
 
 
4380
/**
 
4381
   Write as many as 52+1 bytes to buff, in the form of a legible
 
4382
   duration of time.
 
4383
 
 
4384
   len("4294967296 days, 23 hours, 59 minutes, 60.00 seconds")  ->  52
 
4385
*/
 
4386
static void nice_time(double sec,char *buff,bool part_second)
4516
4387
{
 
4388
  uint32_t tmp;
4517
4389
  ostringstream tmp_buff_str;
4518
4390
 
4519
 
  if (duration.hours() > 0)
4520
 
  {
4521
 
    tmp_buff_str << duration.hours();
4522
 
    if (duration.hours() > 1)
4523
 
      tmp_buff_str << _(" hours ");
4524
 
    else
4525
 
      tmp_buff_str << _(" hour ");
4526
 
  }
4527
 
  if (duration.hours() > 0 || duration.minutes() > 0)
4528
 
  {
4529
 
    tmp_buff_str << duration.minutes() << _(" min ");
4530
 
  }
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(")");
 
4391
  if (sec >= 3600.0*24)
 
4392
  {
 
4393
    tmp=(uint32_t) floor(sec/(3600.0*24));
 
4394
    sec-= 3600.0*24*tmp;
 
4395
    tmp_buff_str << tmp;
 
4396
 
 
4397
    if (tmp > 1)
 
4398
      tmp_buff_str << " days ";
 
4399
    else
 
4400
      tmp_buff_str << " day ";
 
4401
 
 
4402
  }
 
4403
  if (sec >= 3600.0)
 
4404
  {
 
4405
    tmp=(uint32_t) floor(sec/3600.0);
 
4406
    sec-=3600.0*tmp;
 
4407
    tmp_buff_str << tmp;
 
4408
 
 
4409
    if (tmp > 1)
 
4410
      tmp_buff_str << " hours ";
 
4411
    else
 
4412
      tmp_buff_str << " hour ";
 
4413
  }
 
4414
  if (sec >= 60.0)
 
4415
  {
 
4416
    tmp=(uint32_t) floor(sec/60.0);
 
4417
    sec-=60.0*tmp;
 
4418
    tmp_buff_str << tmp << " min ";
 
4419
  }
 
4420
  if (part_second)
 
4421
    tmp_buff_str.precision(2);
 
4422
  else
 
4423
    tmp_buff_str.precision(0);
 
4424
  tmp_buff_str << sec << " sec";
 
4425
  strcpy(buff, tmp_buff_str.str().c_str());
 
4426
}
 
4427
 
 
4428
 
 
4429
static void end_timer(uint32_t start_time,char *buff)
 
4430
{
 
4431
  nice_time((double) (start_timer() - start_time) /
 
4432
            CLOCKS_PER_SEC,buff,1);
 
4433
}
 
4434
 
 
4435
 
 
4436
static void drizzle_end_timer(uint32_t start_time,char *buff)
 
4437
{
 
4438
  buff[0]=' ';
 
4439
  buff[1]='(';
 
4440
  end_timer(start_time,buff+2);
 
4441
  strcpy(strchr(buff, '\0'),")");
4558
4442
}
4559
4443
 
4560
4444
static const char * construct_prompt()
4568
4452
  struct tm *t = localtime(&lclock);
4569
4453
 
4570
4454
  /* parse thru the settings for the prompt */
4571
 
  string::iterator c= current_prompt.begin();
4572
 
  while (c != current_prompt.end())
 
4455
  for (char *c= current_prompt; *c; (void)*c++)
4573
4456
  {
4574
4457
    if (*c != PROMPT_CHAR)
4575
4458
    {
4576
 
      processed_prompt->push_back(*c);
 
4459
      processed_prompt->append(c, 1);
4577
4460
    }
4578
4461
    else
4579
4462
    {
4584
4467
      switch (*++c) {
4585
4468
      case '\0':
4586
4469
        // stop it from going beyond if ends with %
4587
 
        --c;
 
4470
        c--;
4588
4471
        break;
4589
4472
      case 'c':
4590
4473
        add_int_to_prompt(++prompt_counter);
4596
4479
          processed_prompt->append("not_connected");
4597
4480
        break;
4598
4481
      case 'd':
4599
 
        processed_prompt->append(not current_db.empty() ? current_db : "(none)");
 
4482
        processed_prompt->append(current_db ? current_db : "(none)");
4600
4483
        break;
4601
4484
      case 'h':
4602
4485
      {
4603
 
        const char *prompt= connected ? drizzle_con_host(&con) : "not_connected";
 
4486
        const char *prompt;
 
4487
        prompt= connected ? drizzle_con_host(&con) : "not_connected";
4604
4488
        if (strstr(prompt, "Localhost"))
4605
4489
          processed_prompt->append("localhost");
4606
4490
        else
4632
4516
        if (!full_username)
4633
4517
          init_username();
4634
4518
        processed_prompt->append(full_username ? full_username :
4635
 
                                 (!current_user.empty() ?  current_user : "(unknown)"));
 
4519
                                 (current_user ?  current_user : "(unknown)"));
4636
4520
        break;
4637
4521
      case 'u':
4638
4522
        if (!full_username)
4639
4523
          init_username();
4640
4524
        processed_prompt->append(part_username ? part_username :
4641
 
                                 (!current_user.empty() ?  current_user : _("(unknown)")));
 
4525
                                 (current_user ?  current_user : "(unknown)"));
4642
4526
        break;
4643
4527
      case PROMPT_CHAR:
4644
4528
        {
4693
4577
        add_int_to_prompt(t->tm_sec);
4694
4578
        break;
4695
4579
      case 'w':
4696
 
        processed_prompt->append(get_day_name(t->tm_wday));
 
4580
        processed_prompt->append(day_names[t->tm_wday]);
4697
4581
        break;
4698
4582
      case 'P':
4699
4583
        processed_prompt->append(t->tm_hour < 12 ? "am" : "pm");
4702
4586
        add_int_to_prompt(t->tm_mon+1);
4703
4587
        break;
4704
4588
      case 'O':
4705
 
        processed_prompt->append(get_month_name(t->tm_mon));
 
4589
        processed_prompt->append(month_names[t->tm_mon]);
4706
4590
        break;
4707
4591
      case '\'':
4708
4592
        processed_prompt->append("'");
4720
4604
        processed_prompt->append(delimiter_str);
4721
4605
        break;
4722
4606
      default:
4723
 
        processed_prompt->push_back(*c);
 
4607
        processed_prompt->append(c, 1);
4724
4608
      }
4725
4609
    }
4726
 
    ++c;
4727
4610
  }
4728
4611
  return processed_prompt->c_str();
4729
4612
}
4758
4641
{
4759
4642
  const char *ptr=strchr(line, ' ');
4760
4643
  if (ptr == NULL)
4761
 
    tee_fprintf(stdout, _("Returning to default PROMPT of %s\n"),
 
4644
    tee_fprintf(stdout, "Returning to default PROMPT of %s\n",
4762
4645
                default_prompt);
4763
4646
  prompt_counter = 0;
4764
4647
  char * tmpptr= strdup(ptr ? ptr+1 : default_prompt);
4765
4648
  if (tmpptr == NULL)
4766
 
    tee_fprintf(stdout, _("Memory allocation error. Not changing prompt\n"));
 
4649
    tee_fprintf(stdout, "Memory allocation error. Not changing prompt\n");
4767
4650
  else
4768
4651
  {
4769
 
    current_prompt.erase();
 
4652
    free(current_prompt);
4770
4653
    current_prompt= tmpptr;
4771
 
    tee_fprintf(stdout, _("PROMPT set to '%s'\n"), current_prompt.c_str());
 
4654
    tee_fprintf(stdout, "PROMPT set to '%s'\n", current_prompt);
4772
4655
  }
4773
4656
  return 0;
4774
4657
}
4779
4662
    if there isn't anything found.
4780
4663
*/
4781
4664
 
4782
 
static const char * strcont(const char *str, const char *set)
 
4665
static const char * strcont(register const char *str, register const char *set)
4783
4666
{
4784
 
  const char * start = (const char *) set;
 
4667
  register const char * start = (const char *) set;
4785
4668
 
4786
4669
  while (*str)
4787
4670
  {