Merge lp:~vjsamuel/drizzle/refactor-drizzle into lp:~drizzle-trunk/drizzle/development

Proposed by Vijay Samuel
Status: Merged
Approved by: Brian Aker
Approved revision: 1584
Merged at revision: 1594
Proposed branch: lp:~vjsamuel/drizzle/refactor-drizzle
Merge into: lp:~drizzle-trunk/drizzle/development
Diff against target: 1221 lines (+458/-436)
2 files modified
client/drizzle.cc (+457/-435)
client/include.am (+1/-1)
To merge this branch: bzr merge lp:~vjsamuel/drizzle/refactor-drizzle
Reviewer Review Type Date Requested Status
Jay Pipes Pending
Brian Aker Pending
Monty Taylor Pending
Review via email: mp+26732@code.launchpad.net

This proposal supersedes a proposal from 2010-06-03.

To post a comment you must log in.
Revision history for this message
Jay Pipes (jaypipes) wrote : Posted in a previous version of this proposal

Hi Vijay!

Great work on refactoring the client to use program_options! It's great to see the use of mysys (drizzled::internal::) removed here.

Most of my comments are about naming and style. I've noticed you're a bit inconsistent in that area, so I'll try to point out a few things that need fixed :)

1)

put one and only one space between if|else|else if and the left parentheses.
put one space before and one space after comparison operators (==, !=, >, >=, etc)
put one space after negation operators (use if (! some_bool) or if (not some_bool))

You use a mix of a number of styles. For instance:

118 + if(in_connect_timeout>3600*12)
129 + if( in_max_input_line<4096 || in_max_input_line>(int64_t)2*1024L*1024L*1024L)
140 + if (s.find("--password")==0)
154 + if(s.substr(10)=="=")

Please go through and make sure you follow the style guidelines regarding proper spacing :)

Also, please be consistent in comment spacing...you use both this:

144 + //check if no argument is passed.
and
62 + // check if --password has quotes, remove quotes and return the value

Please use a space between // and the start of the comment

2.

Consider renaming the reg_password() function to something more descriptive, and placing a comment block before the function to indicate *why* that function exists and what it's doing so that developers hacking on the client can properly avoid all the pain you worked hard with Monty to work through! :)

Cheers!
jay

review: Needs Fixing
Revision history for this message
Monty Taylor (mordred) wrote : Posted in a previous version of this proposal

Mentioned on IRC, but for the record:

  error=sql_connect((char *)current_host.c_str(), (char *)current_db.c_str(), (char *)current_user.c_str(), (char *)opt_password.c_str(),0);

it might be nicer to change the sql_connect function to take arguments of const string& for host, db and current_user.

review: Needs Fixing
Revision history for this message
Stewart Smith (stewart) wrote : Posted in a previous version of this proposal

On Thu, 03 Jun 2010 10:41:05 -0000, Vijay Samuel <email address hidden> wrote:
> + return make_pair("password", "☃PASSWORD☃");

snowman? special characters probably shouldn't be in source.

--
Stewart Smith

Revision history for this message
Monty Taylor (mordred) wrote : Posted in a previous version of this proposal

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 06/03/2010 04:10 PM, Stewart Smith wrote:
> On Thu, 03 Jun 2010 10:41:05 -0000, Vijay Samuel <email address hidden> wrote:
>> + return make_pair("password", "☃PASSWORD☃");
>
> snowman? special characters probably shouldn't be in source.

We needed a sentinel string that was very unlikely to actually be used
in a password string. (side effect to how the program_options works) ...
This is our work around to mark the option as "didn't provide an option
- - please prompt for password"

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkwIQKMACgkQ2Jv7/VK1RgE87gCghfiHJ1+1tmhpZYg+kXdmPACv
GjMAoMV/0x9mvIEwhP9CBfm/JbXih64b
=QFpi
-----END PGP SIGNATURE-----

1584. By Vijay Samuel <vijay@vijay>

Merge fix for additional parser for --password.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'client/drizzle.cc' (properties changed: +x to -x)
2--- client/drizzle.cc 2010-05-25 15:23:24 +0000
3+++ client/drizzle.cc 2010-06-04 16:41:24 +0000
4@@ -37,6 +37,7 @@
5 #include <string>
6 #include <drizzled/gettext.h>
7 #include <iostream>
8+#include <fstream>
9 #include <map>
10 #include <algorithm>
11 #include <limits.h>
12@@ -139,9 +140,11 @@
13 #undef vidattr
14 #define vidattr(A) {} // Can't get this to work
15 #endif
16+#include <boost/program_options.hpp>
17
18 using namespace drizzled;
19 using namespace std;
20+namespace po=boost::program_options;
21
22 const string VER("14.14");
23 /* Don't try to make a nice table if the data is too big */
24@@ -149,9 +152,9 @@
25
26 /* Buffer to hold 'version' and 'version_comment' */
27 const int MAX_SERVER_VERSION_LENGTH= 128;
28+const string PASSWORD_SENTINEL("\0\0\0\0\0", 5);
29
30 #define PROMPT_CHAR '\\'
31-#define DEFAULT_DELIMITER ";"
32
33 class Status
34 {
35@@ -260,7 +263,6 @@
36 static map<string, string> completion_map;
37 static string completion_string;
38
39-static char **defaults_argv;
40
41 enum enum_info_type { INFO_INFO,INFO_ERROR,INFO_RESULT};
42 typedef enum enum_info_type INFO_TYPE;
43@@ -279,15 +281,14 @@
44 default_pager_set= false, opt_sigint_ignore= false,
45 auto_vertical_output= false,
46 show_warnings= false, executing_query= false, interrupted_query= false,
47- opt_mysql= false;
48-static uint32_t show_progress_size= 0;
49+ opt_mysql= false, opt_local_infile;
50+static uint32_t show_progress_size= 0;
51 static bool column_types_flag;
52 static bool preserve_comments= false;
53-static uint32_t opt_max_input_line, opt_drizzle_port= 0;
54-static int verbose= 0, opt_silent= 0, opt_local_infile= 0;
55+static uint32_t opt_max_input_line;
56+static uint32_t opt_drizzle_port= 0;
57+static int opt_silent, verbose= 0;
58 static drizzle_capabilities_t connect_flag= DRIZZLE_CAPABILITIES_NONE;
59-static char *current_host, *current_db, *current_user= NULL,
60- *opt_password= NULL, *delimiter_str= NULL, *current_prompt= NULL;
61 static char *histfile;
62 static char *histfile_tmp;
63 static string *glob_buffer;
64@@ -298,6 +299,14 @@
65 static uint32_t select_limit;
66 static uint32_t max_join_size;
67 static uint32_t opt_connect_timeout= 0;
68+std::string current_db,
69+ delimiter_str,
70+ current_host,
71+ current_prompt,
72+ current_user,
73+ opt_verbose,
74+ current_password,
75+ opt_password;
76 // TODO: Need to i18n these
77 static const char *day_names[]= {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
78 static const char *month_names[]= {"Jan","Feb","Mar","Apr","May","Jun","Jul",
79@@ -306,7 +315,7 @@
80 static char pager[FN_REFLEN], outfile[FN_REFLEN];
81 static FILE *PAGER, *OUTFILE;
82 static uint32_t prompt_counter;
83-static char delimiter[16]= DEFAULT_DELIMITER;
84+static char *delimiter= NULL;
85 static uint32_t delimiter_length= 1;
86 unsigned short terminal_width= 80;
87
88@@ -324,7 +333,7 @@
89 void tee_putc(int c, FILE *file);
90 static void tee_print_sized_data(const char *, unsigned int, unsigned int, bool);
91 /* The names of functions that actually do the manipulation. */
92-static int get_options(int argc,char **argv);
93+static int process_options(void);
94 static int com_quit(string *str,const char*),
95 com_go(string *str,const char*), com_ego(string *str,const char*),
96 com_print(string *str,const char*),
97@@ -338,7 +347,7 @@
98 com_nopager(string *str, const char*), com_pager(string *str, const char*);
99
100 static int read_and_execute(bool interactive);
101-static int sql_connect(char *host,char *database,char *user,char *password,
102+static int sql_connect(const string &host, const string &database, const string &user, const string &password,
103 uint32_t silent);
104 static const char *server_version_string(drizzle_con_st *con);
105 static int put_info(const char *str,INFO_TYPE info,uint32_t error,
106@@ -1157,7 +1166,6 @@
107 Commands((char *)NULL, 0, 0, 0, "")
108 };
109
110-static const char *load_default_groups[]= { "drizzle","client",0 };
111
112 int history_length;
113 static int not_in_history(const char *line);
114@@ -1300,8 +1308,72 @@
115 return executed;
116 }
117
118+static void check_timeout_value(uint32_t in_connect_timeout)
119+{
120+ opt_connect_timeout= 0;
121+ if (in_connect_timeout > 3600*12)
122+ {
123+ cout<<N_("Error: Invalid Value for connect_timeout");
124+ exit(-1);
125+ }
126+ opt_connect_timeout= in_connect_timeout;
127+}
128+
129+static void check_max_input_line(uint32_t in_max_input_line)
130+{
131+ opt_max_input_line= 0;
132+ if (in_max_input_line<4096 || in_max_input_line>(int64_t)2*1024L*1024L*1024L)
133+ {
134+ cout<<N_("Error: Invalid Value for max_input_line");
135+ exit(-1);
136+ }
137+ opt_max_input_line= in_max_input_line/1024;
138+ opt_max_input_line*=1024;
139+}
140+
141+static pair<string, string> parse_password_arg(std::string s)
142+{
143+ if (s.find("--password") == 0)
144+ {
145+ if (s == "--password")
146+ {
147+ tty_password= true;
148+ //check if no argument is passed.
149+ return make_pair("password", PASSWORD_SENTINEL);
150+ }
151+
152+ if (s.substr(10,3) == "=\"\"" || s.substr(10,3) == "=''")
153+ {
154+ // Check if --password="" or --password=''
155+ return make_pair("password", PASSWORD_SENTINEL);
156+ }
157+
158+ if(s.substr(10) == "=" && s.length() == 11)
159+ {
160+ // check if --password= and return a default value
161+ return make_pair("password", PASSWORD_SENTINEL);
162+ }
163+
164+ if(s.length()>12 && (s[10] == '"' || s[10] == '\''))
165+ {
166+ // check if --password has quotes, remove quotes and return the value
167+ return make_pair("password", s.substr(11,s.length()-1));
168+ }
169+
170+ // if all above are false, it implies that --password=value, return value.
171+ return make_pair("password", s.substr(11));
172+ }
173+
174+ else
175+ {
176+ return make_pair(string(""), string(""));
177+ }
178+}
179+
180 int main(int argc,char *argv[])
181 {
182+try
183+{
184 #if defined(ENABLE_NLS)
185 # if defined(HAVE_LOCALE_H)
186 setlocale(LC_ALL, "");
187@@ -1310,12 +1382,160 @@
188 textdomain("drizzle");
189 #endif
190
191- MY_INIT(argv[0]);
192- delimiter_str= delimiter;
193+ po::options_description commandline_options("Options used only in command line");
194+ commandline_options.add_options()
195+ ("help,?",N_("Displays this help and exit."))
196+ ("batch,B",N_("Don't use history file. Disable interactive behavior. (Enables --silent)"))
197+ ("column-type-info", po::value<bool>(&column_types_flag)->default_value(false)->zero_tokens(),
198+ N_("Display column type information."))
199+ ("comments,c", po::value<bool>(&preserve_comments)->default_value(false)->zero_tokens(),
200+ N_("Preserve comments. Send comments to the server. The default is --skip-comments (discard comments), enable with --comments"))
201+ ("compress,C", po::value<bool>(&opt_compress)->default_value(false)->zero_tokens(),
202+ N_("Use compression in server/client protocol."))
203+ ("vertical,E", po::value<bool>(&vertical)->default_value(false)->zero_tokens(),
204+ N_("Print the output of a query (rows) vertically."))
205+ ("force,f", po::value<bool>(&ignore_errors)->default_value(false)->zero_tokens(),
206+ N_("Continue even if we get an sql error."))
207+ ("named-commands,G", po::value<bool>(&named_cmds)->default_value(false)->zero_tokens(),
208+ 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."))
209+ ("no-named-commands,g",
210+ 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."))
211+ ("ignore-spaces,i", N_("Ignore space after function names."))
212+ ("no-beep,b", po::value<bool>(&opt_nobeep)->default_value(false)->zero_tokens(),
213+ N_("Turn off beep on error."))
214+ ("line-numbers", po::value<bool>(&line_numbers)->default_value(true)->zero_tokens(),
215+ N_("Write line numbers for errors."))
216+ ("skip-line-numbers,L",
217+ N_("Don't write line number for errors. WARNING: -L is deprecated, use long version of this option instead."))
218+ ("column-name", po::value<bool>(&column_names)->default_value(true)->zero_tokens(),
219+ N_("Write column names in results."))
220+ ("skip-column-names,N",
221+ N_("Don't write column names in results. WARNING: -N is deprecated, use long version of this options instead."))
222+ ("set-variable,O", po::value<string>(),
223+ N_("Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value."))
224+ ("table,t", po::value<bool>(&output_tables)->default_value(false)->zero_tokens(),
225+ N_("Output in table format."))
226+ ("safe-updates,U", po::value<bool>(&safe_updates)->default_value(0)->zero_tokens(),
227+ N_("Only allow UPDATE and DELETE that uses keys."))
228+ ("i-am-a-dummy,U", po::value<bool>(&safe_updates)->default_value(0)->zero_tokens(),
229+ N_("Synonym for option --safe-updates, -U."))
230+ ("verbose,v", po::value<string>(&opt_verbose)->default_value(""),
231+ N_("-v vvv implies that verbose= 3, Used to specify verbose"))
232+ ("version,V", N_("Output version information and exit."))
233+ ("secure-auth", po::value<bool>(&opt_secure_auth)->default_value(false)->zero_tokens(),
234+ N_("Refuse client connecting to server if it uses old (pre-4.1.1) protocol"))
235+ ("show-warnings", po::value<bool>(&show_warnings)->default_value(false)->zero_tokens(),
236+ N_("Show warnings after every statement."))
237+ ("show-progress-size", po::value<uint32_t>(&show_progress_size)->default_value(0),
238+ N_("Number of lines before each import progress report."))
239+ ("ping", po::value<bool>(&opt_ping)->default_value(false)->zero_tokens(),
240+ N_("Ping the server to check if it's alive."))
241+ ("no-defaults", po::value<bool>()->default_value(false)->zero_tokens(),
242+ N_("Configuration file defaults are not used if no-defaults is set"))
243+ ;
244+
245+ po::options_description drizzle_options("Options specific to the drizzle client");
246+ drizzle_options.add_options()
247+ ("auto-rehash", po::value<bool>(&opt_rehash)->default_value(true)->zero_tokens(),
248+ 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."))
249+ ("no-auto-rehash,A",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."))
250+ ("auto-vertical-output", po::value<bool>(&auto_vertical_output)->default_value(false)->zero_tokens(),
251+ N_("Automatically switch to vertical output mode if the result is wider than the terminal width."))
252+ ("database,D", po::value<string>(&current_db)->default_value("test"),
253+ N_("Database to use."))
254+ ("default-character-set",po::value<string>(),
255+ N_("(not used)"))
256+ ("delimiter", po::value<string>(&delimiter_str)->default_value(";"),
257+ N_("Delimiter to be used."))
258+ ("execute,e", po::value<string>(),
259+ N_("Execute command and quit. (Disables --force and history file)"))
260+ ("local-infile", po::value<bool>(&opt_local_infile)->default_value(false)->zero_tokens(),
261+ N_("Enable/disable LOAD DATA LOCAL INFILE."))
262+ ("unbuffered,n", po::value<bool>(&unbuffered)->default_value(false)->zero_tokens(),
263+ N_("Flush buffer after each query."))
264+ ("sigint-ignore", po::value<bool>(&opt_sigint_ignore)->default_value(false)->zero_tokens(),
265+ N_("Ignore SIGINT (CTRL-C)"))
266+ ("one-database,o", po::value<bool>(&one_database)->default_value(false)->zero_tokens(),
267+ N_("Only update the default database. This is useful for skipping updates to other database in the update log."))
268+ ("pager", po::value<string>(),
269+ 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."))
270+ ("disable-pager", po::value<bool>(&opt_nopager)->default_value(false)->zero_tokens(),
271+ N_("Disable pager and print to stdout. See interactive help (\\h) also."))
272+ ("prompt", po::value<string>(&current_prompt)->default_value(""),
273+ N_("Set the drizzle prompt to this value."))
274+ ("quick,q", po::value<bool>(&quick)->default_value(false)->zero_tokens(),
275+ 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."))
276+ ("raw,r", po::value<bool>(&opt_raw_data)->default_value(false)->zero_tokens(),
277+ N_("Write fields without conversion. Used with --batch."))
278+ ("reconnect", po::value<bool>(&opt_reconnect)->default_value(true)->zero_tokens(),
279+ N_("Reconnect if the connection is lost. Disable with --disable-reconnect. This option is enabled by default."))
280+ ("shutdown", po::value<bool>(&opt_shutdown)->default_value(false)->zero_tokens(),
281+ N_("Shutdown the server"))
282+ ("silent,s", N_("Be more silent. Print results with a tab as separator, each row on new line."))
283+ ("tee", po::value<string>(),
284+ 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."))
285+ ("disable-tee", po::value<bool>()->default_value(false)->zero_tokens(),
286+ N_("Disable outfile. See interactive help (\\h) also."))
287+ ("wait,w", N_("Wait and retry if connection is down."))
288+ ("connect_timeout", po::value<uint32_t>(&opt_connect_timeout)->default_value(0)->notifier(&check_timeout_value),
289+ N_("Number of seconds before connection timeout."))
290+ ("max_input_line", po::value<uint32_t>(&opt_max_input_line)->default_value(16*1024L*1024L)->notifier(&check_max_input_line),
291+ N_("Max length of input line"))
292+ ("select_limit", po::value<uint32_t>(&select_limit)->default_value(1000L),
293+ N_("Automatic limit for SELECT when using --safe-updates"))
294+ ("max_join_size", po::value<uint32_t>(&max_join_size)->default_value(1000000L),
295+ N_("Automatic limit for rows in a join when using --safe-updates"))
296+ ;
297+
298+ po::options_description client_options("Options specific to the client");
299+ client_options.add_options()
300+ ("mysql,m", po::value<bool>(&opt_mysql)->default_value(true)->zero_tokens(),
301+ N_("Use MySQL Protocol."))
302+ ("host,h", po::value<string>(&current_host)->default_value("localhost"),
303+ N_("Connect to host"))
304+ ("password,P", po::value<string>(&current_password)->default_value(PASSWORD_SENTINEL),
305+ N_("Password to use when connecting to server. If password is not given it's asked from the tty."))
306+ ("port,p", po::value<uint32_t>()->default_value(3306),
307+ N_("Port number to use for connection or 0 for default to, in order of preference, drizzle.cnf, $DRIZZLE_TCP_PORT, built-in default"))
308+ ("user,u", po::value<string>(&current_user)->default_value(""),
309+ N_("User for login if not current user."))
310+ ("protocol",po::value<string>(),
311+ N_("The protocol of connection (tcp,socket,pipe,memory)."))
312+ ;
313+
314+ po::options_description long_options("Allowed Options");
315+ long_options.add(commandline_options).add(drizzle_options).add(client_options);
316+
317+ std::string system_config_dir_drizzle(SYSCONFDIR);
318+ system_config_dir_drizzle.append("/drizzle/drizzle.cnf");
319+
320+ std::string system_config_dir_client(SYSCONFDIR);
321+ system_config_dir_client.append("/drizzle/client.cnf");
322+
323+ po::variables_map vm;
324+
325+ po::store(po::command_line_parser(argc, argv).options(long_options).extra_parser(parse_password_arg).run(), vm);
326+
327+ if (! vm["no-defaults"].as<bool>())
328+ {
329+ ifstream user_drizzle_ifs("~/.drizzle/drizzleslap.cnf");
330+ po::store(parse_config_file(user_drizzle_ifs, drizzle_options), vm);
331+
332+ ifstream system_drizzle_ifs(system_config_dir_drizzle.c_str());
333+ store(parse_config_file(system_drizzle_ifs, drizzle_options), vm);
334+
335+ ifstream user_client_ifs("~/.drizzle/client.cnf");
336+ po::store(parse_config_file(user_client_ifs, client_options), vm);
337+
338+ ifstream system_client_ifs(system_config_dir_client.c_str());
339+ po::store(parse_config_file(system_client_ifs, client_options), vm);
340+ }
341+
342+ po::notify(vm);
343+
344 default_prompt= strdup(getenv("DRIZZLE_PS1") ?
345 getenv("DRIZZLE_PS1") :
346 "drizzle> ");
347-
348 if (default_prompt == NULL)
349 {
350 fprintf(stderr, _("Memory allocation error while constructing initial "
351@@ -1323,7 +1543,7 @@
352 exit(ENOMEM);
353 }
354 current_prompt= strdup(default_prompt);
355- if (current_prompt == NULL)
356+ if (current_prompt.empty())
357 {
358 fprintf(stderr, _("Memory allocation error while constructing initial "
359 "prompt. Aborting.\n"));
360@@ -1344,7 +1564,7 @@
361 strcpy(default_pager, tmp);
362 }
363 }
364- if (!isatty(0) || !isatty(1))
365+ if (! isatty(0) || ! isatty(1))
366 {
367 status.setBatch(1); opt_silent=1;
368 ignore_errors=0;
369@@ -1367,18 +1587,187 @@
370 close(stdout_fileno_copy); /* Clean up dup(). */
371 }
372
373- internal::load_defaults("drizzle",load_default_groups,&argc,&argv);
374- defaults_argv=argv;
375- if (get_options(argc, (char **) argv))
376- {
377- internal::free_defaults(defaults_argv);
378- internal::my_end();
379+ if (vm.count("default-character-set"))
380+ default_charset_used= 1;
381+
382+ if (vm.count("delimiter"))
383+ {
384+ /* Check that delimiter does not contain a backslash */
385+ if (! strstr(delimiter_str.c_str(), "\\"))
386+ {
387+ delimiter= (char *)delimiter_str.c_str();
388+ }
389+ else
390+ {
391+ put_info(_("DELIMITER cannot contain a backslash character"),
392+ INFO_ERROR,0,0);
393+ exit(-1);
394+ }
395+
396+ delimiter_length= (uint32_t)strlen(delimiter);
397+ }
398+ if (vm.count("tee"))
399+ {
400+ if (vm["tee"].as<string>().empty())
401+ {
402+ if (opt_outfile)
403+ end_tee();
404+ }
405+ else
406+ init_tee(vm["tee"].as<string>().c_str());
407+ }
408+ if (vm["disable-tee"].as<bool>() == true)
409+ {
410+ if (opt_outfile)
411+ end_tee();
412+ }
413+ if (vm.count("pager"))
414+ {
415+ if (vm["pager"].as<string>().empty())
416+ opt_nopager= 1;
417+ else
418+ {
419+ opt_nopager= 0;
420+ if (vm[pager].as<string>().length())
421+ {
422+ default_pager_set= 1;
423+ strncpy(pager, vm["pager"].as<string>().c_str(), sizeof(pager) - 1);
424+ strcpy(default_pager, pager);
425+ }
426+ else if (default_pager_set)
427+ strcpy(pager, default_pager);
428+ else
429+ opt_nopager= 1;
430+ }
431+ }
432+ if (vm.count("disable-pager"))
433+ {
434+ opt_nopager= 1;
435+ }
436+
437+ if (vm.count("no-auto-rehash"))
438+ opt_rehash= 0;
439+
440+ if (vm.count("skip-column-names"))
441+ column_names= 0;
442+
443+ if (vm.count("execute"))
444+ {
445+ status.setBatch(1);
446+ status.setAddToHistory(1);
447+ if (status.getLineBuff() == NULL)
448+ status.setLineBuff(opt_max_input_line,NULL);
449+ if (status.getLineBuff() == NULL)
450+ {
451+ internal::my_end();
452+ exit(1);
453+ }
454+ status.getLineBuff()->addString(vm["execute"].as<string>().c_str());
455+ }
456+
457+ if (one_database)
458+ skip_updates= true;
459+
460+ if (vm.count("port"))
461+ {
462+ opt_drizzle_port= vm["port"].as<uint32_t>();
463+
464+ /* If the port number is > 65535 it is not a valid port
465+ This also helps with potential data loss casting unsigned long to a
466+ uint32_t. */
467+ if ((opt_drizzle_port == 0) || (opt_drizzle_port > 65535))
468+ {
469+ printf(_("Error: Value of %" PRIu32 " supplied for port is not valid.\n"), opt_drizzle_port);
470+ exit(-1);
471+ }
472+ }
473+
474+ if (vm.count("password"))
475+ {
476+ if (!opt_password.empty())
477+ opt_password.erase();
478+ if (current_password == PASSWORD_SENTINEL)
479+ {
480+ opt_password= "";
481+ }
482+ else
483+ {
484+ opt_password= current_password;
485+ tty_password= false;
486+ }
487+ char *start= (char *)current_password.c_str();
488+ char *temp_pass= (char *)current_password.c_str();
489+ while (*temp_pass)
490+ {
491+ /* Overwriting password with 'x' */
492+ *temp_pass++= 'x';
493+ }
494+ if (*start)
495+ {
496+ start[1]= 0;
497+ }
498+ }
499+ else
500+ {
501+ tty_password= true;
502+ }
503+
504+
505+ if (!opt_verbose.empty())
506+ {
507+ verbose= opt_verbose.length();
508+ }
509+
510+ if (vm.count("batch"))
511+ {
512+ status.setBatch(1);
513+ status.setAddToHistory(0);
514+ set_if_bigger(opt_silent,1); // more silent
515+ }
516+ if (vm.count("silent"))
517+ {
518+ opt_silent++;
519+ }
520+ if (vm.count("version"))
521+ {
522+ printf(_("%s Ver %s Distrib %s, for %s-%s (%s) using readline %s\n"),
523+ internal::my_progname, VER.c_str(), drizzle_version(),
524+ HOST_VENDOR, HOST_OS, HOST_CPU,
525+ rl_library_version);
526+
527+ exit(0);
528+ }
529+
530+ if (vm.count("help"))
531+ {
532+ printf(_("%s Ver %s Distrib %s, for %s-%s (%s) using readline %s\n"),
533+ internal::my_progname, VER.c_str(), drizzle_version(),
534+ HOST_VENDOR, HOST_OS, HOST_CPU,
535+ rl_library_version);
536+ printf(_("Copyright (C) 2008 Sun Microsystems\n"
537+ "This software comes with ABSOLUTELY NO WARRANTY. "
538+ "This is free software,\n"
539+ "and you are welcome to modify and redistribute it "
540+ "under the GPL license\n"));
541+ printf(_("Usage: %s [OPTIONS] [database]\n"), internal::my_progname);
542+ cout<<long_options;
543+ exit(0);
544+ }
545+
546+
547+ if (process_options())
548+ {
549 exit(1);
550 }
551
552+ if (argc == 1)
553+ {
554+ skip_updates= 0;
555+ current_db.erase();
556+ current_db= strdup(*argv);
557+ }
558 memset(&drizzle, 0, sizeof(drizzle));
559- if (sql_connect(current_host,current_db,current_user,opt_password,
560- opt_silent))
561+ if (sql_connect(current_host, current_db, current_user, opt_password,opt_silent))
562 {
563 quick= 1; // Avoid history
564 status.setExitStatus(1);
565@@ -1389,8 +1778,6 @@
566 if (execute_commands(&command_error) != false)
567 {
568 /* we've executed a command so exit before we go into readline mode */
569- internal::free_defaults(defaults_argv);
570- internal::my_end();
571 exit(command_error);
572 }
573
574@@ -1399,8 +1786,6 @@
575 status.setLineBuff(opt_max_input_line, stdin);
576 if (status.getLineBuff() == NULL)
577 {
578- internal::free_defaults(defaults_argv);
579- internal::my_end();
580 exit(1);
581 }
582 }
583@@ -1436,7 +1821,7 @@
584 server_version_string(&con));
585 put_info(output_buff, INFO_INFO, 0, 0);
586
587- initialize_readline(current_prompt);
588+ initialize_readline((char *)current_prompt.c_str());
589 if (!status.getBatch() && !quick)
590 {
591 /* read-history from file, default ~/.drizzle_history*/
592@@ -1480,7 +1865,12 @@
593 if (opt_outfile)
594 end_tee();
595 drizzle_end(0);
596+}
597
598+ catch(exception &err)
599+ {
600+ cerr<<"Error:"<<err.what()<<endl;
601+ }
602 return(0); // Keep compiler happy
603 }
604
605@@ -1505,18 +1895,16 @@
606 delete glob_buffer;
607 if (processed_prompt)
608 delete processed_prompt;
609- free(opt_password);
610+ opt_password.erase();
611 free(histfile);
612 free(histfile_tmp);
613- free(current_db);
614- free(current_host);
615- free(current_user);
616+ current_db.erase();
617+ current_host.erase();
618+ current_user.erase();
619 free(full_username);
620 free(part_username);
621 free(default_prompt);
622- free(current_prompt);
623- internal::free_defaults(defaults_argv);
624- internal::my_end();
625+ current_prompt.erase();
626 exit(status.getExitStatus());
627 }
628
629@@ -1539,8 +1927,8 @@
630 goto err;
631 }
632
633- if (drizzle_con_add_tcp(&drizzle, &kill_drizzle, current_host,
634- opt_drizzle_port, current_user, opt_password, NULL,
635+ if (drizzle_con_add_tcp(&drizzle, &kill_drizzle, current_host.c_str(),
636+ opt_drizzle_port, current_user.c_str(), opt_password.c_str(), NULL,
637 opt_mysql ? DRIZZLE_CON_MYSQL : DRIZZLE_CON_NONE) == NULL)
638 {
639 goto err;
640@@ -1575,369 +1963,12 @@
641 }
642 #endif
643
644-static struct option my_long_options[] =
645-{
646- {"help", '?', N_("Display this help and exit."), 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
647- 0, 0, 0, 0, 0},
648- {"help", 'I', N_("Synonym for -?"), 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
649- 0, 0, 0, 0, 0},
650- {"auto-rehash", OPT_AUTO_REHASH,
651- 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."),
652- (char**) &opt_rehash, (char**) &opt_rehash, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0,
653- 0, 0},
654- {"no-auto-rehash", 'A',
655- 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."),
656- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
657- {"auto-vertical-output", OPT_AUTO_VERTICAL_OUTPUT,
658- N_("Automatically switch to vertical output mode if the result is wider than the terminal width."),
659- (char**) &auto_vertical_output, (char**) &auto_vertical_output, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
660- {"batch", 'B',
661- 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},
662- {"column-type-info", OPT_COLUMN_TYPES, N_("Display column type information."),
663- (char**) &column_types_flag, (char**) &column_types_flag,
664- 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
665- {"comments", 'c', N_("Preserve comments. Send comments to the server. The default is --skip-comments (discard comments), enable with --comments"),
666- (char**) &preserve_comments, (char**) &preserve_comments,
667- 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
668- {"compress", 'C', N_("Use compression in server/client protocol."),
669- (char**) &opt_compress, (char**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
670- 0, 0, 0},
671- {"database", 'D', N_("Database to use."), (char**) &current_db,
672- (char**) &current_db, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
673- {"default-character-set", OPT_DEFAULT_CHARSET,
674- N_("(not used)"), 0,
675- 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
676- {"delimiter", OPT_DELIMITER, N_("Delimiter to be used."), (char**) &delimiter_str,
677- (char**) &delimiter_str, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
678- {"execute", 'e', N_("Execute command and quit. (Disables --force and history file)"), 0,
679- 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
680- {"vertical", 'E', N_("Print the output of a query (rows) vertically."),
681- (char**) &vertical, (char**) &vertical, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
682- 0},
683- {"force", 'f', N_("Continue even if we get an sql error."),
684- (char**) &ignore_errors, (char**) &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0,
685- 0, 0, 0, 0},
686- {"named-commands", 'G',
687- 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."),
688- (char**) &named_cmds, (char**) &named_cmds, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
689- 0, 0},
690- {"no-named-commands", 'g',
691- 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."),
692- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
693- {"ignore-spaces", 'i', N_("Ignore space after function names."), 0, 0, 0,
694- GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
695- {"local-infile", OPT_LOCAL_INFILE, N_("Enable/disable LOAD DATA LOCAL INFILE."),
696- (char**) &opt_local_infile,
697- (char**) &opt_local_infile, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
698- {"no-beep", 'b', N_("Turn off beep on error."), (char**) &opt_nobeep,
699- (char**) &opt_nobeep, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
700- {"host", 'h', N_("Connect to host."), (char**) &current_host,
701- (char**) &current_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
702- {"line-numbers", OPT_LINE_NUMBERS, N_("Write line numbers for errors."),
703- (char**) &line_numbers, (char**) &line_numbers, 0, GET_BOOL,
704- NO_ARG, 1, 0, 0, 0, 0, 0},
705- {"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,
706- NO_ARG, 0, 0, 0, 0, 0, 0},
707- {"unbuffered", 'n', N_("Flush buffer after each query."), (char**) &unbuffered,
708- (char**) &unbuffered, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
709- {"column-names", OPT_COLUMN_NAMES, N_("Write column names in results."),
710- (char**) &column_names, (char**) &column_names, 0, GET_BOOL,
711- NO_ARG, 1, 0, 0, 0, 0, 0},
712- {"skip-column-names", 'N',
713- N_("Don't write column names in results. WARNING: -N is deprecated, use long version of this options instead."),
714- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
715- {"set-variable", 'O',
716- N_("Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value."),
717- 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
718- {"sigint-ignore", OPT_SIGINT_IGNORE, N_("Ignore SIGINT (CTRL-C)"),
719- (char**) &opt_sigint_ignore, (char**) &opt_sigint_ignore, 0, GET_BOOL,
720- NO_ARG, 0, 0, 0, 0, 0, 0},
721- {"one-database", 'o',
722- N_("Only update the default database. This is useful for skipping updates to other database in the update log."),
723- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
724- {"pager", OPT_PAGER,
725- 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."),
726- 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
727- {"no-pager", OPT_NOPAGER,
728- N_("Disable pager and print to stdout. See interactive help (\\h) also. WARNING: option deprecated; use --disable-pager instead."),
729- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
730- {"password", 'P',
731- N_("Password to use when connecting to server. If password is not given it's asked from the tty."),
732- 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
733- {"port", 'p', N_("Port number to use for connection or 0 for default to, in order of preference, drizzle.cnf, $DRIZZLE_TCP_PORT, ")
734- N_("built-in default") " (" STRINGIFY_ARG(DRIZZLE_PORT) ").",
735- 0, 0, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
736- {"prompt", OPT_PROMPT, N_("Set the drizzle prompt to this value."),
737- (char**) &current_prompt, (char**) &current_prompt, 0, GET_STR_ALLOC,
738- REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
739- {"quick", 'q',
740- 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."),
741- (char**) &quick, (char**) &quick, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
742- {"raw", 'r', N_("Write fields without conversion. Used with --batch."),
743- (char**) &opt_raw_data, (char**) &opt_raw_data, 0, GET_BOOL, NO_ARG, 0, 0, 0,
744- 0, 0, 0},
745- {"reconnect", OPT_RECONNECT, N_("Reconnect if the connection is lost. Disable with --disable-reconnect. This option is enabled by default."),
746- (char**) &opt_reconnect, (char**) &opt_reconnect, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
747- {"shutdown", OPT_SHUTDOWN, N_("Shutdown the server."),
748- (char**) &opt_shutdown, (char**) &opt_shutdown, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
749- {"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,
750- 0, 0},
751- {"table", 't', N_("Output in table format."), (char**) &output_tables,
752- (char**) &output_tables, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
753- {"tee", OPT_TEE,
754- 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."),
755- 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
756- {"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,
757- NO_ARG, 0, 0, 0, 0, 0, 0},
758- {"user", 'u', N_("User for login if not current user."), (char**) &current_user,
759- (char**) &current_user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
760- {"safe-updates", 'U', N_("Only allow UPDATE and DELETE that uses keys."),
761- (char**) &safe_updates, (char**) &safe_updates, 0, GET_BOOL, NO_ARG, 0, 0,
762- 0, 0, 0, 0},
763- {"i-am-a-dummy", 'U', N_("Synonym for option --safe-updates, -U."),
764- (char**) &safe_updates, (char**) &safe_updates, 0, GET_BOOL, NO_ARG, 0, 0,
765- 0, 0, 0, 0},
766- {"verbose", 'v', N_("Write more. (-v -v -v gives the table output format)."), 0,
767- 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
768- {"version", 'V', N_("Output version information and exit."), 0, 0, 0,
769- GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
770- {"wait", 'w', N_("Wait and retry if connection is down."), 0, 0, 0, GET_NO_ARG,
771- NO_ARG, 0, 0, 0, 0, 0, 0},
772- {"connect_timeout", OPT_CONNECT_TIMEOUT,
773- N_("Number of seconds before connection timeout."),
774- (char**) &opt_connect_timeout,
775- (char**) &opt_connect_timeout, 0, GET_UINT32, REQUIRED_ARG, 0, 0, 3600*12, 0,
776- 0, 0},
777- {"max_input_line", OPT_MAX_INPUT_LINE,
778- N_("Max length of input line"),
779- (char**) &opt_max_input_line, (char**) &opt_max_input_line, 0,
780- GET_UINT32, REQUIRED_ARG, 16 *1024L*1024L, 4096,
781- (int64_t) 2*1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
782- {"select_limit", OPT_SELECT_LIMIT,
783- N_("Automatic limit for SELECT when using --safe-updates"),
784- (char**) &select_limit,
785- (char**) &select_limit, 0, GET_UINT32, REQUIRED_ARG, 1000L, 1, ULONG_MAX,
786- 0, 1, 0},
787- {"max_join_size", OPT_MAX_JOIN_SIZE,
788- N_("Automatic limit for rows in a join when using --safe-updates"),
789- (char**) &max_join_size,
790- (char**) &max_join_size, 0, GET_UINT32, REQUIRED_ARG, 1000000L, 1, ULONG_MAX,
791- 0, 1, 0},
792- {"secure-auth", OPT_SECURE_AUTH, N_("Refuse client connecting to server if it uses old (pre-4.1.1) protocol"), (char**) &opt_secure_auth,
793- (char**) &opt_secure_auth, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
794- {"show-warnings", OPT_SHOW_WARNINGS, N_("Show warnings after every statement."),
795- (char**) &show_warnings, (char**) &show_warnings, 0, GET_BOOL, NO_ARG,
796- 0, 0, 0, 0, 0, 0},
797- {"show-progress-size", OPT_SHOW_PROGRESS_SIZE, N_("Number of lines before each import progress report."),
798- (char**) &show_progress_size, (char**) &show_progress_size, 0, GET_UINT32, REQUIRED_ARG,
799- 0, 0, 0, 0, 0, 0},
800- {"ping", OPT_PING, N_("Ping the server to check if it's alive."),
801- (char**) &opt_ping, (char**) &opt_ping, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
802- {"mysql", 'm', N_("Use MySQL Protocol."),
803- (char**) &opt_mysql, (char**) &opt_mysql, 0, GET_BOOL, NO_ARG, 1, 0, 0,
804- 0, 0, 0},
805- { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
806-};
807-
808-
809-static void usage(int version)
810-{
811- const char* readline= "readline";
812-
813- printf(_("%s Ver %s Distrib %s, for %s-%s (%s) using %s %s\n"),
814- internal::my_progname, VER.c_str(), drizzle_version(),
815- HOST_VENDOR, HOST_OS, HOST_CPU,
816- readline, rl_library_version);
817-
818- if (version)
819- return;
820- printf(_("Copyright (C) 2008 Sun Microsystems\n"
821- "This software comes with ABSOLUTELY NO WARRANTY. "
822- "This is free software,\n"
823- "and you are welcome to modify and redistribute it "
824- "under the GPL license\n"));
825- printf(_("Usage: %s [OPTIONS] [database]\n"), internal::my_progname);
826- my_print_help(my_long_options);
827- internal::print_defaults("drizzle", load_default_groups);
828- my_print_variables(my_long_options);
829-}
830-
831-
832-static int get_one_option(int optid, const struct option *, char *argument)
833-{
834- char *endchar= NULL;
835- uint64_t temp_drizzle_port= 0;
836-
837- switch(optid) {
838- case OPT_DEFAULT_CHARSET:
839- default_charset_used= 1;
840- break;
841- case OPT_DELIMITER:
842- if (argument == disabled_my_option)
843- {
844- strcpy(delimiter, DEFAULT_DELIMITER);
845- }
846- else
847- {
848- /* Check that delimiter does not contain a backslash */
849- if (!strstr(argument, "\\"))
850- {
851- strncpy(delimiter, argument, sizeof(delimiter) - 1);
852- }
853- else
854- {
855- put_info(_("DELIMITER cannot contain a backslash character"),
856- INFO_ERROR,0,0);
857- return false;
858- }
859- }
860- delimiter_length= (uint32_t)strlen(delimiter);
861- delimiter_str= delimiter;
862- break;
863- case OPT_TEE:
864- if (argument == disabled_my_option)
865- {
866- if (opt_outfile)
867- end_tee();
868- }
869- else
870- init_tee(argument);
871- break;
872- case OPT_NOTEE:
873- printf(_("WARNING: option deprecated; use --disable-tee instead.\n"));
874- if (opt_outfile)
875- end_tee();
876- break;
877- case OPT_PAGER:
878- if (argument == disabled_my_option)
879- opt_nopager= 1;
880- else
881- {
882- opt_nopager= 0;
883- if (argument && strlen(argument))
884- {
885- default_pager_set= 1;
886- strncpy(pager, argument, sizeof(pager) - 1);
887- strcpy(default_pager, pager);
888- }
889- else if (default_pager_set)
890- strcpy(pager, default_pager);
891- else
892- opt_nopager= 1;
893- }
894- break;
895- case OPT_NOPAGER:
896- printf(_("WARNING: option deprecated; use --disable-pager instead.\n"));
897- opt_nopager= 1;
898- break;
899- case OPT_SERVER_ARG:
900- printf(_("WARNING: --server-arg option not supported in this configuration.\n"));
901- break;
902- case 'A':
903- opt_rehash= 0;
904- break;
905- case 'N':
906- column_names= 0;
907- break;
908- case 'e':
909- status.setBatch(1);
910- status.setAddToHistory(1);
911- if (status.getLineBuff() == NULL)
912- status.setLineBuff(opt_max_input_line,NULL);
913- if (status.getLineBuff() == NULL)
914- {
915- internal::my_end();
916- exit(1);
917- }
918- status.getLineBuff()->addString(argument);
919- break;
920- case 'o':
921- if (argument == disabled_my_option)
922- one_database= 0;
923- else
924- one_database= skip_updates= 1;
925- break;
926- case 'p':
927- temp_drizzle_port= (uint64_t) strtoul(argument, &endchar, 10);
928- /* if there is an alpha character this is not a valid port */
929- if (strlen(endchar) != 0)
930- {
931- put_info(_("Non-integer value supplied for port. If you are trying to enter a password please use --password instead."), INFO_ERROR, 0, 0);
932- return false;
933- }
934- /* If the port number is > 65535 it is not a valid port
935- This also helps with potential data loss casting unsigned long to a
936- uint32_t. */
937- if ((temp_drizzle_port == 0) || (temp_drizzle_port > 65535))
938- {
939- put_info(_("Value supplied for port is not valid."), INFO_ERROR, 0, 0);
940- return false;
941- }
942- else
943- {
944- opt_drizzle_port= (uint32_t) temp_drizzle_port;
945- }
946- break;
947- case 'P':
948- /* Don't require password */
949- if (argument == disabled_my_option)
950- {
951- argument= (char*) "";
952- }
953- if (argument)
954- {
955- char *start= argument;
956- free(opt_password);
957- opt_password= strdup(argument);
958- while (*argument)
959- {
960- /* Overwriting password with 'x' */
961- *argument++= 'x';
962- }
963- if (*start)
964- {
965- start[1]= 0;
966- }
967- tty_password= 0;
968- }
969- else
970- {
971- tty_password= 1;
972- }
973- break;
974- case 's':
975- if (argument == disabled_my_option)
976- opt_silent= 0;
977- else
978- opt_silent++;
979- break;
980- case 'v':
981- if (argument == disabled_my_option)
982- verbose= 0;
983- else
984- verbose++;
985- break;
986- case 'B':
987- status.setBatch(1);
988- status.setAddToHistory(0);
989- set_if_bigger(opt_silent,1); // more silent
990- break;
991- case 'V':
992- usage(1);
993- exit(0);
994- case 'I':
995- case '?':
996- usage(0);
997- exit(0);
998- }
999- return 0;
1000-}
1001-
1002-
1003-static int get_options(int argc, char **argv)
1004+
1005+
1006+static int process_options(void)
1007 {
1008 char *tmp, *pagpoint;
1009- int ho_error;
1010+
1011
1012 tmp= (char *) getenv("DRIZZLE_HOST");
1013 if (tmp)
1014@@ -1953,8 +1984,7 @@
1015 strcpy(pager, pagpoint);
1016 strcpy(default_pager, pager);
1017
1018- if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
1019- exit(ho_error);
1020+ //
1021
1022 if (status.getBatch()) /* disable pager and outfile in this case */
1023 {
1024@@ -1967,20 +1997,8 @@
1025 connect_flag= DRIZZLE_CAPABILITIES_NONE; /* Not in interactive mode */
1026 }
1027
1028- if (argc > 1)
1029- {
1030- usage(0);
1031- exit(1);
1032- }
1033- if (argc == 1)
1034- {
1035- skip_updates= 0;
1036- free(current_db);
1037- current_db= strdup(*argv);
1038- }
1039 if (tty_password)
1040 opt_password= client_get_tty_password(NULL);
1041-
1042 return(0);
1043 }
1044
1045@@ -2582,7 +2600,7 @@
1046 drizzle_column_st *sql_field;
1047 string tmp_str, tmp_str_lower;
1048
1049- if (status.getBatch() || quick || !current_db)
1050+ if (status.getBatch() || quick || current_db.empty())
1051 return; // We don't need completion in batches
1052 if (!rehash)
1053 return;
1054@@ -2717,8 +2735,8 @@
1055 drizzle_return_t ret;
1056 drizzle_result_st res;
1057
1058- free(current_db);
1059- current_db= NULL;
1060+ current_db.erase();
1061+ current_db= "";
1062 /* In case of error below current_db will be NULL */
1063 if (drizzle_query_str(&con, &res, "SELECT DATABASE()", &ret) != NULL)
1064 {
1065@@ -3746,12 +3764,12 @@
1066 tmp= get_arg(buff, 0);
1067 if (tmp && *tmp)
1068 {
1069- free(current_db);
1070+ current_db.erase();
1071 current_db= strdup(tmp);
1072 tmp= get_arg(buff, 1);
1073 if (tmp)
1074 {
1075- free(current_host);
1076+ current_host.erase();
1077 current_host=strdup(tmp);
1078 }
1079 }
1080@@ -3766,7 +3784,7 @@
1081 }
1082 else
1083 opt_rehash= 0;
1084- error=sql_connect(current_host,current_db,current_user,opt_password,0);
1085+ error=sql_connect(current_host, current_db, current_user, opt_password,0);
1086 opt_rehash= save_rehash;
1087
1088 if (connected)
1089@@ -3774,7 +3792,7 @@
1090 sprintf(buff,"Connection id: %u",drizzle_con_thread_id(&con));
1091 put_info(buff,INFO_INFO,0,0);
1092 sprintf(buff,"Current database: %.128s\n",
1093- current_db ? current_db : "*** NONE ***");
1094+ !current_db.empty() ? current_db.c_str() : "*** NONE ***");
1095 put_info(buff,INFO_INFO,0,0);
1096 }
1097 return error;
1098@@ -3896,7 +3914,7 @@
1099 */
1100 get_current_db();
1101
1102- if (!current_db || strcmp(current_db,tmp))
1103+ if (current_db.empty() || strcmp(current_db.c_str(),tmp))
1104 {
1105 if (one_database)
1106 {
1107@@ -3948,7 +3966,7 @@
1108 else
1109 drizzle_result_free(&result);
1110 }
1111- free(current_db);
1112+ current_db.erase();
1113 current_db= strdup(tmp);
1114 if (select_db > 1)
1115 build_completion_hash(opt_rehash, 1);
1116@@ -4037,11 +4055,10 @@
1117
1118
1119 static int
1120-sql_connect(char *host,char *database,char *user,char *password,
1121+sql_connect(const string &host, const string &database, const string &user, const string &password,
1122 uint32_t silent)
1123 {
1124 drizzle_return_t ret;
1125-
1126 if (connected)
1127 {
1128 connected= 0;
1129@@ -4049,8 +4066,8 @@
1130 drizzle_free(&drizzle);
1131 }
1132 drizzle_create(&drizzle);
1133- if (drizzle_con_add_tcp(&drizzle, &con, host, opt_drizzle_port, user,
1134- password, database, opt_mysql ? DRIZZLE_CON_MYSQL : DRIZZLE_CON_NONE) == NULL)
1135+ if (drizzle_con_add_tcp(&drizzle, &con, (char *)host.c_str(), opt_drizzle_port, (char *)user.c_str(),
1136+ (char *)password.c_str(), (char *)database.c_str(), opt_mysql ? DRIZZLE_CON_MYSQL : DRIZZLE_CON_NONE) == NULL)
1137 {
1138 (void) put_error(&con, NULL);
1139 (void) fflush(stdout);
1140@@ -4106,7 +4123,12 @@
1141 drizzle_return_t ret;
1142
1143 tee_puts("--------------", stdout);
1144- usage(1); /* Print version */
1145+ printf(_("%s Ver %s Distrib %s, for %s-%s (%s) using readline %s\n"),
1146+ internal::my_progname, VER.c_str(), drizzle_version(),
1147+ HOST_VENDOR, HOST_OS, HOST_CPU,
1148+ rl_library_version); /* Print version */
1149+
1150+
1151 if (connected)
1152 {
1153 tee_fprintf(stdout, "\nConnection id:\t\t%lu\n",drizzle_con_thread_id(&con));
1154@@ -4452,7 +4474,7 @@
1155 struct tm *t = localtime(&lclock);
1156
1157 /* parse thru the settings for the prompt */
1158- for (char *c= current_prompt; *c; (void)*c++)
1159+ for (char *c= (char *)current_prompt.c_str(); *c; (void)*c++)
1160 {
1161 if (*c != PROMPT_CHAR)
1162 {
1163@@ -4479,7 +4501,7 @@
1164 processed_prompt->append("not_connected");
1165 break;
1166 case 'd':
1167- processed_prompt->append(current_db ? current_db : "(none)");
1168+ processed_prompt->append(!current_db.empty() ? current_db.c_str() : "(none)");
1169 break;
1170 case 'h':
1171 {
1172@@ -4516,13 +4538,13 @@
1173 if (!full_username)
1174 init_username();
1175 processed_prompt->append(full_username ? full_username :
1176- (current_user ? current_user : "(unknown)"));
1177+ (!current_user.empty() ? current_user.c_str() : "(unknown)"));
1178 break;
1179 case 'u':
1180 if (!full_username)
1181 init_username();
1182 processed_prompt->append(part_username ? part_username :
1183- (current_user ? current_user : "(unknown)"));
1184+ (!current_user.empty() ? current_user.c_str() : "(unknown)"));
1185 break;
1186 case PROMPT_CHAR:
1187 {
1188@@ -4601,7 +4623,7 @@
1189 processed_prompt->append("\t");
1190 break;
1191 case 'l':
1192- processed_prompt->append(delimiter_str);
1193+ processed_prompt->append(delimiter_str.c_str());
1194 break;
1195 default:
1196 processed_prompt->append(c, 1);
1197@@ -4649,9 +4671,9 @@
1198 tee_fprintf(stdout, "Memory allocation error. Not changing prompt\n");
1199 else
1200 {
1201- free(current_prompt);
1202+ current_prompt.erase();
1203 current_prompt= tmpptr;
1204- tee_fprintf(stdout, "PROMPT set to '%s'\n", current_prompt);
1205+ tee_fprintf(stdout, "PROMPT set to '%s'\n", current_prompt.c_str());
1206 }
1207 return 0;
1208 }
1209
1210=== modified file 'client/include.am'
1211--- client/include.am 2010-06-02 16:51:50 +0000
1212+++ client/include.am 2010-06-04 16:41:24 +0000
1213@@ -45,7 +45,7 @@
1214
1215
1216 client_drizzle_SOURCES= client/drizzle.cc client/linebuffer.cc
1217-client_drizzle_LDADD= ${CLIENT_LDADD} ${READLINE_LIBS}
1218+client_drizzle_LDADD= ${CLIENT_LDADD} ${READLINE_LIBS} ${BOOST_LIBS}
1219 client_drizzle_CXXFLAGS= ${CLIENT_CXXFLAGS}
1220
1221 client_drizzledump_SOURCES= client/drizzledump.cc