~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzle.cc

  • Committer: Brian Aker
  • Date: 2010-05-18 22:31:57 UTC
  • mto: This revision was merged to the branch mainline in revision 1540.
  • Revision ID: brian@gaz-20100518223157-k0i4yxv6t03yrwyk
JoinCache rename.

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 "client/get_password.h"
41
 
 
42
 
#if TIME_WITH_SYS_TIME
43
 
# include <sys/time.h>
44
 
# include <time.h>
45
 
#else
46
 
# if HAVE_SYS_TIME_H
47
 
#  include <sys/time.h>
48
 
# else
49
 
#  include <time.h>
50
 
# endif
51
 
#endif
52
 
 
53
 
#include <cerrno>
 
36
#include "client_priv.h"
54
37
#include <string>
55
38
#include <drizzled/gettext.h>
56
39
#include <iostream>
57
 
#include <fstream>
58
40
#include <map>
59
41
#include <algorithm>
60
42
#include <limits.h>
61
43
#include <cassert>
 
44
#include "drizzled/charset_info.h"
62
45
#include <stdarg.h>
63
46
#include <math.h>
64
 
#include <memory>
65
47
#include "client/linebuffer.h"
66
48
#include <signal.h>
67
49
#include <sys/ioctl.h>
68
50
#include <drizzled/configmake.h>
69
 
#include "drizzled/utf8/utf8.h"
70
 
#include <cstdlib>
 
51
#include "drizzled/charset.h"
71
52
 
72
53
#if defined(HAVE_CURSES_H) && defined(HAVE_TERM_H)
73
54
#include <curses.h>
158
139
#undef vidattr
159
140
#define vidattr(A) {}      // Can't get this to work
160
141
#endif
161
 
#include <boost/program_options.hpp>
162
 
#include <boost/scoped_ptr.hpp>
163
 
#include "drizzled/program_options/config_file.h"
164
142
 
 
143
using namespace drizzled;
165
144
using namespace std;
166
 
namespace po=boost::program_options;
167
 
namespace dpo=drizzled::program_options;
168
145
 
 
146
const string VER("14.14");
169
147
/* Don't try to make a nice table if the data is too big */
170
148
const uint32_t MAX_COLUMN_LENGTH= 1024;
171
149
 
173
151
const int MAX_SERVER_VERSION_LENGTH= 128;
174
152
 
175
153
#define PROMPT_CHAR '\\'
 
154
#define DEFAULT_DELIMITER ";"
176
155
 
177
156
class Status
178
157
{
180
159
 
181
160
  Status(int in_exit_status, 
182
161
         uint32_t in_query_start_line,
183
 
         char *in_file_name,
 
162
         char *in_file_name,
184
163
         LineBuffer *in_line_buff,
185
 
         bool in_batch,
186
 
         bool in_add_to_history)
 
164
         bool in_batch,
 
165
         bool in_add_to_history)
187
166
    :
188
167
    exit_status(in_exit_status),
189
168
    query_start_line(in_query_start_line),
193
172
    add_to_history(in_add_to_history)
194
173
    {}
195
174
 
196
 
  Status() :
197
 
    exit_status(0),
198
 
    query_start_line(0),
199
 
    file_name(NULL),
200
 
    line_buff(NULL),
201
 
    batch(false),        
202
 
    add_to_history(false)
203
 
  {}
 
175
  Status()
 
176
    :
 
177
    exit_status(),
 
178
    query_start_line(),
 
179
    file_name(),
 
180
    line_buff(),
 
181
    batch(),        
 
182
    add_to_history()
 
183
    {}
204
184
  
205
185
  int getExitStatus() const
206
186
  {
280
260
static map<string, string> completion_map;
281
261
static string completion_string;
282
262
 
 
263
static char **defaults_argv;
283
264
 
284
265
enum enum_info_type { INFO_INFO,INFO_ERROR,INFO_RESULT};
285
266
typedef enum enum_info_type INFO_TYPE;
290
271
  connected= false, opt_raw_data= false, unbuffered= false,
291
272
  output_tables= false, opt_rehash= true, skip_updates= false,
292
273
  safe_updates= false, one_database= false,
293
 
  opt_shutdown= false, opt_ping= false,
 
274
  opt_compress= false, opt_shutdown= false, opt_ping= false,
294
275
  vertical= false, line_numbers= true, column_names= true,
295
276
  opt_nopager= true, opt_outfile= false, named_cmds= false,
296
 
  opt_nobeep= false, opt_reconnect= true,
297
 
  opt_secure_auth= false,
 
277
  tty_password= false, opt_nobeep= false, opt_reconnect= true,
 
278
  default_charset_used= false, opt_secure_auth= false,
298
279
  default_pager_set= false, opt_sigint_ignore= false,
299
280
  auto_vertical_output= false,
300
281
  show_warnings= false, executing_query= false, interrupted_query= false,
301
 
  use_drizzle_protocol= false, opt_local_infile;
302
 
static uint32_t show_progress_size= 0;
 
282
  opt_mysql= false;
 
283
static uint32_t  show_progress_size= 0;
303
284
static bool column_types_flag;
304
285
static bool preserve_comments= false;
305
 
static uint32_t opt_max_input_line;
306
 
static uint32_t opt_drizzle_port= 0;
307
 
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;
308
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;
309
291
static char *histfile;
310
292
static char *histfile_tmp;
311
293
static string *glob_buffer;
316
298
static uint32_t select_limit;
317
299
static uint32_t max_join_size;
318
300
static uint32_t opt_connect_timeout= 0;
319
 
std::string current_db,
320
 
  delimiter_str,  
321
 
  current_host,
322
 
  current_prompt,
323
 
  current_user,
324
 
  opt_verbose,
325
 
  current_password,
326
 
  opt_password,
327
 
  opt_protocol;
328
301
// TODO: Need to i18n these
329
302
static const char *day_names[]= {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
330
303
static const char *month_names[]= {"Jan","Feb","Mar","Apr","May","Jun","Jul",
331
304
                                  "Aug","Sep","Oct","Nov","Dec"};
332
 
/* @TODO: Remove this */
333
 
#define FN_REFLEN 512
334
 
 
335
 
static string default_pager("");
336
 
static string pager("");
337
 
static string outfile("");
 
305
static char default_pager[FN_REFLEN];
 
306
static char pager[FN_REFLEN], outfile[FN_REFLEN];
338
307
static FILE *PAGER, *OUTFILE;
339
308
static uint32_t prompt_counter;
340
 
static char *delimiter= NULL;
 
309
static char delimiter[16]= DEFAULT_DELIMITER;
341
310
static uint32_t delimiter_length= 1;
342
311
unsigned short terminal_width= 80;
343
312
 
344
 
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,
345
316
                                      drizzle_result_st *result,
346
317
                                      uint32_t *error_code);
347
318
int drizzleclient_store_result_for_lazy(drizzle_result_st *result);
353
324
void tee_putc(int c, FILE *file);
354
325
static void tee_print_sized_data(const char *, unsigned int, unsigned int, bool);
355
326
/* The names of functions that actually do the manipulation. */
356
 
static int process_options(void);
 
327
static int get_options(int argc,char **argv);
357
328
static int com_quit(string *str,const char*),
358
329
  com_go(string *str,const char*), com_ego(string *str,const char*),
359
330
  com_print(string *str,const char*),
360
331
  com_help(string *str,const char*), com_clear(string *str,const char*),
361
332
  com_connect(string *str,const char*), com_status(string *str,const char*),
362
333
  com_use(string *str,const char*), com_source(string *str, const char*),
363
 
  com_shutdown(string *str,const char*),
364
334
  com_rehash(string *str, const char*), com_tee(string *str, const char*),
365
335
  com_notee(string *str, const char*),
366
336
  com_prompt(string *str, const char*), com_delimiter(string *str, const char*),
368
338
  com_nopager(string *str, const char*), com_pager(string *str, const char*);
369
339
 
370
340
static int read_and_execute(bool interactive);
371
 
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,
372
342
                       uint32_t silent);
373
343
static const char *server_version_string(drizzle_con_st *con);
374
344
static int put_info(const char *str,INFO_TYPE info,uint32_t error,
492
462
    N_("Set outfile [to_outfile]. Append everything into given outfile.") ),
493
463
  Commands( "use",    'u', com_use,    1,
494
464
    N_("Use another database. Takes database name as argument.") ),
495
 
  Commands( "shutdown",    'u', com_shutdown,    1,
496
 
    N_("Shutdown the instance you are connected too.") ),
497
465
  Commands( "warnings", 'W', com_warnings,  0,
498
466
    N_("Show warnings after every statement.") ),
499
467
  Commands( "nowarning", 'w', com_nowarnings, 0,
529
497
  Commands( "AUTO_INCREMENT", 0, 0, 0, ""),
530
498
  Commands( "AVG", 0, 0, 0, ""),
531
499
  Commands( "AVG_ROW_LENGTH", 0, 0, 0, ""),
 
500
  Commands( "BACKUP", 0, 0, 0, ""),
 
501
  Commands( "BDB", 0, 0, 0, ""),
532
502
  Commands( "BEFORE", 0, 0, 0, ""),
533
503
  Commands( "BEGIN", 0, 0, 0, ""),
 
504
  Commands( "BERKELEYDB", 0, 0, 0, ""),
534
505
  Commands( "BETWEEN", 0, 0, 0, ""),
535
506
  Commands( "BIGINT", 0, 0, 0, ""),
536
507
  Commands( "BINARY", 0, 0, 0, ""),
 
508
  Commands( "BINLOG", 0, 0, 0, ""),
537
509
  Commands( "BIT", 0, 0, 0, ""),
538
510
  Commands( "BLOB", 0, 0, 0, ""),
539
511
  Commands( "BOOL", 0, 0, 0, ""),
552
524
  Commands( "CHANGED", 0, 0, 0, ""),
553
525
  Commands( "CHAR", 0, 0, 0, ""),
554
526
  Commands( "CHARACTER", 0, 0, 0, ""),
 
527
  Commands( "CHARSET", 0, 0, 0, ""),
555
528
  Commands( "CHECK", 0, 0, 0, ""),
556
529
  Commands( "CHECKSUM", 0, 0, 0, ""),
 
530
  Commands( "CIPHER", 0, 0, 0, ""),
557
531
  Commands( "CLIENT", 0, 0, 0, ""),
558
532
  Commands( "CLOSE", 0, 0, 0, ""),
 
533
  Commands( "CODE", 0, 0, 0, ""),
559
534
  Commands( "COLLATE", 0, 0, 0, ""),
560
535
  Commands( "COLLATION", 0, 0, 0, ""),
561
536
  Commands( "COLUMN", 0, 0, 0, ""),
597
572
  Commands( "DEFAULT", 0, 0, 0, ""),
598
573
  Commands( "DEFINER", 0, 0, 0, ""),
599
574
  Commands( "DELAYED", 0, 0, 0, ""),
 
575
  Commands( "DELAY_KEY_WRITE", 0, 0, 0, ""),
600
576
  Commands( "DELETE", 0, 0, 0, ""),
601
577
  Commands( "DESC", 0, 0, 0, ""),
602
578
  Commands( "DESCRIBE", 0, 0, 0, ""),
 
579
  Commands( "DES_KEY_FILE", 0, 0, 0, ""),
603
580
  Commands( "DETERMINISTIC", 0, 0, 0, ""),
 
581
  Commands( "DIRECTORY", 0, 0, 0, ""),
604
582
  Commands( "DISABLE", 0, 0, 0, ""),
605
583
  Commands( "DISCARD", 0, 0, 0, ""),
606
584
  Commands( "DISTINCT", 0, 0, 0, ""),
607
585
  Commands( "DISTINCTROW", 0, 0, 0, ""),
608
586
  Commands( "DIV", 0, 0, 0, ""),
 
587
  Commands( "DO", 0, 0, 0, ""),
609
588
  Commands( "DOUBLE", 0, 0, 0, ""),
610
589
  Commands( "DROP", 0, 0, 0, ""),
 
590
  Commands( "DUAL", 0, 0, 0, ""),
611
591
  Commands( "DUMPFILE", 0, 0, 0, ""),
612
592
  Commands( "DUPLICATE", 0, 0, 0, ""),
613
593
  Commands( "DYNAMIC", 0, 0, 0, ""),
623
603
  Commands( "ERRORS", 0, 0, 0, ""),
624
604
  Commands( "ESCAPE", 0, 0, 0, ""),
625
605
  Commands( "ESCAPED", 0, 0, 0, ""),
 
606
  Commands( "EVENTS", 0, 0, 0, ""),
 
607
  Commands( "EXECUTE", 0, 0, 0, ""),
626
608
  Commands( "EXISTS", 0, 0, 0, ""),
627
609
  Commands( "EXIT", 0, 0, 0, ""),
 
610
  Commands( "EXPANSION", 0, 0, 0, ""),
628
611
  Commands( "EXPLAIN", 0, 0, 0, ""),
629
612
  Commands( "EXTENDED", 0, 0, 0, ""),
630
613
  Commands( "FALSE", 0, 0, 0, ""),
645
628
  Commands( "FRAC_SECOND", 0, 0, 0, ""),
646
629
  Commands( "FROM", 0, 0, 0, ""),
647
630
  Commands( "FULL", 0, 0, 0, ""),
 
631
  Commands( "FULLTEXT", 0, 0, 0, ""),
648
632
  Commands( "FUNCTION", 0, 0, 0, ""),
649
633
  Commands( "GLOBAL", 0, 0, 0, ""),
650
634
  Commands( "GRANT", 0, 0, 0, ""),
712
696
  Commands( "LOCKS", 0, 0, 0, ""),
713
697
  Commands( "LOGS", 0, 0, 0, ""),
714
698
  Commands( "LONG", 0, 0, 0, ""),
 
699
  Commands( "LONGTEXT", 0, 0, 0, ""),
715
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, ""),
716
717
  Commands( "MATCH", 0, 0, 0, ""),
717
718
  Commands( "MAX_CONNECTIONS_PER_HOUR", 0, 0, 0, ""),
718
719
  Commands( "MAX_QUERIES_PER_HOUR", 0, 0, 0, ""),
720
721
  Commands( "MAX_UPDATES_PER_HOUR", 0, 0, 0, ""),
721
722
  Commands( "MAX_USER_CONNECTIONS", 0, 0, 0, ""),
722
723
  Commands( "MEDIUM", 0, 0, 0, ""),
 
724
  Commands( "MEDIUMTEXT", 0, 0, 0, ""),
723
725
  Commands( "MERGE", 0, 0, 0, ""),
724
726
  Commands( "MICROSECOND", 0, 0, 0, ""),
 
727
  Commands( "MIDDLEINT", 0, 0, 0, ""),
725
728
  Commands( "MIGRATE", 0, 0, 0, ""),
726
729
  Commands( "MINUTE", 0, 0, 0, ""),
727
730
  Commands( "MINUTE_MICROSECOND", 0, 0, 0, ""),
740
743
  Commands( "NAMES", 0, 0, 0, ""),
741
744
  Commands( "NATIONAL", 0, 0, 0, ""),
742
745
  Commands( "NATURAL", 0, 0, 0, ""),
 
746
  Commands( "NDB", 0, 0, 0, ""),
 
747
  Commands( "NDBCLUSTER", 0, 0, 0, ""),
743
748
  Commands( "NCHAR", 0, 0, 0, ""),
744
749
  Commands( "NEW", 0, 0, 0, ""),
745
750
  Commands( "NEXT", 0, 0, 0, ""),
746
751
  Commands( "NO", 0, 0, 0, ""),
747
752
  Commands( "NONE", 0, 0, 0, ""),
748
753
  Commands( "NOT", 0, 0, 0, ""),
 
754
  Commands( "NO_WRITE_TO_BINLOG", 0, 0, 0, ""),
749
755
  Commands( "NULL", 0, 0, 0, ""),
750
756
  Commands( "NUMERIC", 0, 0, 0, ""),
751
757
  Commands( "NVARCHAR", 0, 0, 0, ""),
752
758
  Commands( "OFFSET", 0, 0, 0, ""),
 
759
  Commands( "OLD_PASSWORD", 0, 0, 0, ""),
753
760
  Commands( "ON", 0, 0, 0, ""),
754
761
  Commands( "ONE", 0, 0, 0, ""),
755
762
  Commands( "ONE_SHOT", 0, 0, 0, ""),
766
773
  Commands( "PARTIAL", 0, 0, 0, ""),
767
774
  Commands( "PASSWORD", 0, 0, 0, ""),
768
775
  Commands( "PHASE", 0, 0, 0, ""),
 
776
  Commands( "POINT", 0, 0, 0, ""),
 
777
  Commands( "POLYGON", 0, 0, 0, ""),
769
778
  Commands( "PRECISION", 0, 0, 0, ""),
770
779
  Commands( "PREPARE", 0, 0, 0, ""),
771
780
  Commands( "PREV", 0, 0, 0, ""),
785
794
  Commands( "REDUNDANT", 0, 0, 0, ""),
786
795
  Commands( "REFERENCES", 0, 0, 0, ""),
787
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, ""),
788
800
  Commands( "RELEASE", 0, 0, 0, ""),
789
801
  Commands( "RELOAD", 0, 0, 0, ""),
790
802
  Commands( "RENAME", 0, 0, 0, ""),
791
803
  Commands( "REPAIR", 0, 0, 0, ""),
792
804
  Commands( "REPEATABLE", 0, 0, 0, ""),
793
805
  Commands( "REPLACE", 0, 0, 0, ""),
 
806
  Commands( "REPLICATION", 0, 0, 0, ""),
794
807
  Commands( "REPEAT", 0, 0, 0, ""),
795
808
  Commands( "REQUIRE", 0, 0, 0, ""),
796
809
  Commands( "RESET", 0, 0, 0, ""),
829
842
  Commands( "SIMPLE", 0, 0, 0, ""),
830
843
  Commands( "SLAVE", 0, 0, 0, ""),
831
844
  Commands( "SNAPSHOT", 0, 0, 0, ""),
 
845
  Commands( "SMALLINT", 0, 0, 0, ""),
832
846
  Commands( "SOME", 0, 0, 0, ""),
833
847
  Commands( "SONAME", 0, 0, 0, ""),
834
848
  Commands( "SOUNDS", 0, 0, 0, ""),
877
891
  Commands( "TIMESTAMP", 0, 0, 0, ""),
878
892
  Commands( "TIMESTAMPADD", 0, 0, 0, ""),
879
893
  Commands( "TIMESTAMPDIFF", 0, 0, 0, ""),
 
894
  Commands( "TINYTEXT", 0, 0, 0, ""),
880
895
  Commands( "TO", 0, 0, 0, ""),
881
896
  Commands( "TRAILING", 0, 0, 0, ""),
882
897
  Commands( "TRANSACTION", 0, 0, 0, ""),
 
898
  Commands( "TRIGGER", 0, 0, 0, ""),
 
899
  Commands( "TRIGGERS", 0, 0, 0, ""),
883
900
  Commands( "TRUE", 0, 0, 0, ""),
884
901
  Commands( "TRUNCATE", 0, 0, 0, ""),
885
902
  Commands( "TYPE", 0, 0, 0, ""),
892
909
  Commands( "UNIQUE", 0, 0, 0, ""),
893
910
  Commands( "UNKNOWN", 0, 0, 0, ""),
894
911
  Commands( "UNLOCK", 0, 0, 0, ""),
 
912
  Commands( "UNSIGNED", 0, 0, 0, ""),
895
913
  Commands( "UNTIL", 0, 0, 0, ""),
896
914
  Commands( "UPDATE", 0, 0, 0, ""),
897
915
  Commands( "UPGRADE", 0, 0, 0, ""),
899
917
  Commands( "USE", 0, 0, 0, ""),
900
918
  Commands( "USER", 0, 0, 0, ""),
901
919
  Commands( "USER_RESOURCES", 0, 0, 0, ""),
 
920
  Commands( "USE_FRM", 0, 0, 0, ""),
902
921
  Commands( "USING", 0, 0, 0, ""),
903
922
  Commands( "UTC_DATE", 0, 0, 0, ""),
904
923
  Commands( "UTC_TIMESTAMP", 0, 0, 0, ""),
918
937
  Commands( "WITH", 0, 0, 0, ""),
919
938
  Commands( "WORK", 0, 0, 0, ""),
920
939
  Commands( "WRITE", 0, 0, 0, ""),
 
940
  Commands( "X509", 0, 0, 0, ""),
921
941
  Commands( "XOR", 0, 0, 0, ""),
922
942
  Commands( "XA", 0, 0, 0, ""),
923
943
  Commands( "YEAR", 0, 0, 0, ""),
926
946
  Commands( "ABS", 0, 0, 0, ""),
927
947
  Commands( "ACOS", 0, 0, 0, ""),
928
948
  Commands( "ADDDATE", 0, 0, 0, ""),
 
949
  Commands( "AES_ENCRYPT", 0, 0, 0, ""),
 
950
  Commands( "AES_DECRYPT", 0, 0, 0, ""),
929
951
  Commands( "AREA", 0, 0, 0, ""),
930
952
  Commands( "ASIN", 0, 0, 0, ""),
931
953
  Commands( "ASBINARY", 0, 0, 0, ""),
932
954
  Commands( "ASTEXT", 0, 0, 0, ""),
 
955
  Commands( "ASWKB", 0, 0, 0, ""),
 
956
  Commands( "ASWKT", 0, 0, 0, ""),
933
957
  Commands( "ATAN", 0, 0, 0, ""),
934
958
  Commands( "ATAN2", 0, 0, 0, ""),
935
959
  Commands( "BENCHMARK", 0, 0, 0, ""),
995
1019
  Commands( "GROUP_UNIQUE_USERS", 0, 0, 0, ""),
996
1020
  Commands( "HEX", 0, 0, 0, ""),
997
1021
  Commands( "IFNULL", 0, 0, 0, ""),
 
1022
  Commands( "INET_ATON", 0, 0, 0, ""),
 
1023
  Commands( "INET_NTOA", 0, 0, 0, ""),
998
1024
  Commands( "INSTR", 0, 0, 0, ""),
999
1025
  Commands( "INTERIORRINGN", 0, 0, 0, ""),
1000
1026
  Commands( "INTERSECTS", 0, 0, 0, ""),
1010
1036
  Commands( "LEAST", 0, 0, 0, ""),
1011
1037
  Commands( "LENGTH", 0, 0, 0, ""),
1012
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, ""),
1013
1043
  Commands( "LOAD_FILE", 0, 0, 0, ""),
1014
1044
  Commands( "LOCATE", 0, 0, 0, ""),
1015
1045
  Commands( "LOG", 0, 0, 0, ""),
1032
1062
  Commands( "MD5", 0, 0, 0, ""),
1033
1063
  Commands( "MID", 0, 0, 0, ""),
1034
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, ""),
1035
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, ""),
1036
1078
  Commands( "NAME_CONST", 0, 0, 0, ""),
1037
1079
  Commands( "NOW", 0, 0, 0, ""),
1038
1080
  Commands( "NULLIF", 0, 0, 0, ""),
 
1081
  Commands( "NUMINTERIORRINGS", 0, 0, 0, ""),
1039
1082
  Commands( "NUMPOINTS", 0, 0, 0, ""),
1040
1083
  Commands( "OCTET_LENGTH", 0, 0, 0, ""),
1041
1084
  Commands( "OCT", 0, 0, 0, ""),
1044
1087
  Commands( "PERIOD_ADD", 0, 0, 0, ""),
1045
1088
  Commands( "PERIOD_DIFF", 0, 0, 0, ""),
1046
1089
  Commands( "PI", 0, 0, 0, ""),
 
1090
  Commands( "POINTFROMTEXT", 0, 0, 0, ""),
 
1091
  Commands( "POINTFROMWKB", 0, 0, 0, ""),
1047
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, ""),
1048
1097
  Commands( "POSITION", 0, 0, 0, ""),
1049
1098
  Commands( "POW", 0, 0, 0, ""),
1050
1099
  Commands( "POWER", 0, 0, 0, ""),
1108
1157
  Commands((char *)NULL,       0, 0, 0, "")
1109
1158
};
1110
1159
 
 
1160
static const char *load_default_groups[]= { "drizzle","client",0 };
1111
1161
 
1112
1162
int history_length;
1113
1163
static int not_in_history(const char *line);
1147
1197
 
1148
1198
  if (verbose)
1149
1199
  {
1150
 
    printf(_("shutting down drizzled"));
 
1200
    printf("shutting down drizzled");
1151
1201
    if (opt_drizzle_port > 0)
1152
 
      printf(_(" on port %d"), opt_drizzle_port);
 
1202
      printf(" on port %d", opt_drizzle_port);
1153
1203
    printf("... ");
1154
1204
  }
1155
1205
 
1158
1208
  {
1159
1209
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
1160
1210
    {
1161
 
      fprintf(stderr, _("shutdown failed; error: '%s'"),
 
1211
      fprintf(stderr, "shutdown failed; error: '%s'",
1162
1212
              drizzle_result_error(&result));
1163
1213
      drizzle_result_free(&result);
1164
1214
    }
1165
1215
    else
1166
1216
    {
1167
 
      fprintf(stderr, _("shutdown failed; error: '%s'"),
 
1217
      fprintf(stderr, "shutdown failed; error: '%s'",
1168
1218
              drizzle_con_error(&con));
1169
1219
    }
1170
1220
    return false;
1173
1223
  drizzle_result_free(&result);
1174
1224
 
1175
1225
  if (verbose)
1176
 
    printf(_("done\n"));
 
1226
    printf("done\n");
1177
1227
 
1178
1228
  return true;
1179
1229
}
1194
1244
  if (drizzle_ping(&con, &result, &ret) != NULL && ret == DRIZZLE_RETURN_OK)
1195
1245
  {
1196
1246
    if (opt_silent < 2)
1197
 
      printf(_("drizzled is alive\n"));
 
1247
      printf("drizzled is alive\n");
1198
1248
  }
1199
1249
  else
1200
1250
  {
1201
1251
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
1202
1252
    {
1203
 
      fprintf(stderr, _("ping failed; error: '%s'"),
 
1253
      fprintf(stderr, "ping failed; error: '%s'",
1204
1254
              drizzle_result_error(&result));
1205
1255
      drizzle_result_free(&result);
1206
1256
    }
1207
1257
    else
1208
1258
    {
1209
 
      fprintf(stderr, _("drizzled won't answer to ping, error: '%s'"),
 
1259
      fprintf(stderr, "drizzled won't answer to ping, error: '%s'",
1210
1260
              drizzle_con_error(&con));
1211
1261
    }
1212
1262
    return false;
1250
1300
  return executed;
1251
1301
}
1252
1302
 
1253
 
static void check_timeout_value(uint32_t in_connect_timeout)
1254
 
{
1255
 
  opt_connect_timeout= 0;
1256
 
  if (in_connect_timeout > 3600*12)
1257
 
  {
1258
 
    cout << _("Error: Invalid Value for connect_timeout"); 
1259
 
    exit(-1);
1260
 
  }
1261
 
  opt_connect_timeout= in_connect_timeout;
1262
 
}
1263
 
 
1264
 
static void check_max_input_line(uint32_t in_max_input_line)
1265
 
{
1266
 
  opt_max_input_line= 0;
1267
 
  if (in_max_input_line < 4096 || in_max_input_line > (int64_t)2*1024L*1024L*1024L)
1268
 
  {
1269
 
    cout << _("Error: Invalid Value for max_input_line");
1270
 
    exit(-1);
1271
 
  }
1272
 
  opt_max_input_line= in_max_input_line - (in_max_input_line % 1024);
1273
 
}
1274
 
 
1275
1303
int main(int argc,char *argv[])
1276
1304
{
1277
 
try
1278
 
{
1279
 
 
1280
1305
#if defined(ENABLE_NLS)
1281
1306
# if defined(HAVE_LOCALE_H)
1282
1307
  setlocale(LC_ALL, "");
1285
1310
  textdomain("drizzle");
1286
1311
#endif
1287
1312
 
1288
 
  po::options_description commandline_options(N_("Options used only in command line"));
1289
 
  commandline_options.add_options()
1290
 
  ("help,?",N_("Displays this help and exit."))
1291
 
  ("batch,B",N_("Don't use history file. Disable interactive behavior. (Enables --silent)"))
1292
 
  ("column-type-info", po::value<bool>(&column_types_flag)->default_value(false)->zero_tokens(),
1293
 
  N_("Display column type information."))
1294
 
  ("comments,c", po::value<bool>(&preserve_comments)->default_value(false)->zero_tokens(),
1295
 
  N_("Preserve comments. Send comments to the server. The default is --skip-comments (discard comments), enable with --comments"))
1296
 
  ("vertical,E", po::value<bool>(&vertical)->default_value(false)->zero_tokens(),
1297
 
  N_("Print the output of a query (rows) vertically."))
1298
 
  ("force,f", po::value<bool>(&ignore_errors)->default_value(false)->zero_tokens(),
1299
 
  N_("Continue even if we get an sql error."))
1300
 
  ("named-commands,G", po::value<bool>(&named_cmds)->default_value(false)->zero_tokens(),
1301
 
  N_("Enable named commands. Named commands mean this program's internal commands; see drizzle> help . When enabled, the named commands can be used from any line of the query, otherwise only from the first line, before an enter."))
1302
 
  ("no-beep,b", po::value<bool>(&opt_nobeep)->default_value(false)->zero_tokens(),
1303
 
  N_("Turn off beep on error."))
1304
 
  ("disable-line-numbers", N_("Do not write line numbers for errors."))
1305
 
  ("disable-column-names", N_("Do not write column names in results."))
1306
 
  ("skip-column-names,N", 
1307
 
  N_("Don't write column names in results. WARNING: -N is deprecated, use long version of this options instead."))
1308
 
  ("set-variable,O", po::value<string>(),
1309
 
  N_("Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value."))
1310
 
  ("table,t", po::value<bool>(&output_tables)->default_value(false)->zero_tokens(),
1311
 
  N_("Output in table format.")) 
1312
 
  ("safe-updates,U", po::value<bool>(&safe_updates)->default_value(false)->zero_tokens(),
1313
 
  N_("Only allow UPDATE and DELETE that uses keys."))
1314
 
  ("i-am-a-dummy,U", po::value<bool>(&safe_updates)->default_value(false)->zero_tokens(),
1315
 
  N_("Synonym for option --safe-updates, -U."))
1316
 
  ("verbose,v", po::value<string>(&opt_verbose)->default_value(""),
1317
 
  N_("-v vvv implies that verbose= 3, Used to specify verbose"))
1318
 
  ("version,V", N_("Output version information and exit."))
1319
 
  ("secure-auth", po::value<bool>(&opt_secure_auth)->default_value(false)->zero_tokens(),
1320
 
  N_("Refuse client connecting to server if it uses old (pre-4.1.1) protocol"))
1321
 
  ("show-warnings", po::value<bool>(&show_warnings)->default_value(false)->zero_tokens(),
1322
 
  N_("Show warnings after every statement."))
1323
 
  ("show-progress-size", po::value<uint32_t>(&show_progress_size)->default_value(0),
1324
 
  N_("Number of lines before each import progress report."))
1325
 
  ("ping", po::value<bool>(&opt_ping)->default_value(false)->zero_tokens(),
1326
 
  N_("Ping the server to check if it's alive."))
1327
 
  ("no-defaults", po::value<bool>()->default_value(false)->zero_tokens(),
1328
 
  N_("Configuration file defaults are not used if no-defaults is set"))
1329
 
  ;
1330
 
 
1331
 
  po::options_description drizzle_options(N_("Options specific to the drizzle client"));
1332
 
  drizzle_options.add_options()
1333
 
  ("disable-auto-rehash,A",
1334
 
  N_("Disable automatic rehashing. One doesn't need to use 'rehash' to get table and field completion, but startup and reconnecting may take a longer time."))
1335
 
  ("auto-vertical-output", po::value<bool>(&auto_vertical_output)->default_value(false)->zero_tokens(),
1336
 
  N_("Automatically switch to vertical output mode if the result is wider than the terminal width."))
1337
 
  ("database,D", po::value<string>(&current_db)->default_value(""),
1338
 
  N_("Database to use."))
1339
 
  ("default-character-set",po::value<string>(),
1340
 
  N_("(not used)"))
1341
 
  ("delimiter", po::value<string>(&delimiter_str)->default_value(";"),
1342
 
  N_("Delimiter to be used."))
1343
 
  ("execute,e", po::value<string>(),
1344
 
  N_("Execute command and quit. (Disables --force and history file)"))
1345
 
  ("local-infile", po::value<bool>(&opt_local_infile)->default_value(false)->zero_tokens(),
1346
 
  N_("Enable LOAD DATA LOCAL INFILE."))
1347
 
  ("unbuffered,n", po::value<bool>(&unbuffered)->default_value(false)->zero_tokens(),
1348
 
  N_("Flush buffer after each query."))
1349
 
  ("sigint-ignore", po::value<bool>(&opt_sigint_ignore)->default_value(false)->zero_tokens(),
1350
 
  N_("Ignore SIGINT (CTRL-C)"))
1351
 
  ("one-database,o", po::value<bool>(&one_database)->default_value(false)->zero_tokens(),
1352
 
  N_("Only update the default database. This is useful for skipping updates to other database in the update log."))
1353
 
  ("pager", po::value<string>(),
1354
 
  N_("Pager to use to display results. If you don't supply an option the default pager is taken from your ENV variable PAGER. Valid pagers are less, more, cat [> filename], etc. See interactive help (\\h) also. This option does not work in batch mode. Disable with --disable-pager. This option is disabled by default."))
1355
 
  ("disable-pager", po::value<bool>(&opt_nopager)->default_value(false)->zero_tokens(),
1356
 
  N_("Disable pager and print to stdout. See interactive help (\\h) also."))
1357
 
  ("prompt", po::value<string>(&current_prompt)->default_value(""),  
1358
 
  N_("Set the drizzle prompt to this value."))
1359
 
  ("quick,q", po::value<bool>(&quick)->default_value(false)->zero_tokens(),
1360
 
  N_("Don't cache result, print it row by row. This may slow down the server if the output is suspended. Doesn't use history file."))
1361
 
  ("raw,r", po::value<bool>(&opt_raw_data)->default_value(false)->zero_tokens(),
1362
 
  N_("Write fields without conversion. Used with --batch.")) 
1363
 
  ("disable-reconnect", N_("Do not reconnect if the connection is lost."))
1364
 
  ("shutdown", po::value<bool>()->zero_tokens(),
1365
 
  N_("Shutdown the server"))
1366
 
  ("silent,s", N_("Be more silent. Print results with a tab as separator, each row on new line."))
1367
 
  ("tee", po::value<string>(),
1368
 
  N_("Append everything into outfile. See interactive help (\\h) also. Does not work in batch mode. Disable with --disable-tee. This option is disabled by default."))
1369
 
  ("disable-tee", po::value<bool>()->default_value(false)->zero_tokens(), 
1370
 
  N_("Disable outfile. See interactive help (\\h) also."))
1371
 
  ("connect-timeout", po::value<uint32_t>(&opt_connect_timeout)->default_value(0)->notifier(&check_timeout_value),
1372
 
  N_("Number of seconds before connection timeout."))
1373
 
  ("max-input-line", po::value<uint32_t>(&opt_max_input_line)->default_value(16*1024L*1024L)->notifier(&check_max_input_line),
1374
 
  N_("Max length of input line"))
1375
 
  ("select-limit", po::value<uint32_t>(&select_limit)->default_value(1000L),
1376
 
  N_("Automatic limit for SELECT when using --safe-updates"))
1377
 
  ("max-join-size", po::value<uint32_t>(&max_join_size)->default_value(1000000L),
1378
 
  N_("Automatic limit for rows in a join when using --safe-updates"))
1379
 
  ;
1380
 
 
1381
 
  po::options_description client_options(N_("Options specific to the client"));
1382
 
  client_options.add_options()
1383
 
  ("host,h", po::value<string>(&current_host)->default_value("localhost"),
1384
 
  N_("Connect to host"))
1385
 
  ("password,P", po::value<string>(&current_password)->default_value(PASSWORD_SENTINEL),
1386
 
  N_("Password to use when connecting to server. If password is not given it's asked from the tty."))
1387
 
  ("port,p", po::value<uint32_t>()->default_value(0),
1388
 
  N_("Port number to use for connection or 0 for default to, in order of preference, drizzle.cnf, $DRIZZLE_TCP_PORT, built-in default"))
1389
 
#ifdef DRIZZLE_ADMIN_TOOL
1390
 
  ("user,u", po::value<string>(&current_user)->default_value("root"),
1391
 
#else
1392
 
  ("user,u", po::value<string>(&current_user)->default_value(""),
1393
 
#endif
1394
 
  N_("User for login if not current user."))
1395
 
  ("protocol",po::value<string>(&opt_protocol)->default_value("mysql"),
1396
 
  N_("The protocol of connection (mysql or drizzle)."))
1397
 
  ;
1398
 
 
1399
 
  po::options_description long_options(N_("Allowed Options"));
1400
 
  long_options.add(commandline_options).add(drizzle_options).add(client_options);
1401
 
 
1402
 
  std::string system_config_dir_drizzle(SYSCONFDIR); 
1403
 
  system_config_dir_drizzle.append("/drizzle/drizzle.cnf");
1404
 
 
1405
 
  std::string system_config_dir_client(SYSCONFDIR); 
1406
 
  system_config_dir_client.append("/drizzle/client.cnf");
1407
 
 
1408
 
  std::string user_config_dir((getenv("XDG_CONFIG_HOME")? getenv("XDG_CONFIG_HOME"):"~/.config"));
1409
 
 
1410
 
  if (user_config_dir.compare(0, 2, "~/") == 0)
1411
 
  {
1412
 
    char *homedir;
1413
 
    homedir= getenv("HOME");
1414
 
    if (homedir != NULL)
1415
 
      user_config_dir.replace(0, 1, homedir);
1416
 
  }
1417
 
 
1418
 
  po::variables_map vm;
1419
 
 
1420
 
  po::positional_options_description p;
1421
 
  p.add("database", 1);
1422
 
 
1423
 
  // Disable allow_guessing
1424
 
  int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
1425
 
 
1426
 
  po::store(po::command_line_parser(argc, argv).options(long_options).
1427
 
            style(style).positional(p).extra_parser(parse_password_arg).run(),
1428
 
            vm);
1429
 
 
1430
 
  if (! vm["no-defaults"].as<bool>())
1431
 
  {
1432
 
    std::string user_config_dir_drizzle(user_config_dir);
1433
 
    user_config_dir_drizzle.append("/drizzle/drizzle.cnf"); 
1434
 
 
1435
 
    std::string user_config_dir_client(user_config_dir);
1436
 
    user_config_dir_client.append("/drizzle/client.cnf");
1437
 
 
1438
 
    ifstream user_drizzle_ifs(user_config_dir_drizzle.c_str());
1439
 
    po::store(dpo::parse_config_file(user_drizzle_ifs, drizzle_options), vm);
1440
 
 
1441
 
    ifstream user_client_ifs(user_config_dir_client.c_str());
1442
 
    po::store(dpo::parse_config_file(user_client_ifs, client_options), vm);
1443
 
 
1444
 
    ifstream system_drizzle_ifs(system_config_dir_drizzle.c_str());
1445
 
    store(dpo::parse_config_file(system_drizzle_ifs, drizzle_options), vm);
1446
 
 
1447
 
    ifstream system_client_ifs(system_config_dir_client.c_str());
1448
 
    po::store(dpo::parse_config_file(system_client_ifs, client_options), vm);
1449
 
  }
1450
 
 
1451
 
  po::notify(vm);
1452
 
 
1453
 
#ifdef DRIZZLE_ADMIN_TOOL
1454
 
  default_prompt= strdup(getenv("DRIZZLE_PS1") ?
1455
 
                         getenv("DRIZZLE_PS1") :
1456
 
                         "drizzleadmin> ");
1457
 
#else
 
1313
  MY_INIT(argv[0]);
 
1314
  delimiter_str= delimiter;
1458
1315
  default_prompt= strdup(getenv("DRIZZLE_PS1") ?
1459
1316
                         getenv("DRIZZLE_PS1") :
1460
1317
                         "drizzle> ");
1461
 
#endif
 
1318
  
1462
1319
  if (default_prompt == NULL)
1463
1320
  {
1464
1321
    fprintf(stderr, _("Memory allocation error while constructing initial "
1466
1323
    exit(ENOMEM);
1467
1324
  }
1468
1325
  current_prompt= strdup(default_prompt);
1469
 
  if (current_prompt.empty())
 
1326
  if (current_prompt == NULL)
1470
1327
  {
1471
1328
    fprintf(stderr, _("Memory allocation error while constructing initial "
1472
1329
                      "prompt. Aborting.\n"));
1477
1334
 
1478
1335
  prompt_counter=0;
1479
1336
 
1480
 
  outfile.clear();      // no (default) outfile
1481
 
  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
1482
1339
  {
1483
 
    const char *tmp= getenv("PAGER");
 
1340
    char *tmp=getenv("PAGER");
1484
1341
    if (tmp && strlen(tmp))
1485
1342
    {
1486
1343
      default_pager_set= 1;
1487
 
      default_pager.assign(tmp);
 
1344
      strcpy(default_pager, tmp);
1488
1345
    }
1489
1346
  }
1490
 
  if (! isatty(0) || ! isatty(1))
 
1347
  if (!isatty(0) || !isatty(1))
1491
1348
  {
1492
1349
    status.setBatch(1); opt_silent=1;
1493
1350
    ignore_errors=0;
1510
1367
      close(stdout_fileno_copy);             /* Clean up dup(). */
1511
1368
  }
1512
1369
 
1513
 
  /* Inverted Booleans */
1514
 
 
1515
 
  line_numbers= (vm.count("disable-line-numbers")) ? false : true;
1516
 
  column_names= (vm.count("disable-column-names")) ? false : true;
1517
 
  opt_rehash= (vm.count("disable-auto-rehash")) ? false : true;
1518
 
  opt_reconnect= (vm.count("disable-reconnect")) ? false : true;
1519
 
 
1520
 
  /* Don't rehash with --shutdown */
1521
 
  if (vm.count("shutdown"))
1522
 
  {
1523
 
    opt_rehash= false;
1524
 
    opt_shutdown= true;
1525
 
  }
1526
 
 
1527
 
  if (vm.count("delimiter"))
1528
 
  {
1529
 
    /* Check that delimiter does not contain a backslash */
1530
 
    if (! strstr(delimiter_str.c_str(), "\\"))
1531
 
    {
1532
 
      delimiter= (char *)delimiter_str.c_str();  
1533
 
    }
1534
 
    else
1535
 
    {
1536
 
      put_info(_("DELIMITER cannot contain a backslash character"),
1537
 
      INFO_ERROR,0,0);
1538
 
      exit(-1);
1539
 
    }
1540
 
   
1541
 
    delimiter_length= (uint32_t)strlen(delimiter);
1542
 
  }
1543
 
  if (vm.count("tee"))
1544
 
  { 
1545
 
    if (vm["tee"].as<string>().empty())
1546
 
    {
1547
 
      if (opt_outfile)
1548
 
        end_tee();
1549
 
    }
1550
 
    else
1551
 
      init_tee(vm["tee"].as<string>().c_str());
1552
 
  }
1553
 
  if (vm["disable-tee"].as<bool>() == true)
1554
 
  {
1555
 
    if (opt_outfile)
1556
 
      end_tee();
1557
 
  }
1558
 
  if (vm.count("pager"))
1559
 
  {
1560
 
    if (vm["pager"].as<string>().empty())
1561
 
      opt_nopager= 1;
1562
 
    else
1563
 
    {
1564
 
      opt_nopager= 0;
1565
 
      if (vm[pager].as<string>().length())
1566
 
      {
1567
 
        default_pager_set= 1;
1568
 
        pager.assign(vm["pager"].as<string>());
1569
 
        default_pager.assign(pager);
1570
 
      }
1571
 
      else if (default_pager_set)
1572
 
        pager.assign(default_pager);
1573
 
      else
1574
 
        opt_nopager= 1;
1575
 
    }
1576
 
  }
1577
 
  if (vm.count("disable-pager"))
1578
 
  {
1579
 
    opt_nopager= 1;
1580
 
  }
1581
 
 
1582
 
  if (vm.count("no-auto-rehash"))
1583
 
    opt_rehash= 0;
1584
 
 
1585
 
  if (vm.count("skip-column-names"))
1586
 
    column_names= 0;
1587
 
    
1588
 
  if (vm.count("execute"))
1589
 
  {  
1590
 
    status.setBatch(1);
1591
 
    status.setAddToHistory(1);
1592
 
    if (status.getLineBuff() == NULL)
1593
 
      status.setLineBuff(opt_max_input_line,NULL);
1594
 
    if (status.getLineBuff() == NULL)
1595
 
    {
1596
 
      exit(1);
1597
 
    }
1598
 
    status.getLineBuff()->addString(vm["execute"].as<string>().c_str());
1599
 
  }
1600
 
 
1601
 
  if (one_database)
1602
 
    skip_updates= true;
1603
 
 
1604
 
  if (vm.count("protocol"))
1605
 
  {
1606
 
    std::transform(opt_protocol.begin(), opt_protocol.end(), 
1607
 
      opt_protocol.begin(), ::tolower);
1608
 
 
1609
 
    if (not opt_protocol.compare("mysql"))
1610
 
      use_drizzle_protocol=false;
1611
 
    else if (not opt_protocol.compare("drizzle"))
1612
 
      use_drizzle_protocol=true;
1613
 
    else
1614
 
    {
1615
 
      cout << _("Error: Unknown protocol") << " '" << opt_protocol << "'" << endl;
1616
 
      exit(-1);
1617
 
    }
1618
 
  }
1619
 
 
1620
 
  if (vm.count("port"))
1621
 
  {
1622
 
    opt_drizzle_port= vm["port"].as<uint32_t>();
1623
 
 
1624
 
    /* If the port number is > 65535 it is not a valid port
1625
 
       This also helps with potential data loss casting unsigned long to a
1626
 
       uint32_t. */
1627
 
    if (opt_drizzle_port > 65535)
1628
 
    {
1629
 
      printf(_("Error: Value of %" PRIu32 " supplied for port is not valid.\n"), opt_drizzle_port);
1630
 
      exit(-1);
1631
 
    }
1632
 
  }
1633
 
 
1634
 
  if (vm.count("password"))
1635
 
  {
1636
 
    if (!opt_password.empty())
1637
 
      opt_password.erase();
1638
 
    if (current_password == PASSWORD_SENTINEL)
1639
 
    {
1640
 
      opt_password= "";
1641
 
    }
1642
 
    else
1643
 
    {
1644
 
      opt_password= current_password;
1645
 
      tty_password= false;
1646
 
    }
1647
 
  }
1648
 
  else
1649
 
  {
1650
 
      tty_password= true;
1651
 
  }
1652
 
  
1653
 
 
1654
 
  if (!opt_verbose.empty())
1655
 
  {
1656
 
    verbose= opt_verbose.length();
1657
 
  }
1658
 
 
1659
 
  if (vm.count("batch"))
1660
 
  {
1661
 
    status.setBatch(1);
1662
 
    status.setAddToHistory(0);
1663
 
    if (opt_silent < 1)
1664
 
    {
1665
 
      opt_silent= 1;
1666
 
    }
1667
 
  }
1668
 
  if (vm.count("silent"))
1669
 
  {
1670
 
    opt_silent++;
1671
 
  }
1672
 
  
1673
 
  if (vm.count("help") || vm.count("version"))
1674
 
  {
1675
 
    printf(_("Drizzle client %s build %s, for %s-%s (%s) using readline %s\n"),
1676
 
           drizzle_version(), VERSION,
1677
 
           HOST_VENDOR, HOST_OS, HOST_CPU,
1678
 
           rl_library_version);
1679
 
    if (vm.count("version"))
1680
 
      exit(0);
1681
 
    printf(_("Copyright (C) 2008 Sun Microsystems\n"
1682
 
           "This software comes with ABSOLUTELY NO WARRANTY. "
1683
 
           "This is free software,\n"
1684
 
           "and you are welcome to modify and redistribute it "
1685
 
           "under the GPL license\n"));
1686
 
    printf(_("Usage: drizzle [OPTIONS] [database]\n"));
1687
 
    cout << long_options;
1688
 
    exit(0);
1689
 
  }
1690
 
 
1691
 
 
1692
 
  if (process_options())
1693
 
  {
 
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();
1694
1376
    exit(1);
1695
1377
  }
1696
1378
 
1697
1379
  memset(&drizzle, 0, sizeof(drizzle));
1698
 
  if (sql_connect(current_host, current_db, current_user, opt_password,opt_silent))
 
1380
  if (sql_connect(current_host,current_db,current_user,opt_password,
 
1381
                  opt_silent))
1699
1382
  {
1700
1383
    quick= 1;          // Avoid history
1701
1384
    status.setExitStatus(1);
1706
1389
  if (execute_commands(&command_error) != false)
1707
1390
  {
1708
1391
    /* we've executed a command so exit before we go into readline mode */
 
1392
    internal::free_defaults(defaults_argv);
 
1393
    internal::my_end();
1709
1394
    exit(command_error);
1710
1395
  }
1711
1396
 
1714
1399
    status.setLineBuff(opt_max_input_line, stdin);
1715
1400
    if (status.getLineBuff() == NULL)
1716
1401
    {
 
1402
      internal::free_defaults(defaults_argv);
 
1403
      internal::my_end();
1717
1404
      exit(1);
1718
1405
    }
1719
1406
  }
1733
1420
  /* call the SIGWINCH handler to get the default term width */
1734
1421
  window_resize(0);
1735
1422
#endif
1736
 
  std::vector<char> output_buff;
1737
 
  output_buff.resize(512);
1738
 
 
1739
 
  snprintf(&output_buff[0], output_buff.size(), 
1740
 
           _("Welcome to the Drizzle client..  Commands end with %s or \\g."), 
1741
 
           delimiter);
1742
 
 
1743
 
  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);
1744
1426
 
1745
1427
  glob_buffer= new string();
1746
1428
  glob_buffer->reserve(512);
1747
1429
 
1748
 
  snprintf(&output_buff[0], output_buff.size(),
1749
 
          _("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"),
1750
1435
          drizzle_con_thread_id(&con),
1751
 
          opt_protocol.c_str(),
1752
1436
          server_version_string(&con));
1753
 
  put_info(&output_buff[0], INFO_INFO, 0, 0);
1754
 
 
1755
 
 
1756
 
  initialize_readline((char *)current_prompt.c_str());
 
1437
  put_info(output_buff, INFO_INFO, 0, 0);
 
1438
 
 
1439
  initialize_readline(current_prompt);
1757
1440
  if (!status.getBatch() && !quick)
1758
1441
  {
1759
1442
    /* read-history from file, default ~/.drizzle_history*/
1797
1480
  if (opt_outfile)
1798
1481
    end_tee();
1799
1482
  drizzle_end(0);
1800
 
}
1801
1483
 
1802
 
  catch(exception &err)
1803
 
  {
1804
 
    cerr << _("Error:") << err.what() << endl;
1805
 
  }
1806
1484
  return(0);        // Keep compiler happy
1807
1485
}
1808
1486
 
1816
1494
    if (verbose)
1817
1495
      tee_fprintf(stdout, _("Writing history-file %s\n"),histfile);
1818
1496
    if (!write_history(histfile_tmp))
1819
 
      rename(histfile_tmp, histfile);
 
1497
      internal::my_rename(histfile_tmp, histfile, MYF(MY_WME));
1820
1498
  }
1821
1499
  delete status.getLineBuff();
1822
1500
  status.setLineBuff(0);
1823
1501
 
1824
1502
  if (sig >= 0)
1825
1503
    put_info(sig ? _("Aborted") : _("Bye"), INFO_RESULT,0,0);
1826
 
  delete glob_buffer;
1827
 
  delete processed_prompt;
1828
 
  opt_password.erase();
 
1504
  if (glob_buffer)
 
1505
    delete glob_buffer;
 
1506
  if (processed_prompt)
 
1507
    delete processed_prompt;
 
1508
  free(opt_password);
1829
1509
  free(histfile);
1830
1510
  free(histfile_tmp);
1831
 
  current_db.erase();
1832
 
  current_host.erase();
1833
 
  current_user.erase();
 
1511
  free(current_db);
 
1512
  free(current_host);
 
1513
  free(current_user);
1834
1514
  free(full_username);
1835
1515
  free(part_username);
1836
1516
  free(default_prompt);
1837
 
  current_prompt.erase();
 
1517
  free(current_prompt);
 
1518
  internal::free_defaults(defaults_argv);
 
1519
  internal::my_end();
1838
1520
  exit(status.getExitStatus());
1839
1521
}
1840
1522
 
1848
1530
void handle_sigint(int sig)
1849
1531
{
1850
1532
  char kill_buffer[40];
1851
 
  boost::scoped_ptr<drizzle_con_st> kill_drizzle(new drizzle_con_st);
 
1533
  drizzle_con_st kill_drizzle;
1852
1534
  drizzle_result_st res;
1853
1535
  drizzle_return_t ret;
1854
1536
 
1857
1539
    goto err;
1858
1540
  }
1859
1541
 
1860
 
  if (drizzle_con_add_tcp(&drizzle, kill_drizzle.get(), current_host.c_str(),
1861
 
    opt_drizzle_port, current_user.c_str(), opt_password.c_str(), NULL,
1862
 
    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)
1863
1545
  {
1864
1546
    goto err;
1865
1547
  }
1868
1550
  sprintf(kill_buffer, "KILL /*!50000 QUERY */ %u",
1869
1551
          drizzle_con_thread_id(&con));
1870
1552
 
1871
 
  if (drizzle_query_str(kill_drizzle.get(), &res, kill_buffer, &ret) != NULL)
 
1553
  if (drizzle_query_str(&kill_drizzle, &res, kill_buffer, &ret) != NULL)
1872
1554
    drizzle_result_free(&res);
1873
1555
 
1874
 
  drizzle_con_free(kill_drizzle.get());
 
1556
  drizzle_con_free(&kill_drizzle);
1875
1557
  tee_fprintf(stdout, _("Query aborted by Ctrl+C\n"));
1876
1558
 
1877
1559
  interrupted_query= 1;
1893
1575
}
1894
1576
#endif
1895
1577
 
1896
 
 
1897
 
 
1898
 
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)
1899
1938
{
1900
1939
  char *tmp, *pagpoint;
1901
 
  
 
1940
  int ho_error;
1902
1941
 
1903
1942
  tmp= (char *) getenv("DRIZZLE_HOST");
1904
1943
  if (tmp)
1905
 
    current_host.assign(tmp);
 
1944
    current_host= strdup(tmp);
1906
1945
 
1907
1946
  pagpoint= getenv("PAGER");
1908
1947
  if (!((char*) (pagpoint)))
1909
1948
  {
1910
 
    pager.assign("stdout");
 
1949
    strcpy(pager, "stdout");
1911
1950
    opt_nopager= 1;
1912
1951
  }
1913
1952
  else
1914
 
  {
1915
 
    pager.assign(pagpoint);
1916
 
  }
1917
 
  default_pager.assign(pager);
 
1953
    strcpy(pager, pagpoint);
 
1954
  strcpy(default_pager, pager);
1918
1955
 
1919
 
  //
 
1956
  if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
 
1957
    exit(ho_error);
1920
1958
 
1921
1959
  if (status.getBatch()) /* disable pager and outfile in this case */
1922
1960
  {
1923
 
    default_pager.assign("stdout");
1924
 
    pager.assign("stdout");
 
1961
    strcpy(default_pager, "stdout");
 
1962
    strcpy(pager, "stdout");
1925
1963
    opt_nopager= 1;
1926
1964
    default_pager_set= 0;
1927
1965
    opt_outfile= 0;
1929
1967
    connect_flag= DRIZZLE_CAPABILITIES_NONE; /* Not in interactive mode */
1930
1968
  }
1931
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
  }
1932
1981
  if (tty_password)
1933
1982
    opt_password= client_get_tty_password(NULL);
 
1983
 
1934
1984
  return(0);
1935
1985
}
1936
1986
 
1963
2013
    }
1964
2014
    else
1965
2015
    {
1966
 
      string prompt(ml_comment
1967
 
                      ? "   /*> " 
1968
 
                      : glob_buffer->empty()
1969
 
                        ? construct_prompt()
1970
 
                        : not in_string
1971
 
                          ? "    -> "
1972
 
                          : in_string == '\''
1973
 
                            ? "    '> "
1974
 
                            : in_string == '`'
1975
 
                              ? "    `> "
1976
 
                              : "    \"> ");
 
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
                                                      "    \"> "));
1977
2024
      if (opt_outfile && glob_buffer->empty())
1978
2025
        fflush(OUTFILE);
1979
2026
 
1980
2027
      if (opt_outfile)
1981
 
        fputs(prompt.c_str(), OUTFILE);
1982
 
      line= readline(prompt.c_str());
 
2028
        fputs(prompt, OUTFILE);
 
2029
      line= readline(prompt);
1983
2030
      /*
1984
2031
        When Ctrl+d or Ctrl+z is pressed, the line may be NULL on some OS
1985
2032
        which may cause coredump.
2042
2089
  }
2043
2090
  else
2044
2091
  {
2045
 
    while (isspace(*name))
 
2092
    while (my_isspace(charset_info,*name))
2046
2093
      name++;
2047
2094
    /*
2048
2095
      If there is an \\g in the row or if the row has a delimiter but
2051
2098
    */
2052
2099
    if (strstr(name, "\\g") || (strstr(name, delimiter) &&
2053
2100
                                !(strlen(name) >= 9 &&
2054
 
                                  !strcmp(name, "delimiter"))))
 
2101
                                  !my_strnncoll(charset_info,
 
2102
                                                (unsigned char*) name, 9,
 
2103
                                                (const unsigned char*) "delimiter",
 
2104
                                                9))))
2055
2105
      return(NULL);
2056
2106
    if ((end=strcont(name," \t")))
2057
2107
    {
2058
2108
      len=(uint32_t) (end - name);
2059
 
      while (isspace(*end))
 
2109
      while (my_isspace(charset_info,*end))
2060
2110
        end++;
2061
2111
      if (!*end)
2062
2112
        end=0;          // no arguments to function
2068
2118
  for (uint32_t i= 0; commands[i].getName(); i++)
2069
2119
  {
2070
2120
    if (commands[i].func &&
2071
 
        ((name && !strncmp(name, commands[i].getName(), len)
2072
 
          && !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)))
2073
2122
    {
2074
2123
      return(&commands[i]);
2075
2124
    }
2099
2148
    if (!preserve_comments)
2100
2149
    {
2101
2150
      // Skip spaces at the beggining of a statement
2102
 
      if (isspace(inchar) && (out == line) &&
 
2151
      if (my_isspace(charset_info,inchar) && (out == line) &&
2103
2152
          (buffer->empty()))
2104
2153
        continue;
2105
2154
    }
2106
2155
 
2107
2156
    // Accept multi-byte characters as-is
2108
 
    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)))
2109
2160
    {
2110
 
      int length;
2111
 
      if ((length= drizzled::utf8::sequence_length(*pos)))
 
2161
      if (!*ml_comment || preserve_comments)
2112
2162
      {
2113
 
        if (!*ml_comment || preserve_comments)
2114
 
        {
2115
 
          while (length--)
2116
 
            *out++ = *pos++;
2117
 
          pos--;
2118
 
        }
2119
 
        else
2120
 
          pos+= length - 1;
2121
 
        continue;
 
2163
        while (length--)
 
2164
          *out++ = *pos++;
 
2165
        pos--;
2122
2166
      }
 
2167
      else
 
2168
        pos+= length - 1;
 
2169
      continue;
2123
2170
    }
2124
2171
    if (!*ml_comment && inchar == '\\' &&
2125
2172
        !(*in_string && (drizzle_con_status(&con) & DRIZZLE_CON_STATUS_NO_BACKSLASH_ESCAPES)))
2188
2235
    }
2189
2236
    else if (!*ml_comment && !*in_string &&
2190
2237
             (end_of_line - pos) >= 10 &&
2191
 
             !strncmp(pos, "delimiter ", 10))
 
2238
             !my_strnncoll(charset_info, (unsigned char*) pos, 10,
 
2239
                           (const unsigned char*) "delimiter ", 10))
2192
2240
    {
2193
2241
      // Flush previously accepted characters
2194
2242
      if (out != line)
2225
2273
 
2226
2274
      if (preserve_comments)
2227
2275
      {
2228
 
        while (isspace(*pos))
 
2276
        while (my_isspace(charset_info, *pos))
2229
2277
          *out++= *pos++;
2230
2278
      }
2231
2279
      // Flush previously accepted characters
2238
2286
      if (preserve_comments && ((*pos == '#') ||
2239
2287
                                ((*pos == '-') &&
2240
2288
                                 (pos[1] == '-') &&
2241
 
                                 isspace(pos[2]))))
 
2289
                                 my_isspace(charset_info, pos[2]))))
2242
2290
      {
2243
2291
        // Add trailing single line comments to this statement
2244
2292
        buffer->append(pos);
2265
2313
                 && (inchar == '#'
2266
2314
                     || (inchar == '-'
2267
2315
                         && pos[1] == '-'
2268
 
                         && isspace(pos[2])))))
 
2316
                         && my_isspace(charset_info,pos[2])))))
2269
2317
    {
2270
2318
      // Flush previously accepted characters
2271
2319
      if (out != line)
2331
2379
        *in_string= (char) inchar;
2332
2380
      if (!*ml_comment || preserve_comments)
2333
2381
      {
2334
 
        if (need_space && !isspace((char)inchar))
 
2382
        if (need_space && !my_isspace(charset_info, (char)inchar))
2335
2383
          *out++= ' ';
2336
2384
        need_space= 0;
2337
2385
        *out++= (char) inchar;
2342
2390
  {
2343
2391
    *out++='\n';
2344
2392
    uint32_t length=(uint32_t) (out-line);
2345
 
    if ((buffer->length() + length) > opt_max_input_line)
2346
 
    {
2347
 
      status.setExitStatus(1);
2348
 
      put_info(_("Not found a delimiter within max_input_line of input"), INFO_ERROR, 0, 0);
2349
 
      return 1;
2350
 
    }
2351
2393
    if ((!*ml_comment || preserve_comments))
2352
2394
      buffer->append(line, length);
2353
2395
  }
2540
2582
  drizzle_column_st *sql_field;
2541
2583
  string tmp_str, tmp_str_lower;
2542
2584
 
2543
 
  if (status.getBatch() || quick || current_db.empty())
 
2585
  if (status.getBatch() || quick || !current_db)
2544
2586
    return;      // We don't need completion in batches
2545
2587
  if (!rehash)
2546
2588
    return;
2623
2665
  {
2624
2666
    string query;
2625
2667
 
2626
 
    query.append("show fields in `");
 
2668
    query.append("show fields in '");
2627
2669
    query.append(table_row[0]);
2628
 
    query.append("`");
 
2670
    query.append("'");
2629
2671
    
2630
2672
    if (drizzle_query(&con, &fields, query.c_str(), query.length(),
2631
2673
                      &ret) != NULL)
2675
2717
  drizzle_return_t ret;
2676
2718
  drizzle_result_st res;
2677
2719
 
2678
 
  current_db.erase();
2679
 
  current_db= "";
 
2720
  free(current_db);
 
2721
  current_db= NULL;
2680
2722
  /* In case of error below current_db will be NULL */
2681
2723
  if (drizzle_query_str(&con, &res, "SELECT DATABASE()", &ret) != NULL)
2682
2724
  {
2685
2727
    {
2686
2728
      drizzle_row_t row= drizzle_row_next(&res);
2687
2729
      if (row[0])
2688
 
        current_db.assign(row[0]);
 
2730
        current_db= strdup(row[0]);
2689
2731
      drizzle_result_free(&res);
2690
2732
    }
2691
2733
  }
2695
2737
 The different commands
2696
2738
***************************************************************************/
2697
2739
 
2698
 
int drizzleclient_real_query_for_lazy(const char *buf, size_t length,
 
2740
int drizzleclient_real_query_for_lazy(const char *buf, int length,
2699
2741
                                      drizzle_result_st *result,
2700
2742
                                      uint32_t *error_code)
2701
2743
{
2734
2776
    return 0;
2735
2777
 
2736
2778
  if (drizzle_con_error(&con)[0])
2737
 
  {
2738
 
    int ret= put_error(&con, result);
2739
 
    drizzle_result_free(result);
2740
 
    return ret;
2741
 
  }
 
2779
    return put_error(&con, result);
2742
2780
  return 0;
2743
2781
}
2744
2782
 
2747
2785
{
2748
2786
  register int i, j;
2749
2787
  char buff[32], *end;
2750
 
  std::vector<char> output_buff;
2751
 
  output_buff.resize(512);
2752
2788
 
2753
2789
  put_info(_("List of all Drizzle commands:"), INFO_INFO,0,0);
2754
2790
  if (!named_cmds)
2755
 
  {
2756
 
    snprintf(&output_buff[0], output_buff.size(),
2757
 
             _("Note that all text commands must be first on line and end with '%s' or \\g"),
2758
 
             delimiter);
2759
 
    put_info(&output_buff[0], INFO_INFO, 0, 0);
2760
 
  }
 
2791
    put_info(_("Note that all text commands must be first on line and end with ';'"),INFO_INFO,0,0);
2761
2792
  for (i = 0; commands[i].getName(); i++)
2762
2793
  {
2763
2794
    end= strcpy(buff, commands[i].getName());
2971
3002
{
2972
3003
  if (!opt_nopager)
2973
3004
  {
2974
 
    if (!(PAGER= popen(pager.c_str(), "w")))
 
3005
    if (!(PAGER= popen(pager, "w")))
2975
3006
    {
2976
 
      tee_fprintf(stdout,_( "popen() failed! defaulting PAGER to stdout!\n"));
 
3007
      tee_fprintf(stdout, "popen() failed! defaulting PAGER to stdout!\n");
2977
3008
      PAGER= stdout;
2978
3009
    }
2979
3010
  }
2995
3026
    end_tee();
2996
3027
  if (!(new_outfile= fopen(file_name, "a")))
2997
3028
  {
2998
 
    tee_fprintf(stdout, _("Error logging to file '%s'\n"), file_name);
 
3029
    tee_fprintf(stdout, "Error logging to file '%s'\n", file_name);
2999
3030
    return;
3000
3031
  }
3001
3032
  OUTFILE = new_outfile;
3002
 
  outfile.assign(file_name);
3003
 
  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);
3004
3035
  opt_outfile= 1;
3005
3036
 
3006
3037
  return;
3084
3115
 
3085
3116
  while ((field = drizzle_column_next(result)))
3086
3117
  {
3087
 
    tee_fprintf(PAGER, _("Field %3u:  `%s`\n"
 
3118
    tee_fprintf(PAGER, "Field %3u:  `%s`\n"
3088
3119
                "Catalog:    `%s`\n"
3089
3120
                "Database:   `%s`\n"
3090
3121
                "Table:      `%s`\n"
3091
3122
                "Org_table:  `%s`\n"
3092
 
                "Type:       UTF-8\n"
 
3123
                "Type:       %s\n"
3093
3124
                "Collation:  %s (%u)\n"
3094
3125
                "Length:     %lu\n"
3095
3126
                "Max_length: %lu\n"
3096
3127
                "Decimals:   %u\n"
3097
 
                "Flags:      %s\n\n"),
 
3128
                "Flags:      %s\n\n",
3098
3129
                ++i,
3099
3130
                drizzle_column_name(field), drizzle_column_catalog(field),
3100
3131
                drizzle_column_db(field), drizzle_column_table(field),
3101
3132
                drizzle_column_orig_table(field),
3102
3133
                fieldtype2str(drizzle_column_type(field)),
 
3134
                get_charset_name(drizzle_column_charset(field)),
3103
3135
                drizzle_column_charset(field), drizzle_column_size(field),
3104
3136
                drizzle_column_max_size(field), drizzle_column_decimals(field),
3105
3137
                fieldflags2str(drizzle_column_flags(field)));
3107
3139
  tee_puts("", PAGER);
3108
3140
}
3109
3141
 
 
3142
 
3110
3143
static void
3111
3144
print_table_data(drizzle_result_st *result)
3112
3145
{
3113
3146
  drizzle_row_t cur;
3114
3147
  drizzle_return_t ret;
3115
3148
  drizzle_column_st *field;
3116
 
  std::vector<bool> num_flag;
 
3149
  bool *num_flag;
3117
3150
  string separator;
3118
3151
 
3119
3152
  separator.reserve(256);
3120
3153
 
3121
 
  num_flag.resize(drizzle_result_column_count(result));
 
3154
  num_flag=(bool*) malloc(sizeof(bool)*drizzle_result_column_count(result));
3122
3155
  if (column_types_flag)
3123
3156
  {
3124
3157
    print_field_types(result);
3138
3171
      /* Check if the max_byte value is really the maximum in terms
3139
3172
         of visual length since multibyte characters can affect the
3140
3173
         length of the separator. */
3141
 
      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);
3142
3178
 
3143
3179
      if (name_length == drizzle_column_max_size(field))
3144
3180
      {
3176
3212
    for (uint32_t off=0; (field = drizzle_column_next(result)) ; off++)
3177
3213
    {
3178
3214
      uint32_t name_length= (uint32_t) strlen(drizzle_column_name(field));
3179
 
      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);
3180
3219
      uint32_t display_length= drizzle_column_max_size(field) + name_length -
3181
3220
                               numcells;
3182
3221
      tee_fprintf(PAGER, " %-*s |",(int) min(display_length,
3239
3278
        We need to find how much screen real-estate we will occupy to know how
3240
3279
        many extra padding-characters we should send with the printing function.
3241
3280
      */
3242
 
      visible_length= drizzled::utf8::char_length(buffer);
 
3281
      visible_length= charset_info->cset->numcells(charset_info, buffer, buffer + data_length);
3243
3282
      extra_padding= data_length - visible_length;
3244
3283
 
3245
3284
      if (field_max_length > MAX_COLUMN_LENGTH)
3259
3298
      drizzle_row_free(result, cur);
3260
3299
  }
3261
3300
  tee_puts(separator.c_str(), PAGER);
 
3301
  free(num_flag);
3262
3302
}
3263
3303
 
3264
3304
/**
3406
3446
  drizzle_row_t cur;
3407
3447
  uint64_t num_rows;
3408
3448
  uint32_t new_code= 0;
3409
 
  FILE *out;
3410
3449
 
3411
3450
  /* Get the warnings */
3412
3451
  query= "show warnings";
3432
3471
  }
3433
3472
 
3434
3473
  /* Print the warnings */
3435
 
  if (status.getBatch()) 
3436
 
  {
3437
 
    out= stderr;
3438
 
  } 
3439
 
  else 
3440
 
  {
3441
 
    init_pager();
3442
 
    out= PAGER;
3443
 
  }
 
3474
  init_pager();
3444
3475
  do
3445
3476
  {
3446
 
    tee_fprintf(out, "%s (Code %s): %s\n", cur[0], cur[1], cur[2]);
 
3477
    tee_fprintf(PAGER, "%s (Code %s): %s\n", cur[0], cur[1], cur[2]);
3447
3478
  } while ((cur= drizzle_row_next(&result)));
3448
 
 
3449
 
  if (not status.getBatch())
3450
 
    end_pager();
 
3479
  end_pager();
3451
3480
 
3452
3481
end:
3453
3482
  drizzle_result_free(&result);
3466
3495
    else for (const char *end=pos+length ; pos != end ; pos++)
3467
3496
    {
3468
3497
      int l;
3469
 
      if ((l = drizzled::utf8::sequence_length(*pos)))
 
3498
      if (use_mb(charset_info) &&
 
3499
          (l = my_ismbchar(charset_info, pos, end)))
3470
3500
      {
3471
3501
        while (l--)
3472
3502
          tee_putc(*pos++, PAGER);
3545
3575
 
3546
3576
  if (status.getBatch())
3547
3577
    return 0;
3548
 
  while (isspace(*line))
 
3578
  while (my_isspace(charset_info,*line))
3549
3579
    line++;
3550
 
  if (!(param =strchr(line, ' '))) // if outfile wasn't given, use the default
 
3580
  if (!(param = strchr(line, ' '))) // if outfile wasn't given, use the default
3551
3581
  {
3552
 
    if (outfile.empty())
 
3582
    if (!strlen(outfile))
3553
3583
    {
3554
 
      printf(_("No previous outfile available, you must give a filename!\n"));
 
3584
      printf("No previous outfile available, you must give a filename!\n");
3555
3585
      return 0;
3556
3586
    }
3557
3587
    else if (opt_outfile)
3558
3588
    {
3559
 
      tee_fprintf(stdout, _("Currently logging to file '%s'\n"), outfile.c_str());
 
3589
      tee_fprintf(stdout, "Currently logging to file '%s'\n", outfile);
3560
3590
      return 0;
3561
3591
    }
3562
3592
    else
3563
 
      param= outfile.c_str();      //resume using the old outfile
 
3593
      param = outfile;      //resume using the old outfile
3564
3594
  }
3565
3595
 
3566
 
  /* @TODO: Replace this with string methods */
3567
3596
  /* eliminate the spaces before the parameters */
3568
 
  while (isspace(*param))
 
3597
  while (my_isspace(charset_info,*param))
3569
3598
    param++;
3570
3599
  strncpy(file_name, param, sizeof(file_name) - 1);
3571
3600
  end= file_name + strlen(file_name);
3572
3601
  /* remove end space from command line */
3573
 
  while (end > file_name && (isspace(end[-1]) ||
3574
 
                             iscntrl(end[-1])))
 
3602
  while (end > file_name && (my_isspace(charset_info,end[-1]) ||
 
3603
                             my_iscntrl(charset_info,end[-1])))
3575
3604
    end--;
3576
3605
  end[0]= 0;
3577
3606
  if (end == file_name)
3578
3607
  {
3579
 
    printf(_("No outfile specified!\n"));
 
3608
    printf("No outfile specified!\n");
3580
3609
    return 0;
3581
3610
  }
3582
3611
  init_tee(file_name);
3589
3618
{
3590
3619
  if (opt_outfile)
3591
3620
    end_tee();
3592
 
  tee_fprintf(stdout, _("Outfile disabled.\n"));
 
3621
  tee_fprintf(stdout, "Outfile disabled.\n");
3593
3622
  return 0;
3594
3623
}
3595
3624
 
3600
3629
static int
3601
3630
com_pager(string *, const char *line)
3602
3631
{
 
3632
  char pager_name[FN_REFLEN], *end;
3603
3633
  const char *param;
3604
3634
 
3605
3635
  if (status.getBatch())
3606
3636
    return 0;
3607
3637
  /* Skip spaces in front of the pager command */
3608
 
  while (isspace(*line))
 
3638
  while (my_isspace(charset_info, *line))
3609
3639
    line++;
3610
3640
  /* Skip the pager command */
3611
3641
  param= strchr(line, ' ');
3612
3642
  /* Skip the spaces between the command and the argument */
3613
 
  while (param && isspace(*param))
 
3643
  while (param && my_isspace(charset_info, *param))
3614
3644
    param++;
3615
 
  if (!param || (*param == '\0')) // if pager was not given, use the default
 
3645
  if (!param || !strlen(param)) // if pager was not given, use the default
3616
3646
  {
3617
3647
    if (!default_pager_set)
3618
3648
    {
3619
 
      tee_fprintf(stdout, _("Default pager wasn't set, using stdout.\n"));
 
3649
      tee_fprintf(stdout, "Default pager wasn't set, using stdout.\n");
3620
3650
      opt_nopager=1;
3621
 
      pager.assign("stdout");
 
3651
      strcpy(pager, "stdout");
3622
3652
      PAGER= stdout;
3623
3653
      return 0;
3624
3654
    }
3625
 
    pager.assign(default_pager);
 
3655
    strcpy(pager, default_pager);
3626
3656
  }
3627
3657
  else
3628
3658
  {
3629
 
    string pager_name(param);
3630
 
    string::iterator end= pager_name.end();
3631
 
    while (end > pager_name.begin() &&
3632
 
           (isspace(*(end-1)) || iscntrl(*(end-1))))
3633
 
      --end;
3634
 
    pager_name.erase(end, pager_name.end());
3635
 
    pager.assign(pager_name);
3636
 
    default_pager.assign(pager_name);
 
3659
    end= strncpy(pager_name, param, sizeof(pager_name)-1);
 
3660
    end+= strlen(pager_name);
 
3661
    while (end > pager_name && (my_isspace(charset_info,end[-1]) ||
 
3662
                                my_iscntrl(charset_info,end[-1])))
 
3663
      end--;
 
3664
    end[0]=0;
 
3665
    strcpy(pager, pager_name);
 
3666
    strcpy(default_pager, pager_name);
3637
3667
  }
3638
3668
  opt_nopager=0;
3639
 
  tee_fprintf(stdout, _("PAGER set to '%s'\n"), pager.c_str());
 
3669
  tee_fprintf(stdout, "PAGER set to '%s'\n", pager);
3640
3670
  return 0;
3641
3671
}
3642
3672
 
3644
3674
static int
3645
3675
com_nopager(string *, const char *)
3646
3676
{
3647
 
  pager.assign("stdout");
 
3677
  strcpy(pager, "stdout");
3648
3678
  opt_nopager=1;
3649
3679
  PAGER= stdout;
3650
 
  tee_fprintf(stdout, _("PAGER set to stdout\n"));
 
3680
  tee_fprintf(stdout, "PAGER set to stdout\n");
3651
3681
  return 0;
3652
3682
}
3653
3683
 
3705
3735
    tmp= get_arg(buff, 0);
3706
3736
    if (tmp && *tmp)
3707
3737
    {
3708
 
      current_db.erase();
3709
 
      current_db.assign(tmp);
 
3738
      free(current_db);
 
3739
      current_db= strdup(tmp);
3710
3740
      tmp= get_arg(buff, 1);
3711
3741
      if (tmp)
3712
3742
      {
3713
 
        current_host.erase();
 
3743
        free(current_host);
3714
3744
        current_host=strdup(tmp);
3715
3745
      }
3716
3746
    }
3725
3755
  }
3726
3756
  else
3727
3757
    opt_rehash= 0;
3728
 
  error=sql_connect(current_host, current_db, current_user, opt_password,0);
 
3758
  error=sql_connect(current_host,current_db,current_user,opt_password,0);
3729
3759
  opt_rehash= save_rehash;
3730
3760
 
3731
3761
  if (connected)
3732
3762
  {
3733
 
    sprintf(buff, _("Connection id:    %u"), drizzle_con_thread_id(&con));
 
3763
    sprintf(buff,"Connection id:    %u",drizzle_con_thread_id(&con));
3734
3764
    put_info(buff,INFO_INFO,0,0);
3735
 
    sprintf(buff, _("Current database: %.128s\n"),
3736
 
            !current_db.empty() ? current_db.c_str() : _("*** NONE ***"));
 
3765
    sprintf(buff,"Current database: %.128s\n",
 
3766
            current_db ? current_db : "*** NONE ***");
3737
3767
    put_info(buff,INFO_INFO,0,0);
3738
3768
  }
3739
3769
  return error;
3750
3780
  FILE *sql_file;
3751
3781
 
3752
3782
  /* Skip space from file name */
3753
 
  while (isspace(*line))
 
3783
  while (my_isspace(charset_info,*line))
3754
3784
    line++;
3755
3785
  if (!(param = strchr(line, ' ')))    // Skip command name
3756
 
    return put_info(_("Usage: \\. <filename> | source <filename>"),
 
3786
    return put_info("Usage: \\. <filename> | source <filename>",
3757
3787
                    INFO_ERROR, 0,0);
3758
 
  while (isspace(*param))
 
3788
  while (my_isspace(charset_info,*param))
3759
3789
    param++;
3760
3790
  end= strncpy(source_name,param,sizeof(source_name)-1);
3761
3791
  end+= strlen(source_name);
3762
 
  while (end > source_name && (isspace(end[-1]) ||
3763
 
                               iscntrl(end[-1])))
 
3792
  while (end > source_name && (my_isspace(charset_info,end[-1]) ||
 
3793
                               my_iscntrl(charset_info,end[-1])))
3764
3794
    end--;
3765
3795
  end[0]=0;
3766
 
 
 
3796
  internal::unpack_filename(source_name,source_name);
3767
3797
  /* open file name */
3768
3798
  if (!(sql_file = fopen(source_name, "r")))
3769
3799
  {
3770
3800
    char buff[FN_REFLEN+60];
3771
 
    sprintf(buff, _("Failed to open file '%s', error: %d"), source_name,errno);
 
3801
    sprintf(buff,"Failed to open file '%s', error: %d", source_name,errno);
3772
3802
    return put_info(buff, INFO_ERROR, 0 ,0);
3773
3803
  }
3774
3804
 
3776
3806
  if (line_buff == NULL)
3777
3807
  {
3778
3808
    fclose(sql_file);
3779
 
    return put_info(_("Can't initialize LineBuffer"), INFO_ERROR, 0, 0);
 
3809
    return put_info("Can't initialize LineBuffer", INFO_ERROR, 0, 0);
3780
3810
  }
3781
3811
 
3782
3812
  /* Save old status */
3812
3842
 
3813
3843
  if (!tmp || !*tmp)
3814
3844
  {
3815
 
    put_info(_("DELIMITER must be followed by a 'delimiter' character or string"),
 
3845
    put_info("DELIMITER must be followed by a 'delimiter' character or string",
3816
3846
             INFO_ERROR, 0, 0);
3817
3847
    return 0;
3818
3848
  }
3820
3850
  {
3821
3851
    if (strstr(tmp, "\\"))
3822
3852
    {
3823
 
      put_info(_("DELIMITER cannot contain a backslash character"),
 
3853
      put_info("DELIMITER cannot contain a backslash character",
3824
3854
               INFO_ERROR, 0, 0);
3825
3855
      return 0;
3826
3856
    }
3845
3875
  tmp= get_arg(buff, 0);
3846
3876
  if (!tmp || !*tmp)
3847
3877
  {
3848
 
    put_info(_("USE must be followed by a database name"), INFO_ERROR, 0, 0);
 
3878
    put_info("USE must be followed by a database name", INFO_ERROR, 0, 0);
3849
3879
    return 0;
3850
3880
  }
3851
3881
  /*
3855
3885
  */
3856
3886
  get_current_db();
3857
3887
 
3858
 
  if (current_db.empty() || strcmp(current_db.c_str(),tmp))
 
3888
  if (!current_db || strcmp(current_db,tmp))
3859
3889
  {
3860
3890
    if (one_database)
3861
3891
    {
3907
3937
      else
3908
3938
        drizzle_result_free(&result);
3909
3939
    }
3910
 
    current_db.erase();
3911
 
    current_db.assign(tmp);
 
3940
    free(current_db);
 
3941
    current_db= strdup(tmp);
3912
3942
    if (select_db > 1)
3913
3943
      build_completion_hash(opt_rehash, 1);
3914
3944
  }
3915
3945
 
3916
 
  put_info(_("Database changed"),INFO_INFO, 0, 0);
 
3946
  put_info("Database changed",INFO_INFO, 0, 0);
3917
3947
  return 0;
3918
3948
}
3919
3949
 
3920
 
static int com_shutdown(string *, const char *)
3921
 
{
3922
 
  drizzle_result_st result;
3923
 
  drizzle_return_t ret;
3924
 
 
3925
 
  if (verbose)
3926
 
  {
3927
 
    printf(_("shutting down drizzled"));
3928
 
    if (opt_drizzle_port > 0)
3929
 
      printf(_(" on port %d"), opt_drizzle_port);
3930
 
    printf("... ");
3931
 
  }
3932
 
 
3933
 
  if (drizzle_shutdown(&con, &result, DRIZZLE_SHUTDOWN_DEFAULT,
3934
 
                       &ret) == NULL || ret != DRIZZLE_RETURN_OK)
3935
 
  {
3936
 
    if (ret == DRIZZLE_RETURN_ERROR_CODE)
3937
 
    {
3938
 
      fprintf(stderr, _("shutdown failed; error: '%s'"),
3939
 
              drizzle_result_error(&result));
3940
 
      drizzle_result_free(&result);
3941
 
    }
3942
 
    else
3943
 
    {
3944
 
      fprintf(stderr, _("shutdown failed; error: '%s'"),
3945
 
              drizzle_con_error(&con));
3946
 
    }
3947
 
    return false;
3948
 
  }
3949
 
 
3950
 
  drizzle_result_free(&result);
3951
 
 
3952
 
  if (verbose)
3953
 
    printf(_("done\n"));
3954
 
 
3955
 
  return false;
3956
 
}
3957
 
 
3958
3950
static int
3959
3951
com_warnings(string *, const char *)
3960
3952
{
3961
3953
  show_warnings = 1;
3962
 
  put_info(_("Show warnings enabled."),INFO_INFO, 0, 0);
 
3954
  put_info("Show warnings enabled.",INFO_INFO, 0, 0);
3963
3955
  return 0;
3964
3956
}
3965
3957
 
3967
3959
com_nowarnings(string *, const char *)
3968
3960
{
3969
3961
  show_warnings = 0;
3970
 
  put_info(_("Show warnings disabled."),INFO_INFO, 0, 0);
 
3962
  put_info("Show warnings disabled.",INFO_INFO, 0, 0);
3971
3963
  return 0;
3972
3964
}
3973
3965
 
3997
3989
  else
3998
3990
  {
3999
3991
    /* skip leading white spaces */
4000
 
    while (isspace(*ptr))
 
3992
    while (my_isspace(charset_info, *ptr))
4001
3993
      ptr++;
4002
3994
    if (*ptr == '\\') // short command was used
4003
3995
      ptr+= 2;
4004
3996
    else
4005
 
      while (*ptr &&!isspace(*ptr)) // skip command
 
3997
      while (*ptr &&!my_isspace(charset_info, *ptr)) // skip command
4006
3998
        ptr++;
4007
3999
  }
4008
4000
  if (!*ptr)
4009
4001
    return NULL;
4010
 
  while (isspace(*ptr))
 
4002
  while (my_isspace(charset_info, *ptr))
4011
4003
    ptr++;
4012
4004
  if (*ptr == '\'' || *ptr == '\"' || *ptr == '`')
4013
4005
  {
4034
4026
 
4035
4027
 
4036
4028
static int
4037
 
sql_connect(const string &host, const string &database, const string &user, const string &password,
 
4029
sql_connect(char *host,char *database,char *user,char *password,
4038
4030
                 uint32_t silent)
4039
4031
{
4040
4032
  drizzle_return_t ret;
 
4033
 
4041
4034
  if (connected)
4042
4035
  {
4043
4036
    connected= 0;
4045
4038
    drizzle_free(&drizzle);
4046
4039
  }
4047
4040
  drizzle_create(&drizzle);
4048
 
 
4049
 
#ifdef DRIZZLE_ADMIN_TOOL
4050
 
  drizzle_con_options_t options= (drizzle_con_options_t) (DRIZZLE_CON_ADMIN | (use_drizzle_protocol ? DRIZZLE_CON_EXPERIMENTAL : DRIZZLE_CON_MYSQL));
4051
 
#else
4052
 
  drizzle_con_options_t options= (drizzle_con_options_t) (use_drizzle_protocol ? DRIZZLE_CON_EXPERIMENTAL : DRIZZLE_CON_MYSQL);
4053
 
#endif
4054
 
 
4055
 
  if (drizzle_con_add_tcp(&drizzle, &con, (char *)host.c_str(),
4056
 
    opt_drizzle_port, (char *)user.c_str(),
4057
 
    (char *)password.c_str(), (char *)database.c_str(),
4058
 
    options) == NULL)
 
4041
  if (drizzle_con_add_tcp(&drizzle, &con, host, opt_drizzle_port, user,
 
4042
                          password, database, opt_mysql ? DRIZZLE_CON_MYSQL : DRIZZLE_CON_NONE) == NULL)
4059
4043
  {
4060
4044
    (void) put_error(&con, NULL);
4061
4045
    (void) fflush(stdout);
4111
4095
  drizzle_return_t ret;
4112
4096
 
4113
4097
  tee_puts("--------------", stdout);
4114
 
  printf(_("Drizzle client %s build %s, for %s-%s (%s) using readline %s\n"),
4115
 
         drizzle_version(), VERSION,
4116
 
         HOST_VENDOR, HOST_OS, HOST_CPU,
4117
 
         rl_library_version);
4118
 
 
 
4098
  usage(1);          /* Print version */
4119
4099
  if (connected)
4120
4100
  {
4121
 
    tee_fprintf(stdout, _("\nConnection id:\t\t%lu\n"),drizzle_con_thread_id(&con));
 
4101
    tee_fprintf(stdout, "\nConnection id:\t\t%lu\n",drizzle_con_thread_id(&con));
4122
4102
    /*
4123
4103
      Don't remove "limit 1",
4124
4104
      it is protection againts SQL_SELECT_LIMIT=0
4130
4110
      drizzle_row_t cur=drizzle_row_next(&result);
4131
4111
      if (cur)
4132
4112
      {
4133
 
        tee_fprintf(stdout, _("Current database:\t%s\n"), cur[0] ? cur[0] : "");
4134
 
        tee_fprintf(stdout, _("Current user:\t\t%s\n"), cur[1]);
 
4113
        tee_fprintf(stdout, "Current database:\t%s\n", cur[0] ? cur[0] : "");
 
4114
        tee_fprintf(stdout, "Current user:\t\t%s\n", cur[1]);
4135
4115
      }
4136
4116
      drizzle_result_free(&result);
4137
4117
    }
4138
4118
    else if (ret == DRIZZLE_RETURN_ERROR_CODE)
4139
4119
      drizzle_result_free(&result);
4140
 
    tee_puts(_("SSL:\t\t\tNot in use"), stdout);
 
4120
    tee_puts("SSL:\t\t\tNot in use", stdout);
4141
4121
  }
4142
4122
  else
4143
4123
  {
4144
4124
    vidattr(A_BOLD);
4145
 
    tee_fprintf(stdout, _("\nNo connection\n"));
 
4125
    tee_fprintf(stdout, "\nNo connection\n");
4146
4126
    vidattr(A_NORMAL);
4147
4127
    return 0;
4148
4128
  }
4149
4129
  if (skip_updates)
4150
4130
  {
4151
4131
    vidattr(A_BOLD);
4152
 
    tee_fprintf(stdout, _("\nAll updates ignored to this database\n"));
 
4132
    tee_fprintf(stdout, "\nAll updates ignored to this database\n");
4153
4133
    vidattr(A_NORMAL);
4154
4134
  }
4155
 
  tee_fprintf(stdout, _("Current pager:\t\t%s\n"), pager.c_str());
4156
 
  tee_fprintf(stdout, _("Using outfile:\t\t'%s'\n"), opt_outfile ? outfile.c_str() : "");
4157
 
  tee_fprintf(stdout, _("Using delimiter:\t%s\n"), delimiter);
4158
 
  tee_fprintf(stdout, _("Server version:\t\t%s\n"), server_version_string(&con));
4159
 
  tee_fprintf(stdout, _("Protocol:\t\t%s\n"), opt_protocol.c_str());
4160
 
  tee_fprintf(stdout, _("Protocol version:\t%d\n"), drizzle_con_protocol_version(&con));
4161
 
  tee_fprintf(stdout, _("Connection:\t\t%s\n"), drizzle_con_host(&con));
 
4135
  tee_fprintf(stdout, "Current pager:\t\t%s\n", pager);
 
4136
  tee_fprintf(stdout, "Using outfile:\t\t'%s'\n", opt_outfile ? outfile : "");
 
4137
  tee_fprintf(stdout, "Using delimiter:\t%s\n", delimiter);
 
4138
  tee_fprintf(stdout, "Server version:\t\t%s\n", server_version_string(&con));
 
4139
  tee_fprintf(stdout, "Protocol version:\t%d\n", drizzle_con_protocol_version(&con));
 
4140
  tee_fprintf(stdout, "Connection:\t\t%s\n", drizzle_con_host(&con));
4162
4141
/* XXX need to save this from result
4163
4142
  if ((id= drizzleclient_insert_id(&drizzle)))
4164
4143
    tee_fprintf(stdout, "Insert id:\t\t%s\n", internal::llstr(id, buff));
4165
4144
*/
4166
4145
 
4167
4146
  if (drizzle_con_uds(&con))
4168
 
    tee_fprintf(stdout, _("UNIX socket:\t\t%s\n"), drizzle_con_uds(&con));
 
4147
    tee_fprintf(stdout, "UNIX socket:\t\t%s\n", drizzle_con_uds(&con));
4169
4148
  else
4170
 
    tee_fprintf(stdout, _("TCP port:\t\t%d\n"), drizzle_con_port(&con));
 
4149
    tee_fprintf(stdout, "TCP port:\t\t%d\n", drizzle_con_port(&con));
4171
4150
 
4172
4151
  if (safe_updates)
4173
4152
  {
4174
4153
    vidattr(A_BOLD);
4175
 
    tee_fprintf(stdout, _("\nNote that you are running in safe_update_mode:\n"));
 
4154
    tee_fprintf(stdout, "\nNote that you are running in safe_update_mode:\n");
4176
4155
    vidattr(A_NORMAL);
4177
 
    tee_fprintf(stdout, _("\
 
4156
    tee_fprintf(stdout, "\
4178
4157
UPDATEs and DELETEs that don't use a key in the WHERE clause are not allowed.\n\
4179
4158
(One can force an UPDATE/DELETE by adding LIMIT # at the end of the command.)\n \
4180
4159
SELECT has an automatic 'LIMIT %lu' if LIMIT is not used.\n             \
4181
 
Max number of examined row combination in a join is set to: %lu\n\n"),
 
4160
Max number of examined row combination in a join is set to: %lu\n\n",
4182
4161
                select_limit, max_join_size);
4183
4162
  }
4184
4163
  tee_puts("--------------\n", stdout);
4236
4215
    if (info_type == INFO_ERROR)
4237
4216
    {
4238
4217
      (void) fflush(file);
4239
 
      fprintf(file,_("ERROR"));
 
4218
      fprintf(file,"ERROR");
4240
4219
      if (error)
4241
4220
      {
4242
4221
        if (sqlstate)
4279
4258
      if (error)
4280
4259
      {
4281
4260
        if (sqlstate)
4282
 
          (void) tee_fprintf(file, _("ERROR %d (%s): "), error, sqlstate);
 
4261
          (void) tee_fprintf(file, "ERROR %d (%s): ", error, sqlstate);
4283
4262
        else
4284
 
          (void) tee_fprintf(file, _("ERROR %d: "), error);
 
4263
          (void) tee_fprintf(file, "ERROR %d: ", error);
4285
4264
      }
4286
4265
      else
4287
 
        tee_puts(_("ERROR: "), file);
 
4266
        tee_puts("ERROR: ", file);
4288
4267
    }
4289
4268
    else
4290
4269
      vidattr(A_BOLD);
4323
4302
{
4324
4303
  const char *start=  buffer->c_str();
4325
4304
  const char *end= start + (buffer->length());
4326
 
  while (start < end && !isgraph(end[-1]))
 
4305
  while (start < end && !my_isgraph(charset_info,end[-1]))
4327
4306
    end--;
4328
4307
  uint32_t pos_to_truncate= (end-start);
4329
4308
  if (buffer->length() > pos_to_truncate)
4417
4396
    tmp_buff_str << tmp;
4418
4397
 
4419
4398
    if (tmp > 1)
4420
 
      tmp_buff_str << _(" hours ");
 
4399
      tmp_buff_str << " hours ";
4421
4400
    else
4422
 
      tmp_buff_str << _(" hour ");
 
4401
      tmp_buff_str << " hour ";
4423
4402
  }
4424
4403
  if (sec >= 60.0)
4425
4404
  {
4426
4405
    tmp=(uint32_t) floor(sec/60.0);
4427
4406
    sec-=60.0*tmp;
4428
 
    tmp_buff_str << tmp << _(" min ");
 
4407
    tmp_buff_str << tmp << " min ";
4429
4408
  }
4430
4409
  if (part_second)
4431
4410
    tmp_buff_str.precision(2);
4432
4411
  else
4433
4412
    tmp_buff_str.precision(0);
4434
 
  tmp_buff_str << sec << _(" sec");
 
4413
  tmp_buff_str << sec << " sec";
4435
4414
  strcpy(buff, tmp_buff_str.str().c_str());
4436
4415
}
4437
4416
 
4462
4441
  struct tm *t = localtime(&lclock);
4463
4442
 
4464
4443
  /* parse thru the settings for the prompt */
4465
 
  string::iterator c= current_prompt.begin();
4466
 
  while (c != current_prompt.end())
 
4444
  for (char *c= current_prompt; *c; (void)*c++)
4467
4445
  {
4468
4446
    if (*c != PROMPT_CHAR)
4469
4447
    {
4470
 
      processed_prompt->push_back(*c);
 
4448
      processed_prompt->append(c, 1);
4471
4449
    }
4472
4450
    else
4473
4451
    {
4478
4456
      switch (*++c) {
4479
4457
      case '\0':
4480
4458
        // stop it from going beyond if ends with %
4481
 
        --c;
 
4459
        c--;
4482
4460
        break;
4483
4461
      case 'c':
4484
4462
        add_int_to_prompt(++prompt_counter);
4490
4468
          processed_prompt->append("not_connected");
4491
4469
        break;
4492
4470
      case 'd':
4493
 
        processed_prompt->append(not current_db.empty() ? current_db : "(none)");
 
4471
        processed_prompt->append(current_db ? current_db : "(none)");
4494
4472
        break;
4495
4473
      case 'h':
4496
4474
      {
4497
 
        const char *prompt= connected ? drizzle_con_host(&con) : "not_connected";
 
4475
        const char *prompt;
 
4476
        prompt= connected ? drizzle_con_host(&con) : "not_connected";
4498
4477
        if (strstr(prompt, "Localhost"))
4499
4478
          processed_prompt->append("localhost");
4500
4479
        else
4526
4505
        if (!full_username)
4527
4506
          init_username();
4528
4507
        processed_prompt->append(full_username ? full_username :
4529
 
                                 (!current_user.empty() ?  current_user : "(unknown)"));
 
4508
                                 (current_user ?  current_user : "(unknown)"));
4530
4509
        break;
4531
4510
      case 'u':
4532
4511
        if (!full_username)
4533
4512
          init_username();
4534
4513
        processed_prompt->append(part_username ? part_username :
4535
 
                                 (!current_user.empty() ?  current_user : _("(unknown)")));
 
4514
                                 (current_user ?  current_user : "(unknown)"));
4536
4515
        break;
4537
4516
      case PROMPT_CHAR:
4538
4517
        {
4614
4593
        processed_prompt->append(delimiter_str);
4615
4594
        break;
4616
4595
      default:
4617
 
        processed_prompt->push_back(*c);
 
4596
        processed_prompt->append(c, 1);
4618
4597
      }
4619
4598
    }
4620
 
    ++c;
4621
4599
  }
4622
4600
  return processed_prompt->c_str();
4623
4601
}
4652
4630
{
4653
4631
  const char *ptr=strchr(line, ' ');
4654
4632
  if (ptr == NULL)
4655
 
    tee_fprintf(stdout, _("Returning to default PROMPT of %s\n"),
 
4633
    tee_fprintf(stdout, "Returning to default PROMPT of %s\n",
4656
4634
                default_prompt);
4657
4635
  prompt_counter = 0;
4658
4636
  char * tmpptr= strdup(ptr ? ptr+1 : default_prompt);
4659
4637
  if (tmpptr == NULL)
4660
 
    tee_fprintf(stdout, _("Memory allocation error. Not changing prompt\n"));
 
4638
    tee_fprintf(stdout, "Memory allocation error. Not changing prompt\n");
4661
4639
  else
4662
4640
  {
4663
 
    current_prompt.erase();
 
4641
    free(current_prompt);
4664
4642
    current_prompt= tmpptr;
4665
 
    tee_fprintf(stdout, _("PROMPT set to '%s'\n"), current_prompt.c_str());
 
4643
    tee_fprintf(stdout, "PROMPT set to '%s'\n", current_prompt);
4666
4644
  }
4667
4645
  return 0;
4668
4646
}