~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/mysqlshow.c

  • Committer: brian
  • Date: 2008-07-03 12:39:14 UTC
  • Revision ID: brian@localhost.localdomain-20080703123914-lry82qf74f6cbyzs
Disabling myisam tools until incomming link patch from Monty

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