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
=== modified file 'client/drizzle.cc' (properties changed: +x to -x)
--- client/drizzle.cc 2010-05-25 15:23:24 +0000
+++ client/drizzle.cc 2010-06-04 16:41:24 +0000
@@ -37,6 +37,7 @@
37#include <string>37#include <string>
38#include <drizzled/gettext.h>38#include <drizzled/gettext.h>
39#include <iostream>39#include <iostream>
40#include <fstream>
40#include <map>41#include <map>
41#include <algorithm>42#include <algorithm>
42#include <limits.h>43#include <limits.h>
@@ -139,9 +140,11 @@
139#undef vidattr140#undef vidattr
140#define vidattr(A) {} // Can't get this to work141#define vidattr(A) {} // Can't get this to work
141#endif142#endif
143#include <boost/program_options.hpp>
142144
143using namespace drizzled;145using namespace drizzled;
144using namespace std;146using namespace std;
147namespace po=boost::program_options;
145148
146const string VER("14.14");149const string VER("14.14");
147/* Don't try to make a nice table if the data is too big */150/* Don't try to make a nice table if the data is too big */
@@ -149,9 +152,9 @@
149152
150/* Buffer to hold 'version' and 'version_comment' */153/* Buffer to hold 'version' and 'version_comment' */
151const int MAX_SERVER_VERSION_LENGTH= 128;154const int MAX_SERVER_VERSION_LENGTH= 128;
155const string PASSWORD_SENTINEL("\0\0\0\0\0", 5);
152156
153#define PROMPT_CHAR '\\'157#define PROMPT_CHAR '\\'
154#define DEFAULT_DELIMITER ";"
155158
156class Status159class Status
157{160{
@@ -260,7 +263,6 @@
260static map<string, string> completion_map;263static map<string, string> completion_map;
261static string completion_string;264static string completion_string;
262265
263static char **defaults_argv;
264266
265enum enum_info_type { INFO_INFO,INFO_ERROR,INFO_RESULT};267enum enum_info_type { INFO_INFO,INFO_ERROR,INFO_RESULT};
266typedef enum enum_info_type INFO_TYPE;268typedef enum enum_info_type INFO_TYPE;
@@ -279,15 +281,14 @@
279 default_pager_set= false, opt_sigint_ignore= false,281 default_pager_set= false, opt_sigint_ignore= false,
280 auto_vertical_output= false,282 auto_vertical_output= false,
281 show_warnings= false, executing_query= false, interrupted_query= false,283 show_warnings= false, executing_query= false, interrupted_query= false,
282 opt_mysql= false;284 opt_mysql= false, opt_local_infile;
283static uint32_t show_progress_size= 0;285static uint32_t show_progress_size= 0;
284static bool column_types_flag;286static bool column_types_flag;
285static bool preserve_comments= false;287static bool preserve_comments= false;
286static uint32_t opt_max_input_line, opt_drizzle_port= 0;288static uint32_t opt_max_input_line;
287static int verbose= 0, opt_silent= 0, opt_local_infile= 0;289static uint32_t opt_drizzle_port= 0;
290static int opt_silent, verbose= 0;
288static drizzle_capabilities_t connect_flag= DRIZZLE_CAPABILITIES_NONE;291static drizzle_capabilities_t connect_flag= DRIZZLE_CAPABILITIES_NONE;
289static char *current_host, *current_db, *current_user= NULL,
290 *opt_password= NULL, *delimiter_str= NULL, *current_prompt= NULL;
291static char *histfile;292static char *histfile;
292static char *histfile_tmp;293static char *histfile_tmp;
293static string *glob_buffer;294static string *glob_buffer;
@@ -298,6 +299,14 @@
298static uint32_t select_limit;299static uint32_t select_limit;
299static uint32_t max_join_size;300static uint32_t max_join_size;
300static uint32_t opt_connect_timeout= 0;301static uint32_t opt_connect_timeout= 0;
302std::string current_db,
303 delimiter_str,
304 current_host,
305 current_prompt,
306 current_user,
307 opt_verbose,
308 current_password,
309 opt_password;
301// TODO: Need to i18n these310// TODO: Need to i18n these
302static const char *day_names[]= {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};311static const char *day_names[]= {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
303static const char *month_names[]= {"Jan","Feb","Mar","Apr","May","Jun","Jul",312static const char *month_names[]= {"Jan","Feb","Mar","Apr","May","Jun","Jul",
@@ -306,7 +315,7 @@
306static char pager[FN_REFLEN], outfile[FN_REFLEN];315static char pager[FN_REFLEN], outfile[FN_REFLEN];
307static FILE *PAGER, *OUTFILE;316static FILE *PAGER, *OUTFILE;
308static uint32_t prompt_counter;317static uint32_t prompt_counter;
309static char delimiter[16]= DEFAULT_DELIMITER;318static char *delimiter= NULL;
310static uint32_t delimiter_length= 1;319static uint32_t delimiter_length= 1;
311unsigned short terminal_width= 80;320unsigned short terminal_width= 80;
312321
@@ -324,7 +333,7 @@
324void tee_putc(int c, FILE *file);333void tee_putc(int c, FILE *file);
325static void tee_print_sized_data(const char *, unsigned int, unsigned int, bool);334static void tee_print_sized_data(const char *, unsigned int, unsigned int, bool);
326/* The names of functions that actually do the manipulation. */335/* The names of functions that actually do the manipulation. */
327static int get_options(int argc,char **argv);336static int process_options(void);
328static int com_quit(string *str,const char*),337static int com_quit(string *str,const char*),
329 com_go(string *str,const char*), com_ego(string *str,const char*),338 com_go(string *str,const char*), com_ego(string *str,const char*),
330 com_print(string *str,const char*),339 com_print(string *str,const char*),
@@ -338,7 +347,7 @@
338 com_nopager(string *str, const char*), com_pager(string *str, const char*);347 com_nopager(string *str, const char*), com_pager(string *str, const char*);
339348
340static int read_and_execute(bool interactive);349static int read_and_execute(bool interactive);
341static int sql_connect(char *host,char *database,char *user,char *password,350static int sql_connect(const string &host, const string &database, const string &user, const string &password,
342 uint32_t silent);351 uint32_t silent);
343static const char *server_version_string(drizzle_con_st *con);352static const char *server_version_string(drizzle_con_st *con);
344static int put_info(const char *str,INFO_TYPE info,uint32_t error,353static int put_info(const char *str,INFO_TYPE info,uint32_t error,
@@ -1157,7 +1166,6 @@
1157 Commands((char *)NULL, 0, 0, 0, "")1166 Commands((char *)NULL, 0, 0, 0, "")
1158};1167};
11591168
1160static const char *load_default_groups[]= { "drizzle","client",0 };
11611169
1162int history_length;1170int history_length;
1163static int not_in_history(const char *line);1171static int not_in_history(const char *line);
@@ -1300,8 +1308,72 @@
1300 return executed;1308 return executed;
1301}1309}
13021310
1311static void check_timeout_value(uint32_t in_connect_timeout)
1312{
1313 opt_connect_timeout= 0;
1314 if (in_connect_timeout > 3600*12)
1315 {
1316 cout<<N_("Error: Invalid Value for connect_timeout");
1317 exit(-1);
1318 }
1319 opt_connect_timeout= in_connect_timeout;
1320}
1321
1322static void check_max_input_line(uint32_t in_max_input_line)
1323{
1324 opt_max_input_line= 0;
1325 if (in_max_input_line<4096 || in_max_input_line>(int64_t)2*1024L*1024L*1024L)
1326 {
1327 cout<<N_("Error: Invalid Value for max_input_line");
1328 exit(-1);
1329 }
1330 opt_max_input_line= in_max_input_line/1024;
1331 opt_max_input_line*=1024;
1332}
1333
1334static pair<string, string> parse_password_arg(std::string s)
1335{
1336 if (s.find("--password") == 0)
1337 {
1338 if (s == "--password")
1339 {
1340 tty_password= true;
1341 //check if no argument is passed.
1342 return make_pair("password", PASSWORD_SENTINEL);
1343 }
1344
1345 if (s.substr(10,3) == "=\"\"" || s.substr(10,3) == "=''")
1346 {
1347 // Check if --password="" or --password=''
1348 return make_pair("password", PASSWORD_SENTINEL);
1349 }
1350
1351 if(s.substr(10) == "=" && s.length() == 11)
1352 {
1353 // check if --password= and return a default value
1354 return make_pair("password", PASSWORD_SENTINEL);
1355 }
1356
1357 if(s.length()>12 && (s[10] == '"' || s[10] == '\''))
1358 {
1359 // check if --password has quotes, remove quotes and return the value
1360 return make_pair("password", s.substr(11,s.length()-1));
1361 }
1362
1363 // if all above are false, it implies that --password=value, return value.
1364 return make_pair("password", s.substr(11));
1365 }
1366
1367 else
1368 {
1369 return make_pair(string(""), string(""));
1370 }
1371}
1372
1303int main(int argc,char *argv[])1373int main(int argc,char *argv[])
1304{1374{
1375try
1376{
1305#if defined(ENABLE_NLS)1377#if defined(ENABLE_NLS)
1306# if defined(HAVE_LOCALE_H)1378# if defined(HAVE_LOCALE_H)
1307 setlocale(LC_ALL, "");1379 setlocale(LC_ALL, "");
@@ -1310,12 +1382,160 @@
1310 textdomain("drizzle");1382 textdomain("drizzle");
1311#endif1383#endif
13121384
1313 MY_INIT(argv[0]);1385 po::options_description commandline_options("Options used only in command line");
1314 delimiter_str= delimiter;1386 commandline_options.add_options()
1387 ("help,?",N_("Displays this help and exit."))
1388 ("batch,B",N_("Don't use history file. Disable interactive behavior. (Enables --silent)"))
1389 ("column-type-info", po::value<bool>(&column_types_flag)->default_value(false)->zero_tokens(),
1390 N_("Display column type information."))
1391 ("comments,c", po::value<bool>(&preserve_comments)->default_value(false)->zero_tokens(),
1392 N_("Preserve comments. Send comments to the server. The default is --skip-comments (discard comments), enable with --comments"))
1393 ("compress,C", po::value<bool>(&opt_compress)->default_value(false)->zero_tokens(),
1394 N_("Use compression in server/client protocol."))
1395 ("vertical,E", po::value<bool>(&vertical)->default_value(false)->zero_tokens(),
1396 N_("Print the output of a query (rows) vertically."))
1397 ("force,f", po::value<bool>(&ignore_errors)->default_value(false)->zero_tokens(),
1398 N_("Continue even if we get an sql error."))
1399 ("named-commands,G", po::value<bool>(&named_cmds)->default_value(false)->zero_tokens(),
1400 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."))
1401 ("no-named-commands,g",
1402 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."))
1403 ("ignore-spaces,i", N_("Ignore space after function names."))
1404 ("no-beep,b", po::value<bool>(&opt_nobeep)->default_value(false)->zero_tokens(),
1405 N_("Turn off beep on error."))
1406 ("line-numbers", po::value<bool>(&line_numbers)->default_value(true)->zero_tokens(),
1407 N_("Write line numbers for errors."))
1408 ("skip-line-numbers,L",
1409 N_("Don't write line number for errors. WARNING: -L is deprecated, use long version of this option instead."))
1410 ("column-name", po::value<bool>(&column_names)->default_value(true)->zero_tokens(),
1411 N_("Write column names in results."))
1412 ("skip-column-names,N",
1413 N_("Don't write column names in results. WARNING: -N is deprecated, use long version of this options instead."))
1414 ("set-variable,O", po::value<string>(),
1415 N_("Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value."))
1416 ("table,t", po::value<bool>(&output_tables)->default_value(false)->zero_tokens(),
1417 N_("Output in table format."))
1418 ("safe-updates,U", po::value<bool>(&safe_updates)->default_value(0)->zero_tokens(),
1419 N_("Only allow UPDATE and DELETE that uses keys."))
1420 ("i-am-a-dummy,U", po::value<bool>(&safe_updates)->default_value(0)->zero_tokens(),
1421 N_("Synonym for option --safe-updates, -U."))
1422 ("verbose,v", po::value<string>(&opt_verbose)->default_value(""),
1423 N_("-v vvv implies that verbose= 3, Used to specify verbose"))
1424 ("version,V", N_("Output version information and exit."))
1425 ("secure-auth", po::value<bool>(&opt_secure_auth)->default_value(false)->zero_tokens(),
1426 N_("Refuse client connecting to server if it uses old (pre-4.1.1) protocol"))
1427 ("show-warnings", po::value<bool>(&show_warnings)->default_value(false)->zero_tokens(),
1428 N_("Show warnings after every statement."))
1429 ("show-progress-size", po::value<uint32_t>(&show_progress_size)->default_value(0),
1430 N_("Number of lines before each import progress report."))
1431 ("ping", po::value<bool>(&opt_ping)->default_value(false)->zero_tokens(),
1432 N_("Ping the server to check if it's alive."))
1433 ("no-defaults", po::value<bool>()->default_value(false)->zero_tokens(),
1434 N_("Configuration file defaults are not used if no-defaults is set"))
1435 ;
1436
1437 po::options_description drizzle_options("Options specific to the drizzle client");
1438 drizzle_options.add_options()
1439 ("auto-rehash", po::value<bool>(&opt_rehash)->default_value(true)->zero_tokens(),
1440 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."))
1441 ("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."))
1442 ("auto-vertical-output", po::value<bool>(&auto_vertical_output)->default_value(false)->zero_tokens(),
1443 N_("Automatically switch to vertical output mode if the result is wider than the terminal width."))
1444 ("database,D", po::value<string>(&current_db)->default_value("test"),
1445 N_("Database to use."))
1446 ("default-character-set",po::value<string>(),
1447 N_("(not used)"))
1448 ("delimiter", po::value<string>(&delimiter_str)->default_value(";"),
1449 N_("Delimiter to be used."))
1450 ("execute,e", po::value<string>(),
1451 N_("Execute command and quit. (Disables --force and history file)"))
1452 ("local-infile", po::value<bool>(&opt_local_infile)->default_value(false)->zero_tokens(),
1453 N_("Enable/disable LOAD DATA LOCAL INFILE."))
1454 ("unbuffered,n", po::value<bool>(&unbuffered)->default_value(false)->zero_tokens(),
1455 N_("Flush buffer after each query."))
1456 ("sigint-ignore", po::value<bool>(&opt_sigint_ignore)->default_value(false)->zero_tokens(),
1457 N_("Ignore SIGINT (CTRL-C)"))
1458 ("one-database,o", po::value<bool>(&one_database)->default_value(false)->zero_tokens(),
1459 N_("Only update the default database. This is useful for skipping updates to other database in the update log."))
1460 ("pager", po::value<string>(),
1461 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."))
1462 ("disable-pager", po::value<bool>(&opt_nopager)->default_value(false)->zero_tokens(),
1463 N_("Disable pager and print to stdout. See interactive help (\\h) also."))
1464 ("prompt", po::value<string>(&current_prompt)->default_value(""),
1465 N_("Set the drizzle prompt to this value."))
1466 ("quick,q", po::value<bool>(&quick)->default_value(false)->zero_tokens(),
1467 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."))
1468 ("raw,r", po::value<bool>(&opt_raw_data)->default_value(false)->zero_tokens(),
1469 N_("Write fields without conversion. Used with --batch."))
1470 ("reconnect", po::value<bool>(&opt_reconnect)->default_value(true)->zero_tokens(),
1471 N_("Reconnect if the connection is lost. Disable with --disable-reconnect. This option is enabled by default."))
1472 ("shutdown", po::value<bool>(&opt_shutdown)->default_value(false)->zero_tokens(),
1473 N_("Shutdown the server"))
1474 ("silent,s", N_("Be more silent. Print results with a tab as separator, each row on new line."))
1475 ("tee", po::value<string>(),
1476 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."))
1477 ("disable-tee", po::value<bool>()->default_value(false)->zero_tokens(),
1478 N_("Disable outfile. See interactive help (\\h) also."))
1479 ("wait,w", N_("Wait and retry if connection is down."))
1480 ("connect_timeout", po::value<uint32_t>(&opt_connect_timeout)->default_value(0)->notifier(&check_timeout_value),
1481 N_("Number of seconds before connection timeout."))
1482 ("max_input_line", po::value<uint32_t>(&opt_max_input_line)->default_value(16*1024L*1024L)->notifier(&check_max_input_line),
1483 N_("Max length of input line"))
1484 ("select_limit", po::value<uint32_t>(&select_limit)->default_value(1000L),
1485 N_("Automatic limit for SELECT when using --safe-updates"))
1486 ("max_join_size", po::value<uint32_t>(&max_join_size)->default_value(1000000L),
1487 N_("Automatic limit for rows in a join when using --safe-updates"))
1488 ;
1489
1490 po::options_description client_options("Options specific to the client");
1491 client_options.add_options()
1492 ("mysql,m", po::value<bool>(&opt_mysql)->default_value(true)->zero_tokens(),
1493 N_("Use MySQL Protocol."))
1494 ("host,h", po::value<string>(&current_host)->default_value("localhost"),
1495 N_("Connect to host"))
1496 ("password,P", po::value<string>(&current_password)->default_value(PASSWORD_SENTINEL),
1497 N_("Password to use when connecting to server. If password is not given it's asked from the tty."))
1498 ("port,p", po::value<uint32_t>()->default_value(3306),
1499 N_("Port number to use for connection or 0 for default to, in order of preference, drizzle.cnf, $DRIZZLE_TCP_PORT, built-in default"))
1500 ("user,u", po::value<string>(&current_user)->default_value(""),
1501 N_("User for login if not current user."))
1502 ("protocol",po::value<string>(),
1503 N_("The protocol of connection (tcp,socket,pipe,memory)."))
1504 ;
1505
1506 po::options_description long_options("Allowed Options");
1507 long_options.add(commandline_options).add(drizzle_options).add(client_options);
1508
1509 std::string system_config_dir_drizzle(SYSCONFDIR);
1510 system_config_dir_drizzle.append("/drizzle/drizzle.cnf");
1511
1512 std::string system_config_dir_client(SYSCONFDIR);
1513 system_config_dir_client.append("/drizzle/client.cnf");
1514
1515 po::variables_map vm;
1516
1517 po::store(po::command_line_parser(argc, argv).options(long_options).extra_parser(parse_password_arg).run(), vm);
1518
1519 if (! vm["no-defaults"].as<bool>())
1520 {
1521 ifstream user_drizzle_ifs("~/.drizzle/drizzleslap.cnf");
1522 po::store(parse_config_file(user_drizzle_ifs, drizzle_options), vm);
1523
1524 ifstream system_drizzle_ifs(system_config_dir_drizzle.c_str());
1525 store(parse_config_file(system_drizzle_ifs, drizzle_options), vm);
1526
1527 ifstream user_client_ifs("~/.drizzle/client.cnf");
1528 po::store(parse_config_file(user_client_ifs, client_options), vm);
1529
1530 ifstream system_client_ifs(system_config_dir_client.c_str());
1531 po::store(parse_config_file(system_client_ifs, client_options), vm);
1532 }
1533
1534 po::notify(vm);
1535
1315 default_prompt= strdup(getenv("DRIZZLE_PS1") ?1536 default_prompt= strdup(getenv("DRIZZLE_PS1") ?
1316 getenv("DRIZZLE_PS1") :1537 getenv("DRIZZLE_PS1") :
1317 "drizzle> ");1538 "drizzle> ");
1318
1319 if (default_prompt == NULL)1539 if (default_prompt == NULL)
1320 {1540 {
1321 fprintf(stderr, _("Memory allocation error while constructing initial "1541 fprintf(stderr, _("Memory allocation error while constructing initial "
@@ -1323,7 +1543,7 @@
1323 exit(ENOMEM);1543 exit(ENOMEM);
1324 }1544 }
1325 current_prompt= strdup(default_prompt);1545 current_prompt= strdup(default_prompt);
1326 if (current_prompt == NULL)1546 if (current_prompt.empty())
1327 {1547 {
1328 fprintf(stderr, _("Memory allocation error while constructing initial "1548 fprintf(stderr, _("Memory allocation error while constructing initial "
1329 "prompt. Aborting.\n"));1549 "prompt. Aborting.\n"));
@@ -1344,7 +1564,7 @@
1344 strcpy(default_pager, tmp);1564 strcpy(default_pager, tmp);
1345 }1565 }
1346 }1566 }
1347 if (!isatty(0) || !isatty(1))1567 if (! isatty(0) || ! isatty(1))
1348 {1568 {
1349 status.setBatch(1); opt_silent=1;1569 status.setBatch(1); opt_silent=1;
1350 ignore_errors=0;1570 ignore_errors=0;
@@ -1367,18 +1587,187 @@
1367 close(stdout_fileno_copy); /* Clean up dup(). */1587 close(stdout_fileno_copy); /* Clean up dup(). */
1368 }1588 }
13691589
1370 internal::load_defaults("drizzle",load_default_groups,&argc,&argv);1590 if (vm.count("default-character-set"))
1371 defaults_argv=argv;1591 default_charset_used= 1;
1372 if (get_options(argc, (char **) argv))1592
1373 {1593 if (vm.count("delimiter"))
1374 internal::free_defaults(defaults_argv);1594 {
1375 internal::my_end();1595 /* Check that delimiter does not contain a backslash */
1596 if (! strstr(delimiter_str.c_str(), "\\"))
1597 {
1598 delimiter= (char *)delimiter_str.c_str();
1599 }
1600 else
1601 {
1602 put_info(_("DELIMITER cannot contain a backslash character"),
1603 INFO_ERROR,0,0);
1604 exit(-1);
1605 }
1606
1607 delimiter_length= (uint32_t)strlen(delimiter);
1608 }
1609 if (vm.count("tee"))
1610 {
1611 if (vm["tee"].as<string>().empty())
1612 {
1613 if (opt_outfile)
1614 end_tee();
1615 }
1616 else
1617 init_tee(vm["tee"].as<string>().c_str());
1618 }
1619 if (vm["disable-tee"].as<bool>() == true)
1620 {
1621 if (opt_outfile)
1622 end_tee();
1623 }
1624 if (vm.count("pager"))
1625 {
1626 if (vm["pager"].as<string>().empty())
1627 opt_nopager= 1;
1628 else
1629 {
1630 opt_nopager= 0;
1631 if (vm[pager].as<string>().length())
1632 {
1633 default_pager_set= 1;
1634 strncpy(pager, vm["pager"].as<string>().c_str(), sizeof(pager) - 1);
1635 strcpy(default_pager, pager);
1636 }
1637 else if (default_pager_set)
1638 strcpy(pager, default_pager);
1639 else
1640 opt_nopager= 1;
1641 }
1642 }
1643 if (vm.count("disable-pager"))
1644 {
1645 opt_nopager= 1;
1646 }
1647
1648 if (vm.count("no-auto-rehash"))
1649 opt_rehash= 0;
1650
1651 if (vm.count("skip-column-names"))
1652 column_names= 0;
1653
1654 if (vm.count("execute"))
1655 {
1656 status.setBatch(1);
1657 status.setAddToHistory(1);
1658 if (status.getLineBuff() == NULL)
1659 status.setLineBuff(opt_max_input_line,NULL);
1660 if (status.getLineBuff() == NULL)
1661 {
1662 internal::my_end();
1663 exit(1);
1664 }
1665 status.getLineBuff()->addString(vm["execute"].as<string>().c_str());
1666 }
1667
1668 if (one_database)
1669 skip_updates= true;
1670
1671 if (vm.count("port"))
1672 {
1673 opt_drizzle_port= vm["port"].as<uint32_t>();
1674
1675 /* If the port number is > 65535 it is not a valid port
1676 This also helps with potential data loss casting unsigned long to a
1677 uint32_t. */
1678 if ((opt_drizzle_port == 0) || (opt_drizzle_port > 65535))
1679 {
1680 printf(_("Error: Value of %" PRIu32 " supplied for port is not valid.\n"), opt_drizzle_port);
1681 exit(-1);
1682 }
1683 }
1684
1685 if (vm.count("password"))
1686 {
1687 if (!opt_password.empty())
1688 opt_password.erase();
1689 if (current_password == PASSWORD_SENTINEL)
1690 {
1691 opt_password= "";
1692 }
1693 else
1694 {
1695 opt_password= current_password;
1696 tty_password= false;
1697 }
1698 char *start= (char *)current_password.c_str();
1699 char *temp_pass= (char *)current_password.c_str();
1700 while (*temp_pass)
1701 {
1702 /* Overwriting password with 'x' */
1703 *temp_pass++= 'x';
1704 }
1705 if (*start)
1706 {
1707 start[1]= 0;
1708 }
1709 }
1710 else
1711 {
1712 tty_password= true;
1713 }
1714
1715
1716 if (!opt_verbose.empty())
1717 {
1718 verbose= opt_verbose.length();
1719 }
1720
1721 if (vm.count("batch"))
1722 {
1723 status.setBatch(1);
1724 status.setAddToHistory(0);
1725 set_if_bigger(opt_silent,1); // more silent
1726 }
1727 if (vm.count("silent"))
1728 {
1729 opt_silent++;
1730 }
1731 if (vm.count("version"))
1732 {
1733 printf(_("%s Ver %s Distrib %s, for %s-%s (%s) using readline %s\n"),
1734 internal::my_progname, VER.c_str(), drizzle_version(),
1735 HOST_VENDOR, HOST_OS, HOST_CPU,
1736 rl_library_version);
1737
1738 exit(0);
1739 }
1740
1741 if (vm.count("help"))
1742 {
1743 printf(_("%s Ver %s Distrib %s, for %s-%s (%s) using readline %s\n"),
1744 internal::my_progname, VER.c_str(), drizzle_version(),
1745 HOST_VENDOR, HOST_OS, HOST_CPU,
1746 rl_library_version);
1747 printf(_("Copyright (C) 2008 Sun Microsystems\n"
1748 "This software comes with ABSOLUTELY NO WARRANTY. "
1749 "This is free software,\n"
1750 "and you are welcome to modify and redistribute it "
1751 "under the GPL license\n"));
1752 printf(_("Usage: %s [OPTIONS] [database]\n"), internal::my_progname);
1753 cout<<long_options;
1754 exit(0);
1755 }
1756
1757
1758 if (process_options())
1759 {
1376 exit(1);1760 exit(1);
1377 }1761 }
13781762
1763 if (argc == 1)
1764 {
1765 skip_updates= 0;
1766 current_db.erase();
1767 current_db= strdup(*argv);
1768 }
1379 memset(&drizzle, 0, sizeof(drizzle));1769 memset(&drizzle, 0, sizeof(drizzle));
1380 if (sql_connect(current_host,current_db,current_user,opt_password,1770 if (sql_connect(current_host, current_db, current_user, opt_password,opt_silent))
1381 opt_silent))
1382 {1771 {
1383 quick= 1; // Avoid history1772 quick= 1; // Avoid history
1384 status.setExitStatus(1);1773 status.setExitStatus(1);
@@ -1389,8 +1778,6 @@
1389 if (execute_commands(&command_error) != false)1778 if (execute_commands(&command_error) != false)
1390 {1779 {
1391 /* we've executed a command so exit before we go into readline mode */1780 /* we've executed a command so exit before we go into readline mode */
1392 internal::free_defaults(defaults_argv);
1393 internal::my_end();
1394 exit(command_error);1781 exit(command_error);
1395 }1782 }
13961783
@@ -1399,8 +1786,6 @@
1399 status.setLineBuff(opt_max_input_line, stdin);1786 status.setLineBuff(opt_max_input_line, stdin);
1400 if (status.getLineBuff() == NULL)1787 if (status.getLineBuff() == NULL)
1401 {1788 {
1402 internal::free_defaults(defaults_argv);
1403 internal::my_end();
1404 exit(1);1789 exit(1);
1405 }1790 }
1406 }1791 }
@@ -1436,7 +1821,7 @@
1436 server_version_string(&con));1821 server_version_string(&con));
1437 put_info(output_buff, INFO_INFO, 0, 0);1822 put_info(output_buff, INFO_INFO, 0, 0);
14381823
1439 initialize_readline(current_prompt);1824 initialize_readline((char *)current_prompt.c_str());
1440 if (!status.getBatch() && !quick)1825 if (!status.getBatch() && !quick)
1441 {1826 {
1442 /* read-history from file, default ~/.drizzle_history*/1827 /* read-history from file, default ~/.drizzle_history*/
@@ -1480,7 +1865,12 @@
1480 if (opt_outfile)1865 if (opt_outfile)
1481 end_tee();1866 end_tee();
1482 drizzle_end(0);1867 drizzle_end(0);
1868}
14831869
1870 catch(exception &err)
1871 {
1872 cerr<<"Error:"<<err.what()<<endl;
1873 }
1484 return(0); // Keep compiler happy1874 return(0); // Keep compiler happy
1485}1875}
14861876
@@ -1505,18 +1895,16 @@
1505 delete glob_buffer;1895 delete glob_buffer;
1506 if (processed_prompt)1896 if (processed_prompt)
1507 delete processed_prompt;1897 delete processed_prompt;
1508 free(opt_password);1898 opt_password.erase();
1509 free(histfile);1899 free(histfile);
1510 free(histfile_tmp);1900 free(histfile_tmp);
1511 free(current_db);1901 current_db.erase();
1512 free(current_host);1902 current_host.erase();
1513 free(current_user);1903 current_user.erase();
1514 free(full_username);1904 free(full_username);
1515 free(part_username);1905 free(part_username);
1516 free(default_prompt);1906 free(default_prompt);
1517 free(current_prompt);1907 current_prompt.erase();
1518 internal::free_defaults(defaults_argv);
1519 internal::my_end();
1520 exit(status.getExitStatus());1908 exit(status.getExitStatus());
1521}1909}
15221910
@@ -1539,8 +1927,8 @@
1539 goto err;1927 goto err;
1540 }1928 }
15411929
1542 if (drizzle_con_add_tcp(&drizzle, &kill_drizzle, current_host,1930 if (drizzle_con_add_tcp(&drizzle, &kill_drizzle, current_host.c_str(),
1543 opt_drizzle_port, current_user, opt_password, NULL,1931 opt_drizzle_port, current_user.c_str(), opt_password.c_str(), NULL,
1544 opt_mysql ? DRIZZLE_CON_MYSQL : DRIZZLE_CON_NONE) == NULL)1932 opt_mysql ? DRIZZLE_CON_MYSQL : DRIZZLE_CON_NONE) == NULL)
1545 {1933 {
1546 goto err;1934 goto err;
@@ -1575,369 +1963,12 @@
1575}1963}
1576#endif1964#endif
15771965
1578static struct option my_long_options[] =1966
1579{1967
1580 {"help", '?', N_("Display this help and exit."), 0, 0, 0, GET_NO_ARG, NO_ARG, 0,1968static int process_options(void)
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
1743static 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
1766static 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
1937static int get_options(int argc, char **argv)
1938{1969{
1939 char *tmp, *pagpoint;1970 char *tmp, *pagpoint;
1940 int ho_error;1971
19411972
1942 tmp= (char *) getenv("DRIZZLE_HOST");1973 tmp= (char *) getenv("DRIZZLE_HOST");
1943 if (tmp)1974 if (tmp)
@@ -1953,8 +1984,7 @@
1953 strcpy(pager, pagpoint);1984 strcpy(pager, pagpoint);
1954 strcpy(default_pager, pager);1985 strcpy(default_pager, pager);
19551986
1956 if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))1987 //
1957 exit(ho_error);
19581988
1959 if (status.getBatch()) /* disable pager and outfile in this case */1989 if (status.getBatch()) /* disable pager and outfile in this case */
1960 {1990 {
@@ -1967,20 +1997,8 @@
1967 connect_flag= DRIZZLE_CAPABILITIES_NONE; /* Not in interactive mode */1997 connect_flag= DRIZZLE_CAPABILITIES_NONE; /* Not in interactive mode */
1968 }1998 }
19691999
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 }
1981 if (tty_password)2000 if (tty_password)
1982 opt_password= client_get_tty_password(NULL);2001 opt_password= client_get_tty_password(NULL);
1983
1984 return(0);2002 return(0);
1985}2003}
19862004
@@ -2582,7 +2600,7 @@
2582 drizzle_column_st *sql_field;2600 drizzle_column_st *sql_field;
2583 string tmp_str, tmp_str_lower;2601 string tmp_str, tmp_str_lower;
25842602
2585 if (status.getBatch() || quick || !current_db)2603 if (status.getBatch() || quick || current_db.empty())
2586 return; // We don't need completion in batches2604 return; // We don't need completion in batches
2587 if (!rehash)2605 if (!rehash)
2588 return;2606 return;
@@ -2717,8 +2735,8 @@
2717 drizzle_return_t ret;2735 drizzle_return_t ret;
2718 drizzle_result_st res;2736 drizzle_result_st res;
27192737
2720 free(current_db);2738 current_db.erase();
2721 current_db= NULL;2739 current_db= "";
2722 /* In case of error below current_db will be NULL */2740 /* In case of error below current_db will be NULL */
2723 if (drizzle_query_str(&con, &res, "SELECT DATABASE()", &ret) != NULL)2741 if (drizzle_query_str(&con, &res, "SELECT DATABASE()", &ret) != NULL)
2724 {2742 {
@@ -3746,12 +3764,12 @@
3746 tmp= get_arg(buff, 0);3764 tmp= get_arg(buff, 0);
3747 if (tmp && *tmp)3765 if (tmp && *tmp)
3748 {3766 {
3749 free(current_db);3767 current_db.erase();
3750 current_db= strdup(tmp);3768 current_db= strdup(tmp);
3751 tmp= get_arg(buff, 1);3769 tmp= get_arg(buff, 1);
3752 if (tmp)3770 if (tmp)
3753 {3771 {
3754 free(current_host);3772 current_host.erase();
3755 current_host=strdup(tmp);3773 current_host=strdup(tmp);
3756 }3774 }
3757 }3775 }
@@ -3766,7 +3784,7 @@
3766 }3784 }
3767 else3785 else
3768 opt_rehash= 0;3786 opt_rehash= 0;
3769 error=sql_connect(current_host,current_db,current_user,opt_password,0);3787 error=sql_connect(current_host, current_db, current_user, opt_password,0);
3770 opt_rehash= save_rehash;3788 opt_rehash= save_rehash;
37713789
3772 if (connected)3790 if (connected)
@@ -3774,7 +3792,7 @@
3774 sprintf(buff,"Connection id: %u",drizzle_con_thread_id(&con));3792 sprintf(buff,"Connection id: %u",drizzle_con_thread_id(&con));
3775 put_info(buff,INFO_INFO,0,0);3793 put_info(buff,INFO_INFO,0,0);
3776 sprintf(buff,"Current database: %.128s\n",3794 sprintf(buff,"Current database: %.128s\n",
3777 current_db ? current_db : "*** NONE ***");3795 !current_db.empty() ? current_db.c_str() : "*** NONE ***");
3778 put_info(buff,INFO_INFO,0,0);3796 put_info(buff,INFO_INFO,0,0);
3779 }3797 }
3780 return error;3798 return error;
@@ -3896,7 +3914,7 @@
3896 */3914 */
3897 get_current_db();3915 get_current_db();
38983916
3899 if (!current_db || strcmp(current_db,tmp))3917 if (current_db.empty() || strcmp(current_db.c_str(),tmp))
3900 {3918 {
3901 if (one_database)3919 if (one_database)
3902 {3920 {
@@ -3948,7 +3966,7 @@
3948 else3966 else
3949 drizzle_result_free(&result);3967 drizzle_result_free(&result);
3950 }3968 }
3951 free(current_db);3969 current_db.erase();
3952 current_db= strdup(tmp);3970 current_db= strdup(tmp);
3953 if (select_db > 1)3971 if (select_db > 1)
3954 build_completion_hash(opt_rehash, 1);3972 build_completion_hash(opt_rehash, 1);
@@ -4037,11 +4055,10 @@
40374055
40384056
4039static int4057static int
4040sql_connect(char *host,char *database,char *user,char *password,4058sql_connect(const string &host, const string &database, const string &user, const string &password,
4041 uint32_t silent)4059 uint32_t silent)
4042{4060{
4043 drizzle_return_t ret;4061 drizzle_return_t ret;
4044
4045 if (connected)4062 if (connected)
4046 {4063 {
4047 connected= 0;4064 connected= 0;
@@ -4049,8 +4066,8 @@
4049 drizzle_free(&drizzle);4066 drizzle_free(&drizzle);
4050 }4067 }
4051 drizzle_create(&drizzle);4068 drizzle_create(&drizzle);
4052 if (drizzle_con_add_tcp(&drizzle, &con, host, opt_drizzle_port, user,4069 if (drizzle_con_add_tcp(&drizzle, &con, (char *)host.c_str(), opt_drizzle_port, (char *)user.c_str(),
4053 password, database, opt_mysql ? DRIZZLE_CON_MYSQL : DRIZZLE_CON_NONE) == NULL)4070 (char *)password.c_str(), (char *)database.c_str(), opt_mysql ? DRIZZLE_CON_MYSQL : DRIZZLE_CON_NONE) == NULL)
4054 {4071 {
4055 (void) put_error(&con, NULL);4072 (void) put_error(&con, NULL);
4056 (void) fflush(stdout);4073 (void) fflush(stdout);
@@ -4106,7 +4123,12 @@
4106 drizzle_return_t ret;4123 drizzle_return_t ret;
41074124
4108 tee_puts("--------------", stdout);4125 tee_puts("--------------", stdout);
4109 usage(1); /* Print version */4126 printf(_("%s Ver %s Distrib %s, for %s-%s (%s) using readline %s\n"),
4127 internal::my_progname, VER.c_str(), drizzle_version(),
4128 HOST_VENDOR, HOST_OS, HOST_CPU,
4129 rl_library_version); /* Print version */
4130
4131
4110 if (connected)4132 if (connected)
4111 {4133 {
4112 tee_fprintf(stdout, "\nConnection id:\t\t%lu\n",drizzle_con_thread_id(&con));4134 tee_fprintf(stdout, "\nConnection id:\t\t%lu\n",drizzle_con_thread_id(&con));
@@ -4452,7 +4474,7 @@
4452 struct tm *t = localtime(&lclock);4474 struct tm *t = localtime(&lclock);
44534475
4454 /* parse thru the settings for the prompt */4476 /* parse thru the settings for the prompt */
4455 for (char *c= current_prompt; *c; (void)*c++)4477 for (char *c= (char *)current_prompt.c_str(); *c; (void)*c++)
4456 {4478 {
4457 if (*c != PROMPT_CHAR)4479 if (*c != PROMPT_CHAR)
4458 {4480 {
@@ -4479,7 +4501,7 @@
4479 processed_prompt->append("not_connected");4501 processed_prompt->append("not_connected");
4480 break;4502 break;
4481 case 'd':4503 case 'd':
4482 processed_prompt->append(current_db ? current_db : "(none)");4504 processed_prompt->append(!current_db.empty() ? current_db.c_str() : "(none)");
4483 break;4505 break;
4484 case 'h':4506 case 'h':
4485 {4507 {
@@ -4516,13 +4538,13 @@
4516 if (!full_username)4538 if (!full_username)
4517 init_username();4539 init_username();
4518 processed_prompt->append(full_username ? full_username :4540 processed_prompt->append(full_username ? full_username :
4519 (current_user ? current_user : "(unknown)"));4541 (!current_user.empty() ? current_user.c_str() : "(unknown)"));
4520 break;4542 break;
4521 case 'u':4543 case 'u':
4522 if (!full_username)4544 if (!full_username)
4523 init_username();4545 init_username();
4524 processed_prompt->append(part_username ? part_username :4546 processed_prompt->append(part_username ? part_username :
4525 (current_user ? current_user : "(unknown)"));4547 (!current_user.empty() ? current_user.c_str() : "(unknown)"));
4526 break;4548 break;
4527 case PROMPT_CHAR:4549 case PROMPT_CHAR:
4528 {4550 {
@@ -4601,7 +4623,7 @@
4601 processed_prompt->append("\t");4623 processed_prompt->append("\t");
4602 break;4624 break;
4603 case 'l':4625 case 'l':
4604 processed_prompt->append(delimiter_str);4626 processed_prompt->append(delimiter_str.c_str());
4605 break;4627 break;
4606 default:4628 default:
4607 processed_prompt->append(c, 1);4629 processed_prompt->append(c, 1);
@@ -4649,9 +4671,9 @@
4649 tee_fprintf(stdout, "Memory allocation error. Not changing prompt\n");4671 tee_fprintf(stdout, "Memory allocation error. Not changing prompt\n");
4650 else4672 else
4651 {4673 {
4652 free(current_prompt);4674 current_prompt.erase();
4653 current_prompt= tmpptr;4675 current_prompt= tmpptr;
4654 tee_fprintf(stdout, "PROMPT set to '%s'\n", current_prompt);4676 tee_fprintf(stdout, "PROMPT set to '%s'\n", current_prompt.c_str());
4655 }4677 }
4656 return 0;4678 return 0;
4657}4679}
46584680
=== modified file 'client/include.am'
--- client/include.am 2010-06-02 16:51:50 +0000
+++ client/include.am 2010-06-04 16:41:24 +0000
@@ -45,7 +45,7 @@
4545
4646
47client_drizzle_SOURCES= client/drizzle.cc client/linebuffer.cc47client_drizzle_SOURCES= client/drizzle.cc client/linebuffer.cc
48client_drizzle_LDADD= ${CLIENT_LDADD} ${READLINE_LIBS}48client_drizzle_LDADD= ${CLIENT_LDADD} ${READLINE_LIBS} ${BOOST_LIBS}
49client_drizzle_CXXFLAGS= ${CLIENT_CXXFLAGS}49client_drizzle_CXXFLAGS= ${CLIENT_CXXFLAGS}
5050
51client_drizzledump_SOURCES= client/drizzledump.cc51client_drizzledump_SOURCES= client/drizzledump.cc