9
#include <mysql_version.h>
11
#define BUFFER_LEN 1024
12
#define ARCHIVE_ROW_HEADER_SIZE 4
14
#define SHOW_VERSION "0.1"
16
static void get_options(int *argc,char * * *argv);
17
static void print_version(void);
18
static void usage(void);
19
static const char *opt_tmpdir;
20
static const char *new_auto_increment;
21
unsigned long long new_auto_increment_value;
22
static const char *load_default_groups[]= { "archive_reader", 0 };
23
static char **default_argv;
24
int opt_check, opt_force, opt_quiet, opt_backup= 0, opt_extract_frm;
25
int opt_autoincrement;
27
int main(int argc, char *argv[])
30
azio_stream reader_handle;
34
get_options(&argc, &argv);
38
printf("No file specified. \n");
42
if (!(ret= azopen(&reader_handle, argv[0], O_RDONLY|O_BINARY, AZ_METHOD_BLOCK)))
44
printf("Could not open Archive file\n");
48
if (opt_autoincrement)
50
azio_stream writer_handle;
52
if (new_auto_increment_value)
54
if (reader_handle.auto_increment >= new_auto_increment_value)
56
printf("Value is lower then current value\n");
62
new_auto_increment_value= reader_handle.auto_increment + 1;
65
if (!(ret= azopen(&writer_handle, argv[0], O_CREAT|O_RDWR|O_BINARY,
68
printf("Could not open file for update: %s\n", argv[0]);
72
writer_handle.auto_increment= new_auto_increment_value;
74
azclose(&writer_handle);
75
azflush(&reader_handle, Z_SYNC_FLUSH);
78
printf("Version %u\n", reader_handle.version);
79
if (reader_handle.version > 2)
81
printf("\tMinor version %u\n", reader_handle.minor_version);
82
printf("\tStart position %llu\n", (unsigned long long)reader_handle.start);
83
printf("\tBlock size %u\n", reader_handle.block_size);
84
printf("\tRows %llu\n", reader_handle.rows);
85
printf("\tAutoincrement %llu\n", reader_handle.auto_increment);
86
printf("\tCheck Point %llu\n", reader_handle.check_point);
87
printf("\tForced Flushes %llu\n", reader_handle.forced_flushes);
88
printf("\tLongest Row %u\n", reader_handle.longest_row);
89
printf("\tShortest Row %u\n", reader_handle.shortest_row);
90
printf("\tState %s\n", ( reader_handle.dirty ? "dirty" : "clean"));
91
printf("\tFRM stored at %u\n", reader_handle.frm_start_pos);
92
printf("\tComment stored at %u\n", reader_handle.comment_start_pos);
93
printf("\tData starts at %u\n", (unsigned int)reader_handle.start);
94
if (reader_handle.frm_start_pos)
95
printf("\tFRM length %u\n", reader_handle.frm_length);
96
if (reader_handle.comment_start_pos)
99
(char *) malloc(sizeof(char) * reader_handle.comment_length);
100
azread_comment(&reader_handle, comment);
101
printf("\tComment length %u\n\t\t%.*s\n", reader_handle.comment_length,
102
reader_handle.comment_length, comment);
117
unsigned long long row_count= 0;
119
while ((read= azread_row(&reader_handle, &error)))
121
if (error == Z_STREAM_ERROR || &error)
123
printf("Table is damaged\n");
129
if (read > reader_handle.longest_row)
131
printf("Table is damaged, row %llu is invalid\n", row_count);
136
printf("Found %llu rows\n", row_count);
143
unsigned long long row_count= 0;
146
azio_stream writer_handle;
148
buffer= (char *)malloc(reader_handle.longest_row);
151
printf("Could not allocate memory for row %llu\n", row_count);
156
if (!(ret= azopen(&writer_handle, argv[1], O_CREAT|O_RDWR|O_BINARY,
159
printf("Could not open file for backup: %s\n", argv[1]);
163
writer_handle.auto_increment= reader_handle.auto_increment;
164
if (reader_handle.frm_length)
167
ptr= (char *)my_malloc(sizeof(char) * reader_handle.frm_length, MYF(0));
168
azread_frm(&reader_handle, ptr);
169
azwrite_frm(&writer_handle, ptr, reader_handle.frm_length);
170
my_free(ptr, MYF(0));
173
if (reader_handle.comment_length)
176
ptr= (char *)my_malloc(sizeof(char) * reader_handle.comment_length, MYF(0));
177
azread_comment(&reader_handle, ptr);
178
azwrite_comment(&writer_handle, ptr, reader_handle.comment_length);
179
my_free(ptr, MYF(0));
182
while ((read= azread_row(&reader_handle, &error)))
184
if (error == Z_STREAM_ERROR || error)
186
printf("Table is damaged\n");
190
/* If we read nothing we are at the end of the file */
196
azwrite_row(&writer_handle, reader_handle.row_ptr, read);
198
if (reader_handle.rows == writer_handle.rows)
204
azclose(&writer_handle);
211
frm_file= my_open(argv[1], O_CREAT|O_RDWR|O_BINARY, MYF(0));
212
ptr= (char *)my_malloc(sizeof(char) * reader_handle.frm_length, MYF(0));
213
azread_frm(&reader_handle, ptr);
214
my_write(frm_file, (uchar*) ptr, reader_handle.frm_length, MYF(0));
215
my_close(frm_file, MYF(0));
216
my_free(ptr, MYF(0));
221
azclose(&reader_handle);
228
get_one_option(int optid,
229
const struct my_option *opt __attribute__((unused)),
244
printf("Not implemented yet\n");
248
printf("Not implemented yet\n");
254
printf("Not implemented yet\n");
257
opt_autoincrement= 1;
259
new_auto_increment_value= strtoull(argument, NULL, 0);
261
new_auto_increment_value= 0;
267
if (argument == disabled_my_option)
273
DBUG_PUSH(argument ? argument : "d:t:o,/tmp/archive_reader.trace");
280
static struct my_option my_long_options[] =
283
"Make a backup of an archive table.",
284
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
285
{"check", 'c', "Check table for errors.",
286
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
289
"Output debug log. Often this is 'd:t:o,filename'.",
290
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
293
"Extract the frm file.",
294
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
296
"Restart with -r if there are any errors in the table.",
297
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
299
"Display this help and exit.",
300
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
301
{"quick", 'q', "Faster repair by not modifying the data file.",
302
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
303
{"repair", 'r', "Repair a damaged Archive version 3 or above file.",
304
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
305
{"set-auto-increment", 'A',
306
"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.",
307
(uchar**) &new_auto_increment,
308
(uchar**) &new_auto_increment,
309
0, GET_ULL, OPT_ARG, 0, 0, 0, 0, 0, 0},
311
"Only print errors. One can use two -s to make archive_reader very silent.",
312
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
314
"Path for temporary files.",
315
(uchar**) &opt_tmpdir,
316
0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
318
"Print version and exit.",
319
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
320
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
323
static void usage(void)
326
puts("Copyright (C) 2007 MySQL AB");
327
puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\
328
\nand you are welcome to modify and redistribute it under the GPL \
330
puts("Read and modify Archive files directly\n");
331
printf("Usage: %s [OPTIONS] file_to_be_looked_at [file_for_backup]\n", my_progname);
332
print_defaults("my", load_default_groups);
333
my_print_help(my_long_options);
336
static void print_version(void)
338
printf("%s Ver %s Distrib %s, for %s (%s)\n", my_progname, SHOW_VERSION,
339
MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE);
342
static void get_options(int *argc, char ***argv)
344
load_defaults("my", load_default_groups, argc, argv);
347
handle_options(argc, argv, my_long_options, get_one_option);