~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/mysqlshow.c

Removed reference to aio.h - we don't reference its use anywhere.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2000-2006 MySQL AB
 
2
 
 
3
   This program is free software; you can redistribute it and/or modify
 
4
   it under the terms of the GNU General Public License as published by
 
5
   the Free Software Foundation; version 2 of the License.
 
6
 
 
7
   This program is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
   GNU General Public License for more details.
 
11
 
 
12
   You should have received a copy of the GNU General Public License
 
13
   along with this program; if not, write to the Free Software
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
15
 
 
16
/* Show databases, tables or columns */
 
17
 
 
18
#define SHOW_VERSION "9.10"
 
19
 
 
20
#include "client_priv.h"
 
21
#include <my_sys.h>
 
22
#include <m_string.h>
 
23
#include <mysql.h>
 
24
#include <mysqld_error.h>
 
25
#include <signal.h>
 
26
#include <stdarg.h>
 
27
 
 
28
static char * host=0, *opt_password=0, *user=0;
 
29
static my_bool opt_show_keys= 0, opt_compress= 0, opt_count=0, opt_status= 0;
 
30
static my_bool tty_password= 0, opt_table_type= 0;
 
31
static my_bool debug_info_flag= 0, debug_check_flag= 0;
 
32
static uint my_end_arg= 0;
 
33
static uint opt_verbose=0;
 
34
static char *default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME;
 
35
 
 
36
#ifdef HAVE_SMEM 
 
37
static char *shared_memory_base_name=0;
 
38
#endif
 
39
static uint opt_protocol=0;
 
40
 
 
41
static void get_options(int *argc,char ***argv);
 
42
static uint opt_mysql_port=0;
 
43
static int list_dbs(MYSQL *mysql,const char *wild);
 
44
static int list_tables(MYSQL *mysql,const char *db,const char *table);
 
45
static int list_table_status(MYSQL *mysql,const char *db,const char *table);
 
46
static int list_fields(MYSQL *mysql,const char *db,const char *table,
 
47
                       const char *field);
 
48
static void print_header(const char *header,uint head_length,...);
 
49
static void print_row(const char *header,uint head_length,...);
 
50
static void print_trailer(uint length,...);
 
51
static void print_res_header(MYSQL_RES *result);
 
52
static void print_res_top(MYSQL_RES *result);
 
53
static void print_res_row(MYSQL_RES *result,MYSQL_ROW cur);
 
54
 
 
55
static const char *load_default_groups[]= { "mysqlshow","client",0 };
 
56
static char * opt_mysql_unix_port=0;
 
57
 
 
58
int main(int argc, char **argv)
 
59
{
 
60
  int error;
 
61
  my_bool first_argument_uses_wildcards=0;
 
62
  char *wild;
 
63
  MYSQL mysql;
 
64
  MY_INIT(argv[0]);
 
65
  load_defaults("my",load_default_groups,&argc,&argv);
 
66
  get_options(&argc,&argv);
 
67
 
 
68
  wild=0;
 
69
  if (argc)
 
70
  {
 
71
    char *pos= argv[argc-1], *to;
 
72
    for (to= pos ; *pos ; pos++, to++)
 
73
    {
 
74
      switch (*pos) {
 
75
      case '*':
 
76
        *pos= '%';
 
77
        first_argument_uses_wildcards= 1;
 
78
        break;
 
79
      case '?':
 
80
        *pos= '_';
 
81
        first_argument_uses_wildcards= 1;
 
82
        break;
 
83
      case '%':
 
84
      case '_':
 
85
        first_argument_uses_wildcards= 1;
 
86
        break;
 
87
      case '\\':
 
88
        pos++;
 
89
      default: break;
 
90
      }
 
91
      *to= *pos;
 
92
    }    
 
93
    *to= *pos; /* just to copy a '\0'  if '\\' was used */
 
94
  }
 
95
  if (first_argument_uses_wildcards)
 
96
    wild= argv[--argc];
 
97
  else if (argc == 3)                   /* We only want one field */
 
98
    wild= argv[--argc];
 
99
 
 
100
  if (argc > 2)
 
101
  {
 
102
    fprintf(stderr,"%s: Too many arguments\n",my_progname);
 
103
    exit(1);
 
104
  }
 
105
  mysql_init(&mysql);
 
106
  if (opt_compress)
 
107
    mysql_options(&mysql,MYSQL_OPT_COMPRESS,NullS);
 
108
  if (opt_protocol)
 
109
    mysql_options(&mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
 
110
#ifdef HAVE_SMEM
 
111
  if (shared_memory_base_name)
 
112
    mysql_options(&mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
 
113
#endif
 
114
  mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, default_charset);
 
115
 
 
116
  if (!(mysql_real_connect(&mysql,host,user,opt_password,
 
117
                           (first_argument_uses_wildcards) ? "" :
 
118
                           argv[0],opt_mysql_port,opt_mysql_unix_port,
 
119
                           0)))
 
120
  {
 
121
    fprintf(stderr,"%s: %s\n",my_progname,mysql_error(&mysql));
 
122
    exit(1);
 
123
  }
 
124
  mysql.reconnect= 1;
 
125
 
 
126
  switch (argc) {
 
127
  case 0:  error=list_dbs(&mysql,wild); break;
 
128
  case 1:
 
129
    if (opt_status)
 
130
      error=list_table_status(&mysql,argv[0],wild);
 
131
    else
 
132
      error=list_tables(&mysql,argv[0],wild);
 
133
    break;
 
134
  default:
 
135
    if (opt_status && ! wild)
 
136
      error=list_table_status(&mysql,argv[0],argv[1]);
 
137
    else
 
138
      error=list_fields(&mysql,argv[0],argv[1],wild);
 
139
    break;
 
140
  }
 
141
  mysql_close(&mysql);                  /* Close & free connection */
 
142
  if (opt_password)
 
143
    my_free(opt_password,MYF(0));
 
144
#ifdef HAVE_SMEM
 
145
  my_free(shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
 
146
#endif
 
147
  my_end(my_end_arg);
 
148
  exit(error ? 1 : 0);
 
149
}
 
150
 
 
151
static struct my_option my_long_options[] =
 
152
{
 
153
  {"character-sets-dir", 'c', "Directory where character sets are.",
 
154
   (uchar**) &charsets_dir, (uchar**) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0,
 
155
   0, 0, 0, 0, 0},
 
156
  {"default-character-set", OPT_DEFAULT_CHARSET,
 
157
   "Set the default character set.", (uchar**) &default_charset,
 
158
   (uchar**) &default_charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
159
  {"count", OPT_COUNT,
 
160
   "Show number of rows per table (may be slow for not MyISAM tables)",
 
161
   (uchar**) &opt_count, (uchar**) &opt_count, 0, GET_BOOL, NO_ARG, 0, 0, 0,
 
162
   0, 0, 0},
 
163
  {"compress", 'C', "Use compression in server/client protocol.",
 
164
   (uchar**) &opt_compress, (uchar**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
 
165
   0, 0, 0},
 
166
  {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.",
 
167
   0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
168
  {"debug-check", OPT_DEBUG_CHECK, "Check memory and open file usage at exit.",
 
169
   (uchar**) &debug_check_flag, (uchar**) &debug_check_flag, 0,
 
170
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
171
  {"debug-info", OPT_DEBUG_INFO, "Print some debug info at exit.",
 
172
   (uchar**) &debug_info_flag, (uchar**) &debug_info_flag,
 
173
   0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
174
  {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG,
 
175
   0, 0, 0, 0, 0, 0},
 
176
  {"host", 'h', "Connect to host.", (uchar**) &host, (uchar**) &host, 0, GET_STR,
 
177
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
178
  {"status", 'i', "Shows a lot of extra information about each table.",
 
179
   (uchar**) &opt_status, (uchar**) &opt_status, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
 
180
   0, 0},
 
181
  {"keys", 'k', "Show keys for table.", (uchar**) &opt_show_keys,
 
182
   (uchar**) &opt_show_keys, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
183
  {"password", 'p',
 
184
   "Password to use when connecting to server. If password is not given it's asked from the tty.",
 
185
   0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
186
  {"port", 'P', "Port number to use for connection or 0 for default to, in "
 
187
   "order of preference, my.cnf, $MYSQL_TCP_PORT, "
 
188
#if MYSQL_PORT_DEFAULT == 0
 
189
   "/etc/services, "
 
190
#endif
 
191
   "built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").",
 
192
   (uchar**) &opt_mysql_port,
 
193
   (uchar**) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0,
 
194
   0},
 
195
  {"protocol", OPT_MYSQL_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).",
 
196
   0, 0, 0, GET_STR,  REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
197
#ifdef HAVE_SMEM
 
198
  {"shared-memory-base-name", OPT_SHARED_MEMORY_BASE_NAME,
 
199
   "Base name of shared memory.", (uchar**) &shared_memory_base_name, (uchar**) &shared_memory_base_name,
 
200
   0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
201
#endif
 
202
  {"show-table-type", 't', "Show table type column.",
 
203
   (uchar**) &opt_table_type, (uchar**) &opt_table_type, 0, GET_BOOL,
 
204
   NO_ARG, 0, 0, 0, 0, 0, 0},
 
205
  {"socket", 'S', "Socket file to use for connection.",
 
206
   (uchar**) &opt_mysql_unix_port, (uchar**) &opt_mysql_unix_port, 0, GET_STR,
 
207
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
208
#ifndef DONT_ALLOW_USER_CHANGE
 
209
  {"user", 'u', "User for login if not current user.", (uchar**) &user,
 
210
   (uchar**) &user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
211
#endif
 
212
  {"verbose", 'v',
 
213
   "More verbose output; You can use this multiple times to get even more verbose output.",
 
214
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
215
  {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
 
216
   NO_ARG, 0, 0, 0, 0, 0, 0},
 
217
  {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
 
218
};
 
219
 
 
220
  
 
221
#include <help_start.h>
 
222
 
 
223
static void print_version(void)
 
224
{
 
225
  printf("%s  Ver %s Distrib %s, for %s (%s)\n",my_progname,SHOW_VERSION,
 
226
         MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
 
227
}
 
228
 
 
229
 
 
230
static void usage(void)
 
231
{
 
232
  print_version();
 
233
  puts("Copyright (C) 2000-2006 MySQL AB");
 
234
  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");
 
235
  puts("Shows the structure of a mysql database (databases,tables and columns)\n");
 
236
  printf("Usage: %s [OPTIONS] [database [table [column]]]\n",my_progname);
 
237
  puts("\n\
 
238
If last argument contains a shell or SQL wildcard (*,?,% or _) then only\n\
 
239
what\'s matched by the wildcard is shown.\n\
 
240
If no database is given then all matching databases are shown.\n\
 
241
If no table is given then all matching tables in database are shown\n\
 
242
If no column is given then all matching columns and columntypes in table\n\
 
243
are shown");
 
244
  print_defaults("my",load_default_groups);
 
245
  my_print_help(my_long_options);
 
246
  my_print_variables(my_long_options);
 
247
}
 
248
 
 
249
#include <help_end.h>
 
250
 
 
251
static my_bool
 
252
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
 
253
               char *argument)
 
254
{
 
255
  switch(optid) {
 
256
  case 'v':
 
257
    opt_verbose++;
 
258
    break;
 
259
  case 'p':
 
260
    if (argument)
 
261
    {
 
262
      char *start=argument;
 
263
      my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
 
264
      opt_password=my_strdup(argument,MYF(MY_FAE));
 
265
      while (*argument) *argument++= 'x';               /* Destroy argument */
 
266
      if (*start)
 
267
        start[1]=0;                             /* Cut length of argument */
 
268
      tty_password= 0;
 
269
    }
 
270
    else
 
271
      tty_password=1;
 
272
    break;
 
273
  case OPT_MYSQL_PROTOCOL:
 
274
    opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
 
275
                                    opt->name);
 
276
    break;
 
277
  case '#':
 
278
    DBUG_PUSH(argument ? argument : "d:t:o");
 
279
    debug_check_flag= 1;
 
280
    break;
 
281
  case 'V':
 
282
    print_version();
 
283
    exit(0);
 
284
    break;
 
285
  case '?':
 
286
  case 'I':                                     /* Info */
 
287
    usage();
 
288
    exit(0);
 
289
  }
 
290
  return 0;
 
291
}
 
292
 
 
293
 
 
294
static void
 
295
get_options(int *argc,char ***argv)
 
296
{
 
297
  int ho_error;
 
298
 
 
299
  if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
 
300
    exit(ho_error);
 
301
  
 
302
  if (tty_password)
 
303
    opt_password=get_tty_password(NullS);
 
304
  if (opt_count)
 
305
  {
 
306
    /*
 
307
      We need to set verbose to 2 as we need to change the output to include
 
308
      the number-of-rows column
 
309
    */
 
310
    opt_verbose= 2;
 
311
  }
 
312
  if (debug_info_flag)
 
313
    my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
 
314
  if (debug_check_flag)
 
315
    my_end_arg= MY_CHECK_ERROR;
 
316
  return;
 
317
}
 
318
 
 
319
 
 
320
static int
 
321
list_dbs(MYSQL *mysql,const char *wild)
 
322
{
 
323
  const char *header;
 
324
  uint length, counter = 0;
 
325
  ulong rowcount = 0L;
 
326
  char tables[NAME_LEN+1], rows[NAME_LEN+1];
 
327
  char query[255];
 
328
  MYSQL_FIELD *field;
 
329
  MYSQL_RES *result;
 
330
  MYSQL_ROW row= NULL, rrow;
 
331
 
 
332
  if (!(result=mysql_list_dbs(mysql,wild)))
 
333
  {
 
334
    fprintf(stderr,"%s: Cannot list databases: %s\n",my_progname,
 
335
            mysql_error(mysql));
 
336
    return 1;
 
337
  }
 
338
 
 
339
  /*
 
340
    If a wildcard was used, but there was only one row and it's name is an
 
341
    exact match, we'll assume they really wanted to see the contents of that
 
342
    database. This is because it is fairly common for database names to
 
343
    contain the underscore (_), like INFORMATION_SCHEMA.
 
344
   */
 
345
  if (wild && mysql_num_rows(result) == 1)
 
346
  {
 
347
    row= mysql_fetch_row(result);
 
348
    if (!my_strcasecmp(&my_charset_latin1, row[0], wild))
 
349
    {
 
350
      mysql_free_result(result);
 
351
      if (opt_status)
 
352
        return list_table_status(mysql, wild, NULL);
 
353
      else
 
354
        return list_tables(mysql, wild, NULL);
 
355
    }
 
356
  }
 
357
 
 
358
  if (wild)
 
359
    printf("Wildcard: %s\n",wild);
 
360
 
 
361
  header="Databases";
 
362
  length=(uint) strlen(header);
 
363
  field=mysql_fetch_field(result);
 
364
  if (length < field->max_length)
 
365
    length=field->max_length;
 
366
 
 
367
  if (!opt_verbose)
 
368
    print_header(header,length,NullS);
 
369
  else if (opt_verbose == 1)
 
370
    print_header(header,length,"Tables",6,NullS);
 
371
  else
 
372
    print_header(header,length,"Tables",6,"Total Rows",12,NullS);
 
373
 
 
374
  /* The first row may have already been read up above. */
 
375
  while (row || (row= mysql_fetch_row(result)))
 
376
  {
 
377
    counter++;
 
378
 
 
379
    if (opt_verbose)
 
380
    {
 
381
      if (!(mysql_select_db(mysql,row[0])))
 
382
      {
 
383
        MYSQL_RES *tresult = mysql_list_tables(mysql,(char*)NULL);
 
384
        if (mysql_affected_rows(mysql) > 0)
 
385
        {
 
386
          sprintf(tables,"%6lu",(ulong) mysql_affected_rows(mysql));
 
387
          rowcount = 0;
 
388
          if (opt_verbose > 1)
 
389
          {
 
390
            /* Print the count of tables and rows for each database */
 
391
            MYSQL_ROW trow;
 
392
            while ((trow = mysql_fetch_row(tresult)))
 
393
            {
 
394
              sprintf(query,"SELECT COUNT(*) FROM `%s`",trow[0]);
 
395
              if (!(mysql_query(mysql,query)))
 
396
              {
 
397
                MYSQL_RES *rresult;
 
398
                if ((rresult = mysql_store_result(mysql)))
 
399
                {
 
400
                  rrow = mysql_fetch_row(rresult);
 
401
                  rowcount += (ulong) strtoull(rrow[0], (char**) 0, 10);
 
402
                  mysql_free_result(rresult);
 
403
                }
 
404
              }
 
405
            }
 
406
            sprintf(rows,"%12lu",rowcount);
 
407
          }
 
408
        }
 
409
        else
 
410
        {
 
411
          sprintf(tables,"%6d",0);
 
412
          sprintf(rows,"%12d",0);
 
413
        }
 
414
        mysql_free_result(tresult);
 
415
      }
 
416
      else
 
417
      {
 
418
        strmov(tables,"N/A");
 
419
        strmov(rows,"N/A");
 
420
      }
 
421
    }
 
422
 
 
423
    if (!opt_verbose)
 
424
      print_row(row[0],length,0);
 
425
    else if (opt_verbose == 1)
 
426
      print_row(row[0],length,tables,6,NullS);
 
427
    else
 
428
      print_row(row[0],length,tables,6,rows,12,NullS);
 
429
 
 
430
    row= NULL;
 
431
  }
 
432
 
 
433
  print_trailer(length,
 
434
                (opt_verbose > 0 ? 6 : 0),
 
435
                (opt_verbose > 1 ? 12 :0),
 
436
                0);
 
437
 
 
438
  if (counter && opt_verbose)
 
439
    printf("%u row%s in set.\n",counter,(counter > 1) ? "s" : "");
 
440
  mysql_free_result(result);
 
441
  return 0;
 
442
}
 
443
 
 
444
 
 
445
static int
 
446
list_tables(MYSQL *mysql,const char *db,const char *table)
 
447
{
 
448
  const char *header;
 
449
  uint head_length, counter = 0;
 
450
  char query[255], rows[NAME_LEN], fields[16];
 
451
  MYSQL_FIELD *field;
 
452
  MYSQL_RES *result;
 
453
  MYSQL_ROW row, rrow;
 
454
 
 
455
  if (mysql_select_db(mysql,db))
 
456
  {
 
457
    fprintf(stderr,"%s: Cannot connect to db %s: %s\n",my_progname,db,
 
458
            mysql_error(mysql));
 
459
    return 1;
 
460
  }
 
461
  if (table)
 
462
  {
 
463
    /*
 
464
      We just hijack the 'rows' variable for a bit to store the escaped
 
465
      table name
 
466
    */
 
467
    mysql_real_escape_string(mysql, rows, table, (unsigned long)strlen(table));
 
468
    snprintf(query, sizeof(query), "show%s tables like '%s'",
 
469
             opt_table_type ? " full" : "", rows);
 
470
  }
 
471
  else
 
472
    snprintf(query, sizeof(query), "show%s tables",
 
473
             opt_table_type ? " full" : "");
 
474
  if (mysql_query(mysql, query) || !(result= mysql_store_result(mysql)))
 
475
  {
 
476
    fprintf(stderr,"%s: Cannot list tables in %s: %s\n",my_progname,db,
 
477
            mysql_error(mysql));
 
478
    exit(1);
 
479
  }
 
480
  printf("Database: %s",db);
 
481
  if (table)
 
482
    printf("  Wildcard: %s",table);
 
483
  putchar('\n');
 
484
 
 
485
  header="Tables";
 
486
  head_length=(uint) strlen(header);
 
487
  field=mysql_fetch_field(result);
 
488
  if (head_length < field->max_length)
 
489
    head_length=field->max_length;
 
490
 
 
491
  if (opt_table_type)
 
492
  {
 
493
    if (!opt_verbose)
 
494
      print_header(header,head_length,"table_type",10,NullS);
 
495
    else if (opt_verbose == 1)
 
496
      print_header(header,head_length,"table_type",10,"Columns",8,NullS);
 
497
    else
 
498
    {
 
499
      print_header(header,head_length,"table_type",10,"Columns",8,
 
500
                   "Total Rows",10,NullS);
 
501
    }
 
502
  }
 
503
  else
 
504
  {
 
505
    if (!opt_verbose)
 
506
      print_header(header,head_length,NullS);
 
507
    else if (opt_verbose == 1)
 
508
      print_header(header,head_length,"Columns",8,NullS);
 
509
    else
 
510
      print_header(header,head_length,"Columns",8, "Total Rows",10,NullS);
 
511
  }
 
512
 
 
513
  while ((row = mysql_fetch_row(result)))
 
514
  {
 
515
    counter++;
 
516
    if (opt_verbose > 0)
 
517
    {
 
518
      if (!(mysql_select_db(mysql,db)))
 
519
      {
 
520
        MYSQL_RES *rresult = mysql_list_fields(mysql,row[0],NULL);
 
521
        ulong rowcount=0L;
 
522
        if (!rresult)
 
523
        {
 
524
          strmov(fields,"N/A");
 
525
          strmov(rows,"N/A");
 
526
        }
 
527
        else
 
528
        {
 
529
          sprintf(fields,"%8u",(uint) mysql_num_fields(rresult));
 
530
          mysql_free_result(rresult);
 
531
 
 
532
          if (opt_verbose > 1)
 
533
          {
 
534
            /* Print the count of rows for each table */
 
535
            sprintf(query,"SELECT COUNT(*) FROM `%s`",row[0]);
 
536
            if (!(mysql_query(mysql,query)))
 
537
            {
 
538
              if ((rresult = mysql_store_result(mysql)))
 
539
              {
 
540
                rrow = mysql_fetch_row(rresult);
 
541
                rowcount += (unsigned long) strtoull(rrow[0], (char**) 0, 10);
 
542
                mysql_free_result(rresult);
 
543
              }
 
544
              sprintf(rows,"%10lu",rowcount);
 
545
            }
 
546
            else
 
547
              sprintf(rows,"%10d",0);
 
548
          }
 
549
        }
 
550
      }
 
551
      else
 
552
      {
 
553
        strmov(fields,"N/A");
 
554
        strmov(rows,"N/A");
 
555
      }
 
556
    }
 
557
    if (opt_table_type)
 
558
    {
 
559
      if (!opt_verbose)
 
560
        print_row(row[0],head_length,row[1],10,NullS);
 
561
      else if (opt_verbose == 1)
 
562
        print_row(row[0],head_length,row[1],10,fields,8,NullS);
 
563
      else
 
564
        print_row(row[0],head_length,row[1],10,fields,8,rows,10,NullS);
 
565
    }
 
566
    else
 
567
    {
 
568
      if (!opt_verbose)
 
569
        print_row(row[0],head_length,NullS);
 
570
      else if (opt_verbose == 1)
 
571
        print_row(row[0],head_length, fields,8, NullS);
 
572
      else
 
573
        print_row(row[0],head_length, fields,8, rows,10, NullS);
 
574
    }
 
575
  }
 
576
 
 
577
  print_trailer(head_length,
 
578
                (opt_table_type ? 10 : opt_verbose > 0 ? 8 : 0),
 
579
                (opt_table_type ? (opt_verbose > 0 ? 8 : 0) 
 
580
                 : (opt_verbose > 1 ? 10 :0)),
 
581
                !opt_table_type ? 0 : opt_verbose > 1 ? 10 :0,
 
582
                0);
 
583
 
 
584
  if (counter && opt_verbose)
 
585
    printf("%u row%s in set.\n\n",counter,(counter > 1) ? "s" : "");
 
586
 
 
587
  mysql_free_result(result);
 
588
  return 0;
 
589
}
 
590
 
 
591
 
 
592
static int
 
593
list_table_status(MYSQL *mysql,const char *db,const char *wild)
 
594
{
 
595
  char query[1024],*end;
 
596
  MYSQL_RES *result;
 
597
  MYSQL_ROW row;
 
598
 
 
599
  end=strxmov(query,"show table status from `",db,"`",NullS);
 
600
  if (wild && wild[0])
 
601
    strxmov(end," like '",wild,"'",NullS);
 
602
  if (mysql_query(mysql,query) || !(result=mysql_store_result(mysql)))
 
603
  {
 
604
    fprintf(stderr,"%s: Cannot get status for db: %s, table: %s: %s\n",
 
605
            my_progname,db,wild ? wild : "",mysql_error(mysql));
 
606
    if (mysql_errno(mysql) == ER_PARSE_ERROR)
 
607
      fprintf(stderr,"This error probably means that your MySQL server doesn't support the\n\'show table status' command.\n");
 
608
    return 1;
 
609
  }
 
610
 
 
611
  printf("Database: %s",db);
 
612
  if (wild)
 
613
    printf("  Wildcard: %s",wild);
 
614
  putchar('\n');
 
615
 
 
616
  print_res_header(result);
 
617
  while ((row=mysql_fetch_row(result)))
 
618
    print_res_row(result,row);
 
619
  print_res_top(result);
 
620
  mysql_free_result(result);
 
621
  return 0;
 
622
}
 
623
 
 
624
/*
 
625
  list fields uses field interface as an example of how to parse
 
626
  a MYSQL FIELD
 
627
*/
 
628
 
 
629
static int
 
630
list_fields(MYSQL *mysql,const char *db,const char *table,
 
631
            const char *wild)
 
632
{
 
633
  char query[1024],*end;
 
634
  MYSQL_RES *result;
 
635
  MYSQL_ROW row;
 
636
  ulong rows= 0;
 
637
 
 
638
  if (mysql_select_db(mysql,db))
 
639
  {
 
640
    fprintf(stderr,"%s: Cannot connect to db: %s: %s\n",my_progname,db,
 
641
            mysql_error(mysql));
 
642
    return 1;
 
643
  }
 
644
 
 
645
  if (opt_count)
 
646
  {
 
647
    sprintf(query,"select count(*) from `%s`", table);
 
648
    if (mysql_query(mysql,query) || !(result=mysql_store_result(mysql)))
 
649
    {
 
650
      fprintf(stderr,"%s: Cannot get record count for db: %s, table: %s: %s\n",
 
651
              my_progname,db,table,mysql_error(mysql));
 
652
      return 1;
 
653
    }
 
654
    row= mysql_fetch_row(result);
 
655
    rows= (ulong) strtoull(row[0], (char**) 0, 10);
 
656
    mysql_free_result(result);
 
657
  }
 
658
 
 
659
  end=strmov(strmov(strmov(query,"show /*!32332 FULL */ columns from `"),table),"`");
 
660
  if (wild && wild[0])
 
661
    strxmov(end," like '",wild,"'",NullS);
 
662
  if (mysql_query(mysql,query) || !(result=mysql_store_result(mysql)))
 
663
  {
 
664
    fprintf(stderr,"%s: Cannot list columns in db: %s, table: %s: %s\n",
 
665
            my_progname,db,table,mysql_error(mysql));
 
666
    return 1;
 
667
  }
 
668
 
 
669
  printf("Database: %s  Table: %s", db, table);
 
670
  if (opt_count)
 
671
    printf("  Rows: %lu", rows);
 
672
  if (wild && wild[0])
 
673
    printf("  Wildcard: %s",wild);
 
674
  putchar('\n');
 
675
 
 
676
  print_res_header(result);
 
677
  while ((row=mysql_fetch_row(result)))
 
678
    print_res_row(result,row);
 
679
  print_res_top(result);
 
680
  if (opt_show_keys)
 
681
  {
 
682
    end=strmov(strmov(strmov(query,"show keys from `"),table),"`");
 
683
    if (mysql_query(mysql,query) || !(result=mysql_store_result(mysql)))
 
684
    {
 
685
      fprintf(stderr,"%s: Cannot list keys in db: %s, table: %s: %s\n",
 
686
              my_progname,db,table,mysql_error(mysql));
 
687
      return 1;
 
688
    }
 
689
    if (mysql_num_rows(result))
 
690
    {
 
691
      print_res_header(result);
 
692
      while ((row=mysql_fetch_row(result)))
 
693
        print_res_row(result,row);
 
694
      print_res_top(result);
 
695
    }
 
696
    else
 
697
      puts("Table has no keys");
 
698
  }
 
699
  mysql_free_result(result);
 
700
  return 0;
 
701
}
 
702
 
 
703
 
 
704
/*****************************************************************************
 
705
 General functions to print a nice ascii-table from data
 
706
*****************************************************************************/
 
707
 
 
708
static void
 
709
print_header(const char *header,uint head_length,...)
 
710
{
 
711
  va_list args;
 
712
  uint length,i,str_length,pre_space;
 
713
  const char *field;
 
714
 
 
715
  va_start(args,head_length);
 
716
  putchar('+');
 
717
  field=header; length=head_length;
 
718
  for (;;)
 
719
  {
 
720
    for (i=0 ; i < length+2 ; i++)
 
721
      putchar('-');
 
722
    putchar('+');
 
723
    if (!(field=va_arg(args,char *)))
 
724
      break;
 
725
    length=va_arg(args,uint);
 
726
  }
 
727
  va_end(args);
 
728
  putchar('\n');
 
729
 
 
730
  va_start(args,head_length);
 
731
  field=header; length=head_length;
 
732
  putchar('|');
 
733
  for (;;)
 
734
  {
 
735
    str_length=(uint) strlen(field);
 
736
    if (str_length > length)
 
737
      str_length=length+1;
 
738
    pre_space=(uint) (((int) length-(int) str_length)/2)+1;
 
739
    for (i=0 ; i < pre_space ; i++)
 
740
      putchar(' ');
 
741
    for (i = 0 ; i < str_length ; i++)
 
742
      putchar(field[i]);
 
743
    length=length+2-str_length-pre_space;
 
744
    for (i=0 ; i < length ; i++)
 
745
      putchar(' ');
 
746
    putchar('|');
 
747
    if (!(field=va_arg(args,char *)))
 
748
      break;
 
749
    length=va_arg(args,uint);
 
750
  }
 
751
  va_end(args);
 
752
  putchar('\n');
 
753
 
 
754
  va_start(args,head_length);
 
755
  putchar('+');
 
756
  field=header; length=head_length;
 
757
  for (;;)
 
758
  {
 
759
    for (i=0 ; i < length+2 ; i++)
 
760
      putchar('-');
 
761
    putchar('+');
 
762
    if (!(field=va_arg(args,char *)))
 
763
      break;
 
764
    length=va_arg(args,uint);
 
765
  }
 
766
  va_end(args);
 
767
  putchar('\n');
 
768
}
 
769
 
 
770
 
 
771
static void
 
772
print_row(const char *header,uint head_length,...)
 
773
{
 
774
  va_list args;
 
775
  const char *field;
 
776
  uint i,length,field_length;
 
777
 
 
778
  va_start(args,head_length);
 
779
  field=header; length=head_length;
 
780
  for (;;)
 
781
  {
 
782
    putchar('|');
 
783
    putchar(' ');
 
784
    fputs(field,stdout);
 
785
    field_length=(uint) strlen(field);
 
786
    for (i=field_length ; i <= length ; i++)
 
787
      putchar(' ');
 
788
    if (!(field=va_arg(args,char *)))
 
789
      break;
 
790
    length=va_arg(args,uint);
 
791
  }
 
792
  va_end(args);
 
793
  putchar('|');
 
794
  putchar('\n');
 
795
}
 
796
 
 
797
 
 
798
static void
 
799
print_trailer(uint head_length,...)
 
800
{
 
801
  va_list args;
 
802
  uint length,i;
 
803
 
 
804
  va_start(args,head_length);
 
805
  length=head_length;
 
806
  putchar('+');
 
807
  for (;;)
 
808
  {
 
809
    for (i=0 ; i < length+2 ; i++)
 
810
      putchar('-');
 
811
    putchar('+');
 
812
    if (!(length=va_arg(args,uint)))
 
813
      break;
 
814
  }
 
815
  va_end(args);
 
816
  putchar('\n');
 
817
}
 
818
 
 
819
 
 
820
static void print_res_header(MYSQL_RES *result)
 
821
{
 
822
  MYSQL_FIELD *field;
 
823
 
 
824
  print_res_top(result);
 
825
  mysql_field_seek(result,0);
 
826
  putchar('|');
 
827
  while ((field = mysql_fetch_field(result)))
 
828
  {
 
829
    printf(" %-*s|",(int) field->max_length+1,field->name);
 
830
  }
 
831
  putchar('\n');
 
832
  print_res_top(result);
 
833
}
 
834
 
 
835
 
 
836
static void print_res_top(MYSQL_RES *result)
 
837
{
 
838
  uint i,length;
 
839
  MYSQL_FIELD *field;
 
840
 
 
841
  putchar('+');
 
842
  mysql_field_seek(result,0);
 
843
  while((field = mysql_fetch_field(result)))
 
844
  {
 
845
    if ((length=(uint) strlen(field->name)) > field->max_length)
 
846
      field->max_length=length;
 
847
    else
 
848
      length=field->max_length;
 
849
    for (i=length+2 ; i--> 0 ; )
 
850
      putchar('-');
 
851
    putchar('+');
 
852
  }
 
853
  putchar('\n');
 
854
}
 
855
 
 
856
 
 
857
static void print_res_row(MYSQL_RES *result,MYSQL_ROW cur)
 
858
{
 
859
  uint i,length;
 
860
  MYSQL_FIELD *field;
 
861
  putchar('|');
 
862
  mysql_field_seek(result,0);
 
863
  for (i=0 ; i < mysql_num_fields(result); i++)
 
864
  {
 
865
    field = mysql_fetch_field(result);
 
866
    length=field->max_length;
 
867
    printf(" %-*s|",length+1,cur[i] ? (char*) cur[i] : "");
 
868
  }
 
869
  putchar('\n');
 
870
}