~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/archive/archive_reader.cc

  • Committer: Monty Taylor
  • Date: 2011-02-13 17:26:39 UTC
  • mfrom: (2157.2.2 give-in-to-pkg-config)
  • mto: This revision was merged to the branch mainline in revision 2166.
  • Revision ID: mordred@inaugust.com-20110213172639-nhy7i72sfhoq13ms
Merged in pkg-config fixes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
 
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
 
3
 *
 
4
 *  Copyright (C) 2006 MySQL AB
 
5
 *  Copyright (C) 2009 Sun Microsystems, Inc.
 
6
 *
 
7
 *  This program is free software; you can redistribute it and/or modify
 
8
 *  it under the terms of the GNU General Public License as published by
 
9
 *  the Free Software Foundation; version 2 of the License.
 
10
 *
 
11
 *  This program is distributed in the hope that it will be useful,
 
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 *  GNU General Public License for more details.
 
15
 *
 
16
 *  You should have received a copy of the GNU General Public License
 
17
 *  along with this program; if not, write to the Free Software
 
18
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
19
 */
 
20
 
 
21
#include "config.h"
 
22
#include <iostream>
 
23
#include <string>
 
24
#include <fstream>
 
25
#include <drizzled/configmake.h>
 
26
using namespace std;
 
27
#include <boost/program_options.hpp>
 
28
#include <boost/scoped_ptr.hpp>
 
29
namespace po= boost::program_options;
 
30
#include "azio.h"
 
31
#include <string.h>
 
32
#include <assert.h>
 
33
#include <stdio.h>
 
34
#include <stdarg.h>
 
35
#include <fcntl.h>
 
36
#include <memory>
 
37
#include "drizzled/charset_info.h"
 
38
#include "drizzled/internal/m_string.h"
 
39
 
 
40
#define SHOW_VERSION "0.1"
 
41
 
 
42
using namespace drizzled;
 
43
 
 
44
string opt_tmpdir;
 
45
uint64_t new_auto_increment_value;
 
46
bool opt_check, 
 
47
  opt_force,
 
48
  opt_backup, 
 
49
  opt_extract_table_message, 
 
50
  opt_silent,
 
51
  opt_quiet,
 
52
  opt_quick,
 
53
  opt_autoincrement;
 
54
 
 
55
int main(int argc, char *argv[])
 
56
{
 
57
try
 
58
{
 
59
  po::options_description commandline_options("Options used only in command line");
 
60
  commandline_options.add_options()
 
61
  ("force,f",po::value<bool>(&opt_force)->default_value(false)->zero_tokens(),
 
62
  "Restart with -r if there are any errors in the table")
 
63
  ("help,?","Display this help and exit")
 
64
  ("version,V","Print version and exit")
 
65
  ("no-defaults", po::value<bool>()->default_value(false)->zero_tokens(),
 
66
  "Configuration file defaults are not used if no-defaults is set")
 
67
  ;
 
68
 
 
69
  po::options_description archive_reader_options("Options specific to the archive reader");
 
70
  archive_reader_options.add_options()
 
71
  ("tmpdir,t",po::value<string>(&opt_tmpdir)->default_value(""),
 
72
  "Path for temporary files.") 
 
73
  ("set-auto-increment,A",po::value<uint64_t>(&new_auto_increment_value)->default_value(0),
 
74
  "Force auto_increment to start at this or higher value. If no value is given, then sets the next auto_increment value to the highest used value for the auto key + 1.")
 
75
  ("silent,s",po::value<bool>(&opt_silent)->default_value(false)->zero_tokens(),
 
76
  "Only print errors. One can use two -s to make archive_reader very silent.")
 
77
  ("quick,q",po::value<bool>(&opt_quick)->default_value(false)->zero_tokens(),
 
78
  "Faster repair but not modifying the data")
 
79
  ("repair,r",po::value<bool>(&opt_quick)->default_value(false)->zero_tokens(),
 
80
  "Repair a damaged Archive version 3 or above file.")
 
81
  ("back-up,b",po::value<bool>(&opt_backup)->default_value(false)->zero_tokens(),
 
82
  "Make a backup of an archive table.")
 
83
  ("check,c",po::value<bool>(&opt_check)->default_value(false)->zero_tokens(),
 
84
  "Check table for errors")
 
85
  ("extract-table-message,e",po::value<bool>(&opt_extract_table_message)->default_value(false)->zero_tokens(),
 
86
  "Extract the table protobuf message.")
 
87
  ;
 
88
 
 
89
  unsigned int ret;
 
90
  boost::scoped_ptr<azio_stream> reader_handle_ap(new azio_stream);
 
91
  azio_stream &reader_handle= *reader_handle_ap.get();
 
92
 
 
93
  std::string system_config_dir_archive_reader(SYSCONFDIR); 
 
94
  system_config_dir_archive_reader.append("/drizzle/archive_reader.cnf");
 
95
 
 
96
  std::string user_config_dir((getenv("XDG_CONFIG_HOME")? getenv("XDG_CONFIG_HOME"):"~/.config"));
 
97
 
 
98
  if (user_config_dir.compare(0, 2, "~/") == 0)
 
99
  {
 
100
    char *homedir;
 
101
    homedir= getenv("HOME");
 
102
    if (homedir != NULL)
 
103
      user_config_dir.replace(0, 1, homedir);
 
104
  }
 
105
  
 
106
  po::options_description long_options("Allowed Options");
 
107
  long_options.add(commandline_options).add(archive_reader_options);
 
108
 
 
109
  po::variables_map vm;
 
110
  po::store(po::parse_command_line(argc,argv,long_options),vm);
 
111
 
 
112
  if (! vm["no-defaults"].as<bool>())
 
113
  {
 
114
    std::string user_config_dir_archive_reader(user_config_dir);
 
115
    user_config_dir_archive_reader.append("/drizzle/archive_reader.cnf");
 
116
  
 
117
    ifstream user_archive_reader_ifs(user_config_dir_archive_reader.c_str());
 
118
    po::store(parse_config_file(user_archive_reader_ifs, archive_reader_options), vm);
 
119
 
 
120
    ifstream system_archive_reader_ifs(system_config_dir_archive_reader.c_str());
 
121
    store(parse_config_file(system_archive_reader_ifs, archive_reader_options), vm);
 
122
 
 
123
  }
 
124
  po::notify(vm);
 
125
 
 
126
  if (vm.count("force") || vm.count("quiet") || vm.count("tmpdir"))
 
127
    cout << "Not implemented yet";
 
128
 
 
129
  if (vm.count("version"))
 
130
  {
 
131
    printf("%s  Ver %s, for %s-%s (%s)\n", internal::my_progname, SHOW_VERSION,
 
132
        HOST_VENDOR, HOST_OS, HOST_CPU);
 
133
    exit(0);
 
134
  }
 
135
  
 
136
  if (vm.count("set-auto-increment"))
 
137
  {
 
138
    opt_autoincrement= true;
 
139
  }
 
140
 
 
141
  if (vm.count("help") || argc == 0)
 
142
  {
 
143
    printf("%s  Ver %s, for %s-%s (%s)\n", internal::my_progname, SHOW_VERSION,
 
144
        HOST_VENDOR, HOST_OS, HOST_CPU);
 
145
    puts("This software comes with ABSOLUTELY NO WARRANTY. This is free "
 
146
         "software,\n"
 
147
         "and you are welcome to modify and redistribute it under the GPL "
 
148
         "license\n");
 
149
    puts("Read and modify Archive files directly\n");
 
150
    printf("Usage: %s [OPTIONS] file_to_be_looked_at [file_for_backup]\n", internal::my_progname);
 
151
    cout << long_options << endl;    
 
152
    exit(0); 
 
153
  }
 
154
  
 
155
  if (argc < 1)
 
156
  {
 
157
    printf("No file specified. \n");
 
158
    return -1;
 
159
  }
 
160
 
 
161
  if (!(ret= azopen(&reader_handle, argv[0], O_RDONLY, AZ_METHOD_BLOCK)))
 
162
  {
 
163
    printf("Could not open Archive file\n");
 
164
    return -1;
 
165
  }
 
166
 
 
167
  if (opt_autoincrement)
 
168
  {
 
169
    boost::scoped_ptr<azio_stream> writer_handle_ap(new azio_stream);
 
170
    azio_stream &writer_handle= *writer_handle_ap.get();
 
171
 
 
172
    if (new_auto_increment_value)
 
173
    {
 
174
      if (reader_handle.auto_increment >= new_auto_increment_value)
 
175
      {
 
176
        printf("Value is lower then current value\n");
 
177
        goto end;
 
178
      }
 
179
    }
 
180
    else
 
181
    {
 
182
      new_auto_increment_value= reader_handle.auto_increment + 1;
 
183
    }
 
184
 
 
185
    if (!(ret= azopen(&writer_handle, argv[0], O_CREAT|O_RDWR,
 
186
                      AZ_METHOD_BLOCK)))
 
187
    {
 
188
      printf("Could not open file for update: %s\n", argv[0]);
 
189
      goto end;
 
190
    }
 
191
 
 
192
    writer_handle.auto_increment= new_auto_increment_value;
 
193
 
 
194
    azclose(&writer_handle);
 
195
    azflush(&reader_handle, Z_SYNC_FLUSH);
 
196
  }
 
197
 
 
198
  printf("Version %u\n", reader_handle.version);
 
199
  if (reader_handle.version > 2)
 
200
  {
 
201
    printf("\tMinor version %u\n", reader_handle.minor_version);
 
202
    printf("\tStart position %"PRIu64"\n", (uint64_t)reader_handle.start);
 
203
    printf("\tBlock size %u\n", reader_handle.block_size);
 
204
    printf("\tRows %"PRIu64"\n", reader_handle.rows);
 
205
    printf("\tAutoincrement %"PRIu64"\n", reader_handle.auto_increment);
 
206
    printf("\tCheck Point %"PRIu64"\n", reader_handle.check_point);
 
207
    printf("\tForced Flushes %"PRIu64"\n", reader_handle.forced_flushes);
 
208
    printf("\tLongest Row %u\n", reader_handle.longest_row);
 
209
    printf("\tShortest Row %u\n", reader_handle.shortest_row);
 
210
    printf("\tState %s\n", ( reader_handle.dirty ? "dirty" : "clean"));
 
211
    printf("\tTable protobuf message stored at %u\n",
 
212
           reader_handle.frm_start_pos);
 
213
    printf("\tComment stored at %u\n", reader_handle.comment_start_pos);
 
214
    printf("\tData starts at %u\n", (unsigned int)reader_handle.start);
 
215
    if (reader_handle.frm_start_pos)
 
216
      printf("\tTable proto message length %u\n", reader_handle.frm_length);
 
217
    if (reader_handle.comment_start_pos)
 
218
    {
 
219
      char *comment =
 
220
        (char *) malloc(sizeof(char) * reader_handle.comment_length);
 
221
      azread_comment(&reader_handle, comment);
 
222
      printf("\tComment length %u\n\t\t%.*s\n", reader_handle.comment_length,
 
223
             reader_handle.comment_length, comment);
 
224
      free(comment);
 
225
    }
 
226
  }
 
227
  else
 
228
  {
 
229
    goto end;
 
230
  }
 
231
 
 
232
  printf("\n");
 
233
 
 
234
  if (opt_check)
 
235
  {
 
236
    int error;
 
237
    unsigned int row_read;
 
238
    uint64_t row_count= 0;
 
239
 
 
240
    while ((row_read= azread_row(&reader_handle, &error)))
 
241
    {
 
242
      if (error == Z_STREAM_ERROR)
 
243
      {
 
244
        printf("Table is damaged\n");
 
245
        goto end;
 
246
      }
 
247
 
 
248
      row_count++;
 
249
 
 
250
      if (row_read > reader_handle.longest_row)
 
251
      {
 
252
        printf("Table is damaged, row %"PRIu64" is invalid\n", row_count);
 
253
        goto end;
 
254
      }
 
255
    }
 
256
 
 
257
    printf("Found %"PRIu64" rows\n", row_count);
 
258
  }
 
259
 
 
260
  if (opt_backup)
 
261
  {
 
262
    int error;
 
263
    unsigned int row_read;
 
264
    uint64_t row_count= 0;
 
265
    char *buffer;
 
266
 
 
267
    boost::scoped_ptr<azio_stream> writer_handle_ap(new azio_stream);
 
268
    azio_stream &writer_handle= *writer_handle_ap.get();
 
269
 
 
270
    buffer= (char *)malloc(reader_handle.longest_row);
 
271
    if (buffer == NULL)
 
272
    {
 
273
      printf("Could not allocate memory for row %"PRIu64"\n", row_count);
 
274
      goto end;
 
275
    }
 
276
 
 
277
 
 
278
    if (!(ret= azopen(&writer_handle, argv[1], O_CREAT|O_RDWR,
 
279
                      AZ_METHOD_BLOCK)))
 
280
    {
 
281
      printf("Could not open file for backup: %s\n", argv[1]);
 
282
      goto end;
 
283
    }
 
284
 
 
285
    writer_handle.auto_increment= reader_handle.auto_increment;
 
286
    if (reader_handle.frm_length)
 
287
    {
 
288
      char *ptr;
 
289
      ptr= (char *)malloc(sizeof(char) * reader_handle.frm_length);
 
290
      if (ptr == NULL)
 
291
      {
 
292
        printf("Could not allocate enough memory\n");
 
293
        goto end;
 
294
      }
 
295
      azread_frm(&reader_handle, ptr);
 
296
      azwrite_frm(&writer_handle, ptr, reader_handle.frm_length);
 
297
      free(ptr);
 
298
    }
 
299
 
 
300
    if (reader_handle.comment_length)
 
301
    {
 
302
      char *ptr;
 
303
      ptr= (char *)malloc(sizeof(char) * reader_handle.comment_length);
 
304
      azread_comment(&reader_handle, ptr);
 
305
      azwrite_comment(&writer_handle, ptr, reader_handle.comment_length);
 
306
      free(ptr);
 
307
    }
 
308
 
 
309
    while ((row_read= azread_row(&reader_handle, &error)))
 
310
    {
 
311
      if (error == Z_STREAM_ERROR || error)
 
312
      {
 
313
        printf("Table is damaged\n");
 
314
        goto end;
 
315
      }
 
316
 
 
317
      /* If we read nothing we are at the end of the file */
 
318
      if (row_read == 0)
 
319
        break;
 
320
 
 
321
      row_count++;
 
322
 
 
323
      azwrite_row(&writer_handle, reader_handle.row_ptr, row_read);
 
324
 
 
325
      if (reader_handle.rows == writer_handle.rows)
 
326
        break;
 
327
    }
 
328
 
 
329
    free(buffer);
 
330
 
 
331
    azclose(&writer_handle);
 
332
  }
 
333
 
 
334
  if (opt_extract_table_message)
 
335
  {
 
336
    int frm_file;
 
337
    char *ptr;
 
338
    frm_file= internal::my_open(argv[1], O_CREAT|O_RDWR, MYF(0));
 
339
    ptr= (char *)malloc(sizeof(char) * reader_handle.frm_length);
 
340
    if (ptr == NULL)
 
341
    {
 
342
      printf("Could not allocate enough memory\n");
 
343
      goto end;
 
344
    }
 
345
    azread_frm(&reader_handle, ptr);
 
346
    internal::my_write(frm_file, (unsigned char*) ptr, reader_handle.frm_length, MYF(0));
 
347
    internal::my_close(frm_file, MYF(0));
 
348
    free(ptr);
 
349
  }
 
350
 
 
351
end:
 
352
  printf("\n");
 
353
  azclose(&reader_handle);
 
354
 
 
355
  internal::my_end();
 
356
 
 
357
}
 
358
  catch(exception &e)
 
359
  {
 
360
    cerr<<"Error"<<e.what()<<endl;
 
361
  }
 
362
  return 0;
 
363
}
 
364