~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/mysqlshow.c

  • Committer: brian
  • Date: 2008-07-08 21:36:40 UTC
  • Revision ID: brian@localhost.localdomain-20080708213640-qqw7s2memqeg5282
Removed mysqlshow

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