00001 /* Copyright (C) 2000 MySQL AB 00002 00003 This program is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU General Public License as published by 00005 the Free Software Foundation; either version 2 of the License, or 00006 (at your option) any later version. 00007 00008 This program is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 GNU General Public License for more details. 00012 00013 You should have received a copy of the GNU General Public License 00014 along with this program; if not, write to the Free Software 00015 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 00016 00017 /* Show databases, tables or columns */ 00018 00019 #define SHOW_VERSION "9.5" 00020 00021 #include "client_priv.h" 00022 #include <my_sys.h> 00023 #include <m_string.h> 00024 #include <mysql.h> 00025 #include <mysqld_error.h> 00026 #include <signal.h> 00027 #include <stdarg.h> 00028 #include <sslopt-vars.h> 00029 00030 static my_string host=0,opt_password=0,user=0; 00031 static my_bool opt_show_keys= 0, opt_compress= 0, opt_count=0, opt_status= 0, 00032 tty_password= 0, opt_table_type= 0; 00033 static uint opt_verbose=0; 00034 static char *default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME; 00035 00036 #ifdef HAVE_SMEM 00037 static char *shared_memory_base_name=0; 00038 #endif 00039 static uint opt_protocol=0; 00040 00041 static void get_options(int *argc,char ***argv); 00042 static uint opt_mysql_port=0; 00043 static int list_dbs(MYSQL *mysql,const char *wild); 00044 static int list_tables(MYSQL *mysql,const char *db,const char *table); 00045 static int list_table_status(MYSQL *mysql,const char *db,const char *table); 00046 static int list_fields(MYSQL *mysql,const char *db,const char *table, 00047 const char *field); 00048 static void print_header(const char *header,uint head_length,...); 00049 static void print_row(const char *header,uint head_length,...); 00050 static void print_trailer(uint length,...); 00051 static void print_res_header(MYSQL_RES *result); 00052 static void print_res_top(MYSQL_RES *result); 00053 static void print_res_row(MYSQL_RES *result,MYSQL_ROW cur); 00054 00055 static const char *load_default_groups[]= { "mysqlshow","client",0 }; 00056 static my_string opt_mysql_unix_port=0; 00057 00058 int main(int argc, char **argv) 00059 { 00060 int error; 00061 my_bool first_argument_uses_wildcards=0; 00062 char *wild; 00063 MYSQL mysql; 00064 MY_INIT(argv[0]); 00065 load_defaults("my",load_default_groups,&argc,&argv); 00066 get_options(&argc,&argv); 00067 00068 wild=0; 00069 if (argc) 00070 { 00071 char *pos= argv[argc-1], *to; 00072 for (to= pos ; *pos ; pos++, to++) 00073 { 00074 switch (*pos) { 00075 case '*': 00076 *pos= '%'; 00077 first_argument_uses_wildcards= 1; 00078 break; 00079 case '?': 00080 *pos= '_'; 00081 first_argument_uses_wildcards= 1; 00082 break; 00083 case '%': 00084 case '_': 00085 first_argument_uses_wildcards= 1; 00086 break; 00087 case '\\': 00088 pos++; 00089 default: break; 00090 } 00091 *to= *pos; 00092 } 00093 *to= *pos; /* just to copy a '\0' if '\\' was used */ 00094 } 00095 if (first_argument_uses_wildcards) 00096 wild= argv[--argc]; 00097 else if (argc == 3) /* We only want one field */ 00098 wild= argv[--argc]; 00099 00100 if (argc > 2) 00101 { 00102 fprintf(stderr,"%s: Too many arguments\n",my_progname); 00103 exit(1); 00104 } 00105 mysql_init(&mysql); 00106 if (opt_compress) 00107 mysql_options(&mysql,MYSQL_OPT_COMPRESS,NullS); 00108 #ifdef HAVE_OPENSSL 00109 if (opt_use_ssl) 00110 mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, 00111 opt_ssl_capath, opt_ssl_cipher); 00112 mysql_options(&mysql,MYSQL_OPT_SSL_VERIFY_SERVER_CERT, 00113 (char*)&opt_ssl_verify_server_cert); 00114 #endif 00115 if (opt_protocol) 00116 mysql_options(&mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol); 00117 #ifdef HAVE_SMEM 00118 if (shared_memory_base_name) 00119 mysql_options(&mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name); 00120 #endif 00121 mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, default_charset); 00122 00123 if (!(mysql_real_connect(&mysql,host,user,opt_password, 00124 (first_argument_uses_wildcards) ? "" : argv[0],opt_mysql_port,opt_mysql_unix_port, 00125 0))) 00126 { 00127 fprintf(stderr,"%s: %s\n",my_progname,mysql_error(&mysql)); 00128 exit(1); 00129 } 00130 mysql.reconnect= 1; 00131 00132 switch (argc) 00133 { 00134 case 0: error=list_dbs(&mysql,wild); break; 00135 case 1: 00136 if (opt_status) 00137 error=list_table_status(&mysql,argv[0],wild); 00138 else 00139 error=list_tables(&mysql,argv[0],wild); 00140 break; 00141 default: 00142 if (opt_status && ! wild) 00143 error=list_table_status(&mysql,argv[0],argv[1]); 00144 else 00145 error=list_fields(&mysql,argv[0],argv[1],wild); 00146 break; 00147 } 00148 mysql_close(&mysql); /* Close & free connection */ 00149 if (opt_password) 00150 my_free(opt_password,MYF(0)); 00151 #ifdef HAVE_SMEM 00152 my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR)); 00153 #endif 00154 my_end(0); 00155 exit(error ? 1 : 0); 00156 return 0; /* No compiler warnings */ 00157 } 00158 00159 static struct my_option my_long_options[] = 00160 { 00161 #ifdef __NETWARE__ 00162 {"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", 00163 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, 00164 #endif 00165 {"character-sets-dir", 'c', "Directory where character sets are.", 00166 (gptr*) &charsets_dir, (gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 00167 0, 0, 0, 0, 0}, 00168 {"default-character-set", OPT_DEFAULT_CHARSET, 00169 "Set the default character set.", (gptr*) &default_charset, 00170 (gptr*) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, 00171 {"count", OPT_COUNT, 00172 "Show number of rows per table (may be slow for not MyISAM tables)", 00173 (gptr*) &opt_count, (gptr*) &opt_count, 0, GET_BOOL, NO_ARG, 0, 0, 0, 00174 0, 0, 0}, 00175 {"compress", 'C', "Use compression in server/client protocol.", 00176 (gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0, 00177 0, 0, 0}, 00178 {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.", 00179 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, 00180 {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 00181 0, 0, 0, 0, 0, 0}, 00182 {"host", 'h', "Connect to host.", (gptr*) &host, (gptr*) &host, 0, GET_STR, 00183 REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, 00184 {"status", 'i', "Shows a lot of extra information about each table.", 00185 (gptr*) &opt_status, (gptr*) &opt_status, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 00186 0, 0}, 00187 {"keys", 'k', "Show keys for table.", (gptr*) &opt_show_keys, 00188 (gptr*) &opt_show_keys, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, 00189 {"password", 'p', 00190 "Password to use when connecting to server. If password is not given it's asked from the tty.", 00191 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, 00192 {"port", 'P', "Port number to use for connection.", (gptr*) &opt_mysql_port, 00193 (gptr*) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 00194 0}, 00195 #ifdef __WIN__ 00196 {"pipe", 'W', "Use named pipes to connect to server.", 0, 0, 0, GET_NO_ARG, 00197 NO_ARG, 0, 0, 0, 0, 0, 0}, 00198 #endif 00199 {"protocol", OPT_MYSQL_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).", 00200 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, 00201 #ifdef HAVE_SMEM 00202 {"shared-memory-base-name", OPT_SHARED_MEMORY_BASE_NAME, 00203 "Base name of shared memory.", (gptr*) &shared_memory_base_name, (gptr*) &shared_memory_base_name, 00204 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, 00205 #endif 00206 {"show-table-type", 't', "Show table type column.", 00207 (gptr*) &opt_table_type, (gptr*) &opt_table_type, 0, GET_BOOL, 00208 NO_ARG, 0, 0, 0, 0, 0, 0}, 00209 {"socket", 'S', "Socket file to use for connection.", 00210 (gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, GET_STR, 00211 REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, 00212 #include <sslopt-longopts.h> 00213 #ifndef DONT_ALLOW_USER_CHANGE 00214 {"user", 'u', "User for login if not current user.", (gptr*) &user, 00215 (gptr*) &user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, 00216 #endif 00217 {"verbose", 'v', 00218 "More verbose output; You can use this multiple times to get even more verbose output.", 00219 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, 00220 {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG, 00221 NO_ARG, 0, 0, 0, 0, 0, 0}, 00222 {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} 00223 }; 00224 00225 00226 #include <help_start.h> 00227 00228 static void print_version(void) 00229 { 00230 printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,SHOW_VERSION, 00231 MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE); 00232 NETWARE_SET_SCREEN_MODE(1); 00233 } 00234 00235 00236 static void usage(void) 00237 { 00238 print_version(); 00239 puts("Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB"); 00240 puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n"); 00241 puts("Shows the structure of a mysql database (databases,tables and columns)\n"); 00242 printf("Usage: %s [OPTIONS] [database [table [column]]]\n",my_progname); 00243 puts("\n\ 00244 If last argument contains a shell or SQL wildcard (*,?,% or _) then only\n\ 00245 what\'s matched by the wildcard is shown.\n\ 00246 If no database is given then all matching databases are shown.\n\ 00247 If no table is given then all matching tables in database are shown\n\ 00248 If no column is given then all matching columns and columntypes in table\n\ 00249 are shown"); 00250 print_defaults("my",load_default_groups); 00251 my_print_help(my_long_options); 00252 my_print_variables(my_long_options); 00253 } 00254 00255 #include <help_end.h> 00256 00257 static my_bool 00258 get_one_option(int optid, const struct my_option *opt __attribute__((unused)), 00259 char *argument) 00260 { 00261 switch(optid) { 00262 #ifdef __NETWARE__ 00263 case OPT_AUTO_CLOSE: 00264 setscreenmode(SCR_AUTOCLOSE_ON_EXIT); 00265 break; 00266 #endif 00267 case 'v': 00268 opt_verbose++; 00269 break; 00270 case 'p': 00271 if (argument) 00272 { 00273 char *start=argument; 00274 my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR)); 00275 opt_password=my_strdup(argument,MYF(MY_FAE)); 00276 while (*argument) *argument++= 'x'; /* Destroy argument */ 00277 if (*start) 00278 start[1]=0; /* Cut length of argument */ 00279 tty_password= 0; 00280 } 00281 else 00282 tty_password=1; 00283 break; 00284 case 'W': 00285 #ifdef __WIN__ 00286 opt_protocol = MYSQL_PROTOCOL_PIPE; 00287 #endif 00288 break; 00289 case OPT_MYSQL_PROTOCOL: 00290 { 00291 if ((opt_protocol= find_type(argument, &sql_protocol_typelib,0)) <= 0) 00292 { 00293 fprintf(stderr, "Unknown option to protocol: %s\n", argument); 00294 exit(1); 00295 } 00296 break; 00297 } 00298 case '#': 00299 DBUG_PUSH(argument ? argument : "d:t:o"); 00300 break; 00301 #include <sslopt-case.h> 00302 case 'V': 00303 print_version(); 00304 exit(0); 00305 break; 00306 case '?': 00307 case 'I': /* Info */ 00308 usage(); 00309 exit(0); 00310 } 00311 return 0; 00312 } 00313 00314 00315 static void 00316 get_options(int *argc,char ***argv) 00317 { 00318 int ho_error; 00319 00320 if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option))) 00321 exit(ho_error); 00322 00323 if (tty_password) 00324 opt_password=get_tty_password(NullS); 00325 if (opt_count) 00326 { 00327 /* 00328 We need to set verbose to 2 as we need to change the output to include 00329 the number-of-rows column 00330 */ 00331 opt_verbose= 2; 00332 } 00333 return; 00334 } 00335 00336 00337 static int 00338 list_dbs(MYSQL *mysql,const char *wild) 00339 { 00340 const char *header; 00341 uint length, counter = 0; 00342 ulong rowcount = 0L; 00343 char tables[NAME_LEN+1], rows[NAME_LEN+1]; 00344 char query[255]; 00345 MYSQL_FIELD *field; 00346 MYSQL_RES *result; 00347 MYSQL_ROW row= NULL, rrow; 00348 00349 if (!(result=mysql_list_dbs(mysql,wild))) 00350 { 00351 fprintf(stderr,"%s: Cannot list databases: %s\n",my_progname, 00352 mysql_error(mysql)); 00353 return 1; 00354 } 00355 00356 /* 00357 If a wildcard was used, but there was only one row and it's name is an 00358 exact match, we'll assume they really wanted to see the contents of that 00359 database. This is because it is fairly common for database names to 00360 contain the underscore (_), like INFORMATION_SCHEMA. 00361 */ 00362 if (wild && mysql_num_rows(result) == 1) 00363 { 00364 row= mysql_fetch_row(result); 00365 if (!my_strcasecmp(&my_charset_latin1, row[0], wild)) 00366 { 00367 mysql_free_result(result); 00368 if (opt_status) 00369 return list_table_status(mysql, wild, NULL); 00370 else 00371 return list_tables(mysql, wild, NULL); 00372 } 00373 } 00374 00375 if (wild) 00376 printf("Wildcard: %s\n",wild); 00377 00378 header="Databases"; 00379 length=(uint) strlen(header); 00380 field=mysql_fetch_field(result); 00381 if (length < field->max_length) 00382 length=field->max_length; 00383 00384 if (!opt_verbose) 00385 print_header(header,length,NullS); 00386 else if (opt_verbose == 1) 00387 print_header(header,length,"Tables",6,NullS); 00388 else 00389 print_header(header,length,"Tables",6,"Total Rows",12,NullS); 00390 00391 /* The first row may have already been read up above. */ 00392 while (row || (row= mysql_fetch_row(result))) 00393 { 00394 counter++; 00395 00396 if (opt_verbose) 00397 { 00398 if (!(mysql_select_db(mysql,row[0]))) 00399 { 00400 MYSQL_RES *tresult = mysql_list_tables(mysql,(char*)NULL); 00401 if (mysql_affected_rows(mysql) > 0) 00402 { 00403 sprintf(tables,"%6lu",(ulong) mysql_affected_rows(mysql)); 00404 rowcount = 0; 00405 if (opt_verbose > 1) 00406 { 00407 /* Print the count of tables and rows for each database */ 00408 MYSQL_ROW trow; 00409 while ((trow = mysql_fetch_row(tresult))) 00410 { 00411 sprintf(query,"SELECT COUNT(*) FROM `%s`",trow[0]); 00412 if (!(mysql_query(mysql,query))) 00413 { 00414 MYSQL_RES *rresult; 00415 if ((rresult = mysql_store_result(mysql))) 00416 { 00417 rrow = mysql_fetch_row(rresult); 00418 rowcount += (ulong) strtoull(rrow[0], (char**) 0, 10); 00419 mysql_free_result(rresult); 00420 } 00421 } 00422 } 00423 sprintf(rows,"%12lu",rowcount); 00424 } 00425 } 00426 else 00427 { 00428 sprintf(tables,"%6d",0); 00429 sprintf(rows,"%12d",0); 00430 } 00431 mysql_free_result(tresult); 00432 } 00433 else 00434 { 00435 strmov(tables,"N/A"); 00436 strmov(rows,"N/A"); 00437 } 00438 } 00439 00440 if (!opt_verbose) 00441 print_row(row[0],length,0); 00442 else if (opt_verbose == 1) 00443 print_row(row[0],length,tables,6,NullS); 00444 else 00445 print_row(row[0],length,tables,6,rows,12,NullS); 00446 00447 row= NULL; 00448 } 00449 00450 print_trailer(length, 00451 (opt_verbose > 0 ? 6 : 0), 00452 (opt_verbose > 1 ? 12 :0), 00453 0); 00454 00455 if (counter && opt_verbose) 00456 printf("%u row%s in set.\n",counter,(counter > 1) ? "s" : ""); 00457 mysql_free_result(result); 00458 return 0; 00459 } 00460 00461 00462 static int 00463 list_tables(MYSQL *mysql,const char *db,const char *table) 00464 { 00465 const char *header; 00466 uint head_length, counter = 0; 00467 char query[255], rows[NAME_LEN], fields[16]; 00468 MYSQL_FIELD *field; 00469 MYSQL_RES *result; 00470 MYSQL_ROW row, rrow; 00471 00472 if (mysql_select_db(mysql,db)) 00473 { 00474 fprintf(stderr,"%s: Cannot connect to db %s: %s\n",my_progname,db, 00475 mysql_error(mysql)); 00476 return 1; 00477 } 00478 if (table) 00479 { 00480 /* 00481 We just hijack the 'rows' variable for a bit to store the escaped 00482 table name 00483 */ 00484 mysql_real_escape_string(mysql, rows, table, (unsigned long)strlen(table)); 00485 my_snprintf(query, sizeof(query), "show%s tables like '%s'", 00486 opt_table_type ? " full" : "", rows); 00487 } 00488 else 00489 my_snprintf(query, sizeof(query), "show%s tables", 00490 opt_table_type ? " full" : ""); 00491 if (mysql_query(mysql, query) || !(result= mysql_store_result(mysql))) 00492 { 00493 fprintf(stderr,"%s: Cannot list tables in %s: %s\n",my_progname,db, 00494 mysql_error(mysql)); 00495 exit(1); 00496 } 00497 printf("Database: %s",db); 00498 if (table) 00499 printf(" Wildcard: %s",table); 00500 putchar('\n'); 00501 00502 header="Tables"; 00503 head_length=(uint) strlen(header); 00504 field=mysql_fetch_field(result); 00505 if (head_length < field->max_length) 00506 head_length=field->max_length; 00507 00508 if (opt_table_type) 00509 { 00510 if (!opt_verbose) 00511 print_header(header,head_length,"table_type",10,NullS); 00512 else if (opt_verbose == 1) 00513 print_header(header,head_length,"table_type",10,"Columns",8,NullS); 00514 else 00515 { 00516 print_header(header,head_length,"table_type",10,"Columns",8, 00517 "Total Rows",10,NullS); 00518 } 00519 } 00520 else 00521 { 00522 if (!opt_verbose) 00523 print_header(header,head_length,NullS); 00524 else if (opt_verbose == 1) 00525 print_header(header,head_length,"Columns",8,NullS); 00526 else 00527 print_header(header,head_length,"Columns",8, "Total Rows",10,NullS); 00528 } 00529 00530 while ((row = mysql_fetch_row(result))) 00531 { 00532 counter++; 00533 if (opt_verbose > 0) 00534 { 00535 if (!(mysql_select_db(mysql,db))) 00536 { 00537 MYSQL_RES *rresult = mysql_list_fields(mysql,row[0],NULL); 00538 ulong rowcount=0L; 00539 if (!rresult) 00540 { 00541 strmov(fields,"N/A"); 00542 strmov(rows,"N/A"); 00543 } 00544 else 00545 { 00546 sprintf(fields,"%8u",(uint) mysql_num_fields(rresult)); 00547 mysql_free_result(rresult); 00548 00549 if (opt_verbose > 1) 00550 { 00551 /* Print the count of rows for each table */ 00552 sprintf(query,"SELECT COUNT(*) FROM `%s`",row[0]); 00553 if (!(mysql_query(mysql,query))) 00554 { 00555 if ((rresult = mysql_store_result(mysql))) 00556 { 00557 rrow = mysql_fetch_row(rresult); 00558 rowcount += (unsigned long) strtoull(rrow[0], (char**) 0, 10); 00559 mysql_free_result(rresult); 00560 } 00561 sprintf(rows,"%10lu",rowcount); 00562 } 00563 else 00564 sprintf(rows,"%10d",0); 00565 } 00566 } 00567 } 00568 else 00569 { 00570 strmov(fields,"N/A"); 00571 strmov(rows,"N/A"); 00572 } 00573 } 00574 if (opt_table_type) 00575 { 00576 if (!opt_verbose) 00577 print_row(row[0],head_length,row[1],10,NullS); 00578 else if (opt_verbose == 1) 00579 print_row(row[0],head_length,row[1],10,fields,8,NullS); 00580 else 00581 print_row(row[0],head_length,row[1],10,fields,8,rows,10,NullS); 00582 } 00583 else 00584 { 00585 if (!opt_verbose) 00586 print_row(row[0],head_length,NullS); 00587 else if (opt_verbose == 1) 00588 print_row(row[0],head_length, fields,8, NullS); 00589 else 00590 print_row(row[0],head_length, fields,8, rows,10, NullS); 00591 } 00592 } 00593 00594 print_trailer(head_length, 00595 (opt_table_type ? 10 : opt_verbose > 0 ? 8 : 0), 00596 (opt_table_type ? (opt_verbose > 0 ? 8 : 0) 00597 : (opt_verbose > 1 ? 10 :0)), 00598 !opt_table_type ? 0 : opt_verbose > 1 ? 10 :0, 00599 0); 00600 00601 if (counter && opt_verbose) 00602 printf("%u row%s in set.\n\n",counter,(counter > 1) ? "s" : ""); 00603 00604 mysql_free_result(result); 00605 return 0; 00606 } 00607 00608 00609 static int 00610 list_table_status(MYSQL *mysql,const char *db,const char *wild) 00611 { 00612 char query[1024],*end; 00613 MYSQL_RES *result; 00614 MYSQL_ROW row; 00615 00616 end=strxmov(query,"show table status from `",db,"`",NullS); 00617 if (wild && wild[0]) 00618 strxmov(end," like '",wild,"'",NullS); 00619 if (mysql_query(mysql,query) || !(result=mysql_store_result(mysql))) 00620 { 00621 fprintf(stderr,"%s: Cannot get status for db: %s, table: %s: %s\n", 00622 my_progname,db,wild ? wild : "",mysql_error(mysql)); 00623 if (mysql_errno(mysql) == ER_PARSE_ERROR) 00624 fprintf(stderr,"This error probably means that your MySQL server doesn't support the\n\'show table status' command.\n"); 00625 return 1; 00626 } 00627 00628 printf("Database: %s",db); 00629 if (wild) 00630 printf(" Wildcard: %s",wild); 00631 putchar('\n'); 00632 00633 print_res_header(result); 00634 while ((row=mysql_fetch_row(result))) 00635 print_res_row(result,row); 00636 print_res_top(result); 00637 mysql_free_result(result); 00638 return 0; 00639 } 00640 00641 /* 00642 list fields uses field interface as an example of how to parse 00643 a MYSQL FIELD 00644 */ 00645 00646 static int 00647 list_fields(MYSQL *mysql,const char *db,const char *table, 00648 const char *wild) 00649 { 00650 char query[1024],*end; 00651 MYSQL_RES *result; 00652 MYSQL_ROW row; 00653 ulong rows; 00654 LINT_INIT(rows); 00655 00656 if (mysql_select_db(mysql,db)) 00657 { 00658 fprintf(stderr,"%s: Cannot connect to db: %s: %s\n",my_progname,db, 00659 mysql_error(mysql)); 00660 return 1; 00661 } 00662 00663 if (opt_count) 00664 { 00665 sprintf(query,"select count(*) from `%s`", table); 00666 if (mysql_query(mysql,query) || !(result=mysql_store_result(mysql))) 00667 { 00668 fprintf(stderr,"%s: Cannot get record count for db: %s, table: %s: %s\n", 00669 my_progname,db,table,mysql_error(mysql)); 00670 return 1; 00671 } 00672 row= mysql_fetch_row(result); 00673 rows= (ulong) strtoull(row[0], (char**) 0, 10); 00674 mysql_free_result(result); 00675 } 00676 00677 end=strmov(strmov(strmov(query,"show /*!32332 FULL */ columns from `"),table),"`"); 00678 if (wild && wild[0]) 00679 strxmov(end," like '",wild,"'",NullS); 00680 if (mysql_query(mysql,query) || !(result=mysql_store_result(mysql))) 00681 { 00682 fprintf(stderr,"%s: Cannot list columns in db: %s, table: %s: %s\n", 00683 my_progname,db,table,mysql_error(mysql)); 00684 return 1; 00685 } 00686 00687 printf("Database: %s Table: %s", db, table); 00688 if (opt_count) 00689 printf(" Rows: %lu", rows); 00690 if (wild && wild[0]) 00691 printf(" Wildcard: %s",wild); 00692 putchar('\n'); 00693 00694 print_res_header(result); 00695 while ((row=mysql_fetch_row(result))) 00696 print_res_row(result,row); 00697 print_res_top(result); 00698 if (opt_show_keys) 00699 { 00700 end=strmov(strmov(strmov(query,"show keys from `"),table),"`"); 00701 if (mysql_query(mysql,query) || !(result=mysql_store_result(mysql))) 00702 { 00703 fprintf(stderr,"%s: Cannot list keys in db: %s, table: %s: %s\n", 00704 my_progname,db,table,mysql_error(mysql)); 00705 return 1; 00706 } 00707 if (mysql_num_rows(result)) 00708 { 00709 print_res_header(result); 00710 while ((row=mysql_fetch_row(result))) 00711 print_res_row(result,row); 00712 print_res_top(result); 00713 } 00714 else 00715 puts("Table has no keys"); 00716 } 00717 mysql_free_result(result); 00718 return 0; 00719 } 00720 00721 00722 /***************************************************************************** 00723 General functions to print a nice ascii-table from data 00724 *****************************************************************************/ 00725 00726 static void 00727 print_header(const char *header,uint head_length,...) 00728 { 00729 va_list args; 00730 uint length,i,str_length,pre_space; 00731 const char *field; 00732 00733 va_start(args,head_length); 00734 putchar('+'); 00735 field=header; length=head_length; 00736 for (;;) 00737 { 00738 for (i=0 ; i < length+2 ; i++) 00739 putchar('-'); 00740 putchar('+'); 00741 if (!(field=va_arg(args,my_string))) 00742 break; 00743 length=va_arg(args,uint); 00744 } 00745 va_end(args); 00746 putchar('\n'); 00747 00748 va_start(args,head_length); 00749 field=header; length=head_length; 00750 putchar('|'); 00751 for (;;) 00752 { 00753 str_length=(uint) strlen(field); 00754 if (str_length > length) 00755 str_length=length+1; 00756 pre_space=(uint) (((int) length-(int) str_length)/2)+1; 00757 for (i=0 ; i < pre_space ; i++) 00758 putchar(' '); 00759 for (i = 0 ; i < str_length ; i++) 00760 putchar(field[i]); 00761 length=length+2-str_length-pre_space; 00762 for (i=0 ; i < length ; i++) 00763 putchar(' '); 00764 putchar('|'); 00765 if (!(field=va_arg(args,my_string))) 00766 break; 00767 length=va_arg(args,uint); 00768 } 00769 va_end(args); 00770 putchar('\n'); 00771 00772 va_start(args,head_length); 00773 putchar('+'); 00774 field=header; length=head_length; 00775 for (;;) 00776 { 00777 for (i=0 ; i < length+2 ; i++) 00778 putchar('-'); 00779 putchar('+'); 00780 if (!(field=va_arg(args,my_string))) 00781 break; 00782 length=va_arg(args,uint); 00783 } 00784 va_end(args); 00785 putchar('\n'); 00786 } 00787 00788 00789 static void 00790 print_row(const char *header,uint head_length,...) 00791 { 00792 va_list args; 00793 const char *field; 00794 uint i,length,field_length; 00795 00796 va_start(args,head_length); 00797 field=header; length=head_length; 00798 for (;;) 00799 { 00800 putchar('|'); 00801 putchar(' '); 00802 fputs(field,stdout); 00803 field_length=(uint) strlen(field); 00804 for (i=field_length ; i <= length ; i++) 00805 putchar(' '); 00806 if (!(field=va_arg(args,my_string))) 00807 break; 00808 length=va_arg(args,uint); 00809 } 00810 va_end(args); 00811 putchar('|'); 00812 putchar('\n'); 00813 } 00814 00815 00816 static void 00817 print_trailer(uint head_length,...) 00818 { 00819 va_list args; 00820 uint length,i; 00821 00822 va_start(args,head_length); 00823 length=head_length; 00824 putchar('+'); 00825 for (;;) 00826 { 00827 for (i=0 ; i < length+2 ; i++) 00828 putchar('-'); 00829 putchar('+'); 00830 if (!(length=va_arg(args,uint))) 00831 break; 00832 } 00833 va_end(args); 00834 putchar('\n'); 00835 } 00836 00837 00838 static void print_res_header(MYSQL_RES *result) 00839 { 00840 MYSQL_FIELD *field; 00841 00842 print_res_top(result); 00843 mysql_field_seek(result,0); 00844 putchar('|'); 00845 while ((field = mysql_fetch_field(result))) 00846 { 00847 printf(" %-*s|",(int) field->max_length+1,field->name); 00848 } 00849 putchar('\n'); 00850 print_res_top(result); 00851 } 00852 00853 00854 static void print_res_top(MYSQL_RES *result) 00855 { 00856 uint i,length; 00857 MYSQL_FIELD *field; 00858 00859 putchar('+'); 00860 mysql_field_seek(result,0); 00861 while((field = mysql_fetch_field(result))) 00862 { 00863 if ((length=(uint) strlen(field->name)) > field->max_length) 00864 field->max_length=length; 00865 else 00866 length=field->max_length; 00867 for (i=length+2 ; i--> 0 ; ) 00868 putchar('-'); 00869 putchar('+'); 00870 } 00871 putchar('\n'); 00872 } 00873 00874 00875 static void print_res_row(MYSQL_RES *result,MYSQL_ROW cur) 00876 { 00877 uint i,length; 00878 MYSQL_FIELD *field; 00879 putchar('|'); 00880 mysql_field_seek(result,0); 00881 for (i=0 ; i < mysql_num_fields(result); i++) 00882 { 00883 field = mysql_fetch_field(result); 00884 length=field->max_length; 00885 printf(" %-*s|",length+1,cur[i] ? (char*) cur[i] : ""); 00886 } 00887 putchar('\n'); 00888 }
1.4.7

