~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/archive/ha_archive.cc

  • Committer: Toru Maesaka
  • Date: 2008-07-17 05:59:20 UTC
  • mto: (202.1.1 toru)
  • mto: This revision was merged to the branch mainline in revision 204.
  • Revision ID: dev@torum.net-20080717055920-10okif50x6nh7b1d
forgot to bzr-add new files in the previous push

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
#pragma implementation        // gcc: Class implementation
18
18
#endif
19
19
 
20
 
#include <drizzled/common_includes.h>
21
 
#include <storage/myisam/myisam.h>
 
20
#include "mysql_priv.h"
 
21
#include <myisam.h>
22
22
 
23
23
#include "ha_archive.h"
 
24
#include <my_dir.h>
 
25
 
 
26
#include <mysql/plugin.h>
24
27
 
25
28
/*
26
29
  First, if you want to understand storage engines you should look at 
101
104
#define ARM ".ARM"               // Meta file (deprecated)
102
105
 
103
106
/*
104
 
  unsigned char + unsigned char
 
107
  uchar + uchar
105
108
*/
106
109
#define DATA_BUFFER_SIZE 2       // Size of the data used in the data file
107
110
#define ARCHIVE_CHECK_HEADER 254 // The number we use to determine corruption
112
115
                                       MEM_ROOT *mem_root);
113
116
int archive_discover(handlerton *hton, THD* thd, const char *db, 
114
117
                     const char *name,
115
 
                     unsigned char **frmblob, 
 
118
                     uchar **frmblob, 
116
119
                     size_t *frmlen);
117
120
 
118
 
static bool archive_use_aio= false;
 
121
static my_bool archive_use_aio= false;
119
122
 
120
123
/*
121
124
  Number of rows that will force a bulk insert.
137
140
/*
138
141
  Used for hash table that tracks open tables.
139
142
*/
140
 
static unsigned char* archive_get_key(ARCHIVE_SHARE *share, size_t *length,
141
 
                             bool not_used __attribute__((unused)))
 
143
static uchar* archive_get_key(ARCHIVE_SHARE *share, size_t *length,
 
144
                             my_bool not_used __attribute__((unused)))
142
145
{
143
146
  *length=share->table_name_length;
144
 
  return (unsigned char*) share->table_name;
 
147
  return (uchar*) share->table_name;
145
148
}
146
149
 
147
150
 
159
162
 
160
163
int archive_db_init(void *p)
161
164
{
 
165
  DBUG_ENTER("archive_db_init");
162
166
  handlerton *archive_hton;
163
167
 
164
168
  archive_hton= (handlerton *)p;
165
169
  archive_hton->state= SHOW_OPTION_YES;
 
170
  archive_hton->db_type= DB_TYPE_ARCHIVE_DB;
166
171
  archive_hton->create= archive_create_handler;
167
172
  archive_hton->flags= HTON_NO_FLAGS;
168
173
  archive_hton->discover= archive_discover;
175
180
  if (hash_init(&archive_open_tables, system_charset_info, 32, 0, 0,
176
181
                (hash_get_key) archive_get_key, 0, 0))
177
182
  {
178
 
    pthread_mutex_destroy(&archive_mutex);
 
183
    VOID(pthread_mutex_destroy(&archive_mutex));
179
184
  }
180
185
  else
181
186
  {
182
 
    return(false);
 
187
    DBUG_RETURN(false);
183
188
  }
184
189
error:
185
 
  return(true);
 
190
  DBUG_RETURN(true);
186
191
}
187
192
 
188
193
/*
196
201
    false       OK
197
202
*/
198
203
 
199
 
int archive_db_done(void *p __attribute__((unused)))
 
204
int archive_db_done(void *p __attribute__((__unused__)))
200
205
{
201
206
  hash_free(&archive_open_tables);
202
 
  pthread_mutex_destroy(&archive_mutex);
 
207
  VOID(pthread_mutex_destroy(&archive_mutex));
203
208
 
204
209
  return 0;
205
210
}
216
221
  archive_reader_open= false;
217
222
}
218
223
 
219
 
int archive_discover(handlerton *hton __attribute__((unused)),
220
 
                     THD* thd __attribute__((unused)),
 
224
int archive_discover(handlerton *hton __attribute__((__unused__)),
 
225
                     THD* thd __attribute__((__unused__)),
221
226
                     const char *db,
222
227
                     const char *name,
223
 
                     unsigned char **frmblob,
 
228
                     uchar **frmblob,
224
229
                     size_t *frmlen)
225
230
{
 
231
  DBUG_ENTER("archive_discover");
 
232
  DBUG_PRINT("archive_discover", ("db: %s, name: %s", db, name)); 
226
233
  azio_stream frm_stream;
227
234
  char az_file[FN_REFLEN];
228
235
  char *frm_ptr;
236
243
  if (!(azopen(&frm_stream, az_file, O_RDONLY|O_BINARY, AZ_METHOD_BLOCK)))
237
244
  {
238
245
    if (errno == EROFS || errno == EACCES)
239
 
      return(my_errno= errno);
240
 
    return(HA_ERR_CRASHED_ON_USAGE);
 
246
      DBUG_RETURN(my_errno= errno);
 
247
    DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
241
248
  }
242
249
 
243
250
  if (frm_stream.frm_length == 0)
248
255
  azclose(&frm_stream);
249
256
 
250
257
  *frmlen= frm_stream.frm_length;
251
 
  *frmblob= (unsigned char*) frm_ptr;
 
258
  *frmblob= (uchar*) frm_ptr;
252
259
 
253
 
  return(0);
 
260
  DBUG_RETURN(0);
254
261
err:
255
262
  my_errno= 0;
256
 
  return(1);
 
263
  DBUG_RETURN(1);
257
264
}
258
265
 
259
266
/*
261
268
*/
262
269
int ha_archive::read_data_header(azio_stream *file_to_read)
263
270
{
 
271
  DBUG_ENTER("ha_archive::read_data_header");
 
272
 
264
273
  if (azread_init(file_to_read) == -1)
265
 
    return(HA_ERR_CRASHED_ON_USAGE);
 
274
    DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
266
275
 
267
276
  if (file_to_read->version >= 3)
268
 
    return(0);
 
277
    DBUG_RETURN(0);
269
278
 
270
 
  return(1);
 
279
  DBUG_RETURN(1);
271
280
}
272
281
 
273
282
 
280
289
*/
281
290
ARCHIVE_SHARE *ha_archive::get_share(const char *table_name, int *rc)
282
291
{
283
 
  uint32_t length;
 
292
  uint length;
 
293
  DBUG_ENTER("ha_archive::get_share");
284
294
 
285
295
  pthread_mutex_lock(&archive_mutex);
286
296
  length=(uint) strlen(table_name);
287
297
 
288
298
  if (!(share=(ARCHIVE_SHARE*) hash_search(&archive_open_tables,
289
 
                                           (unsigned char*) table_name,
 
299
                                           (uchar*) table_name,
290
300
                                           length)))
291
301
  {
292
302
    char *tmp_name;
295
305
    if (!my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
296
306
                          &share, sizeof(*share),
297
307
                          &tmp_name, length+1,
298
 
                          NULL)) 
 
308
                          NullS)) 
299
309
    {
300
310
      pthread_mutex_unlock(&archive_mutex);
301
311
      *rc= HA_ERR_OUT_OF_MEM;
302
 
      return(NULL);
 
312
      DBUG_RETURN(NULL);
303
313
    }
304
314
 
305
315
    share->use_count= 0;
309
319
    share->archive_write_open= false;
310
320
    fn_format(share->data_file_name, table_name, "",
311
321
              ARZ, MY_REPLACE_EXT | MY_UNPACK_FILENAME);
312
 
    my_stpcpy(share->table_name, table_name);
 
322
    strmov(share->table_name, table_name);
 
323
    DBUG_PRINT("ha_archive", ("Data File %s", 
 
324
                        share->data_file_name));
313
325
    /*
314
326
      We will use this lock for rows.
315
327
    */
316
 
    pthread_mutex_init(&share->mutex,MY_MUTEX_INIT_FAST);
 
328
    VOID(pthread_mutex_init(&share->mutex,MY_MUTEX_INIT_FAST));
317
329
    
318
330
    /*
319
331
      We read the meta file, but do not mark it dirty. Since we are not
324
336
    if (!(azopen(&archive_tmp, share->data_file_name, O_RDONLY|O_BINARY,
325
337
                 AZ_METHOD_BLOCK)))
326
338
    {
327
 
      pthread_mutex_destroy(&share->mutex);
 
339
      VOID(pthread_mutex_destroy(&share->mutex));
328
340
      free(share);
329
341
      pthread_mutex_unlock(&archive_mutex);
330
342
      *rc= HA_ERR_CRASHED_ON_REPAIR;
331
 
      return(NULL);
 
343
      DBUG_RETURN(NULL);
332
344
    }
333
345
    stats.auto_increment_value= archive_tmp.auto_increment + 1;
334
346
    share->rows_recorded= (ha_rows)archive_tmp.rows;
340
352
    }
341
353
    azclose(&archive_tmp);
342
354
 
343
 
    my_hash_insert(&archive_open_tables, (unsigned char*) share);
 
355
    VOID(my_hash_insert(&archive_open_tables, (uchar*) share));
344
356
    thr_lock_init(&share->lock);
345
357
  }
346
358
  share->use_count++;
 
359
  DBUG_PRINT("ha_archive", ("archive table %.*s has %d open handles now", 
 
360
                      share->table_name_length, share->table_name,
 
361
                      share->use_count));
347
362
  if (share->crashed)
348
363
    *rc= HA_ERR_CRASHED_ON_USAGE;
349
364
  pthread_mutex_unlock(&archive_mutex);
350
365
 
351
 
  return(share);
 
366
  DBUG_RETURN(share);
352
367
}
353
368
 
354
369
 
359
374
int ha_archive::free_share()
360
375
{
361
376
  int rc= 0;
 
377
  DBUG_ENTER("ha_archive::free_share");
 
378
  DBUG_PRINT("ha_archive",
 
379
             ("archive table %.*s has %d open handles on entrance", 
 
380
              share->table_name_length, share->table_name,
 
381
              share->use_count));
362
382
 
363
383
  pthread_mutex_lock(&archive_mutex);
364
384
  if (!--share->use_count)
365
385
  {
366
 
    hash_delete(&archive_open_tables, (unsigned char*) share);
 
386
    hash_delete(&archive_open_tables, (uchar*) share);
367
387
    thr_lock_delete(&share->lock);
368
 
    pthread_mutex_destroy(&share->mutex);
 
388
    VOID(pthread_mutex_destroy(&share->mutex));
369
389
    /* 
370
390
      We need to make sure we don't reset the crashed state.
371
391
      If we open a crashed file, wee need to close it as crashed unless
378
398
      if (azclose(&(share->archive_write)))
379
399
        rc= 1;
380
400
    }
381
 
    free((unsigned char*) share);
 
401
    my_free((uchar*) share, MYF(0));
382
402
  }
383
403
  pthread_mutex_unlock(&archive_mutex);
384
404
 
385
 
  return(rc);
 
405
  DBUG_RETURN(rc);
386
406
}
387
407
 
388
408
int ha_archive::init_archive_writer()
389
409
{
 
410
  DBUG_ENTER("ha_archive::init_archive_writer");
390
411
  /* 
391
412
    It is expensive to open and close the data files and since you can't have
392
413
    a gzip file that can be both read and written we keep a writer open
395
416
  if (!(azopen(&(share->archive_write), share->data_file_name, 
396
417
               O_RDWR|O_BINARY, AZ_METHOD_BLOCK)))
397
418
  {
 
419
    DBUG_PRINT("ha_archive", ("Could not open archive write file"));
398
420
    share->crashed= true;
399
 
    return(1);
 
421
    DBUG_RETURN(1);
400
422
  }
401
423
  share->archive_write_open= true;
402
424
 
403
 
  return(0);
 
425
  DBUG_RETURN(0);
404
426
}
405
427
 
406
428
 
409
431
*/
410
432
int ha_archive::init_archive_reader()
411
433
{
 
434
  DBUG_ENTER("ha_archive::init_archive_reader");
412
435
  /* 
413
436
    It is expensive to open and close the data files and since you can't have
414
437
    a gzip file that can be both read and written we keep a writer open
432
455
    if (!(azopen(&archive, share->data_file_name, O_RDONLY|O_BINARY, 
433
456
                 method)))
434
457
    {
 
458
      DBUG_PRINT("ha_archive", ("Could not open archive read file"));
435
459
      share->crashed= true;
436
 
      return(1);
 
460
      DBUG_RETURN(1);
437
461
    }
438
462
    archive_reader_open= true;
439
463
  }
440
464
 
441
 
  return(0);
 
465
  DBUG_RETURN(0);
442
466
}
443
467
 
444
468
 
447
471
*/
448
472
static const char *ha_archive_exts[] = {
449
473
  ARZ,
450
 
  NULL
 
474
  NullS
451
475
};
452
476
 
453
477
const char **ha_archive::bas_ext() const
463
487
  We open the file we will read from.
464
488
*/
465
489
int ha_archive::open(const char *name,
466
 
                     int mode __attribute__((unused)),
467
 
                     uint32_t open_options)
 
490
                     int mode __attribute__((__unused__)),
 
491
                     uint open_options)
468
492
{
469
493
  int rc= 0;
 
494
  DBUG_ENTER("ha_archive::open");
 
495
 
 
496
  DBUG_PRINT("ha_archive", ("archive table was opened for crash: %s", 
 
497
                      (open_options & HA_OPEN_FOR_REPAIR) ? "yes" : "no"));
470
498
  share= get_share(name, &rc);
471
499
 
472
500
  if (rc == HA_ERR_CRASHED_ON_USAGE && !(open_options & HA_OPEN_FOR_REPAIR))
473
501
  {
474
502
    /* purecov: begin inspected */
475
503
    free_share();
476
 
    return(rc);
 
504
    DBUG_RETURN(rc);
477
505
    /* purecov: end */    
478
506
  }
479
507
  else if (rc == HA_ERR_OUT_OF_MEM)
480
508
  {
481
 
    return(rc);
 
509
    DBUG_RETURN(rc);
482
510
  }
483
511
 
484
 
  assert(share);
 
512
  DBUG_ASSERT(share);
485
513
 
486
514
  record_buffer= create_record_buffer(table->s->reclength + 
487
515
                                      ARCHIVE_ROW_HEADER_SIZE);
489
517
  if (!record_buffer)
490
518
  {
491
519
    free_share();
492
 
    return(HA_ERR_OUT_OF_MEM);
 
520
    DBUG_RETURN(HA_ERR_OUT_OF_MEM);
493
521
  }
494
522
 
495
523
  thr_lock_data_init(&share->lock, &lock, NULL);
496
524
 
 
525
  DBUG_PRINT("ha_archive", ("archive table was crashed %s", 
 
526
                      rc == HA_ERR_CRASHED_ON_USAGE ? "yes" : "no"));
497
527
  if (rc == HA_ERR_CRASHED_ON_USAGE && open_options & HA_OPEN_FOR_REPAIR)
498
528
  {
499
 
    return(0);
 
529
    DBUG_RETURN(0);
500
530
  }
501
531
  else
502
 
    return(rc);
 
532
    DBUG_RETURN(rc);
503
533
}
504
534
 
505
535
 
523
553
int ha_archive::close(void)
524
554
{
525
555
  int rc= 0;
 
556
  DBUG_ENTER("ha_archive::close");
526
557
 
527
558
  destroy_record_buffer(record_buffer);
528
559
 
535
566
  /* then also close share */
536
567
  rc|= free_share();
537
568
 
538
 
  return(rc);
 
569
  DBUG_RETURN(rc);
539
570
}
540
571
 
541
572
 
548
579
  of creation.
549
580
*/
550
581
 
551
 
int ha_archive::create(const char *name, Table *table_arg,
 
582
int ha_archive::create(const char *name, TABLE *table_arg,
552
583
                       HA_CREATE_INFO *create_info)
553
584
{
554
585
  char name_buff[FN_REFLEN];
557
588
  azio_stream create_stream;            /* Archive file we are working with */
558
589
  File frm_file;                   /* File handler for readers */
559
590
  struct stat file_stat;
560
 
  unsigned char *frm_ptr;
 
591
  uchar *frm_ptr;
 
592
 
 
593
  DBUG_ENTER("ha_archive::create");
561
594
 
562
595
  stats.auto_increment_value= create_info->auto_increment_value;
563
596
 
564
 
  for (uint32_t key= 0; key < table_arg->sizeKeys(); key++)
 
597
  for (uint key= 0; key < table_arg->s->keys; key++)
565
598
  {
566
599
    KEY *pos= table_arg->key_info+key;
567
600
    KEY_PART_INFO *key_part=     pos->key_part;
574
607
      if (!(field->flags & AUTO_INCREMENT_FLAG))
575
608
      {
576
609
        error= -1;
 
610
        DBUG_PRINT("ha_archive", ("Index error in creating archive table"));
577
611
        goto error;
578
612
      }
579
613
    }
584
618
  */
585
619
  if (create_info->data_file_name && create_info->data_file_name[0] != '#')
586
620
  {
 
621
    DBUG_PRINT("ha_archive", ("archive will create stream file %s", 
 
622
                        create_info->data_file_name));
 
623
                        
587
624
    fn_format(name_buff, create_info->data_file_name, "", ARZ,
588
625
              MY_REPLACE_EXT | MY_UNPACK_FILENAME);
589
626
    fn_format(linkname, name, "", ARZ,
622
659
    {
623
660
      if (fstat(frm_file, &file_stat))
624
661
      {
625
 
        frm_ptr= (unsigned char *)my_malloc(sizeof(unsigned char) * file_stat.st_size, MYF(0));
 
662
        frm_ptr= (uchar *)my_malloc(sizeof(uchar) * file_stat.st_size, MYF(0));
626
663
        if (frm_ptr)
627
664
        {
628
665
          my_read(frm_file, frm_ptr, file_stat.st_size, MYF(0));
629
666
          azwrite_frm(&create_stream, (char *)frm_ptr, file_stat.st_size);
630
 
          free((unsigned char*)frm_ptr);
 
667
          my_free((uchar*)frm_ptr, MYF(0));
631
668
        }
632
669
      }
633
670
      my_close(frm_file, MYF(0));
652
689
  else
653
690
    my_errno= 0;
654
691
 
655
 
  return(0);
 
692
  DBUG_PRINT("ha_archive", ("Creating File %s", name_buff));
 
693
  DBUG_PRINT("ha_archive", ("Creating Link %s", linkname));
 
694
 
 
695
 
 
696
  DBUG_RETURN(0);
656
697
 
657
698
error2:
658
699
  delete_table(name);
659
700
error:
660
701
  /* Return error number, if we got one */
661
 
  return(error ? error : -1);
 
702
  DBUG_RETURN(error ? error : -1);
662
703
}
663
704
 
664
705
/*
665
706
  This is where the actual row is written out.
666
707
*/
667
 
int ha_archive::real_write_row(unsigned char *buf, azio_stream *writer)
 
708
int ha_archive::real_write_row(uchar *buf, azio_stream *writer)
668
709
{
669
710
  my_off_t written;
670
711
  unsigned int r_pack_length;
 
712
  DBUG_ENTER("ha_archive::real_write_row");
671
713
 
672
714
  /* We pack the row for writing */
673
715
  r_pack_length= pack_row(buf);
675
717
  written= azwrite_row(writer, record_buffer->buffer, r_pack_length);
676
718
  if (written != r_pack_length)
677
719
  {
678
 
    return(-1);
 
720
    DBUG_PRINT("ha_archive", ("Wrote %d bytes expected %d", 
 
721
                                              (uint32) written, 
 
722
                                              (uint32)r_pack_length));
 
723
    DBUG_RETURN(-1);
679
724
  }
680
725
 
681
726
  if (!delayed_insert || !bulk_insert)
682
727
    share->dirty= true;
683
728
 
684
 
  return(0);
 
729
  DBUG_RETURN(0);
685
730
}
686
731
 
687
732
 
690
735
  the bytes required for the length in the header.
691
736
*/
692
737
 
693
 
uint32_t ha_archive::max_row_length(const unsigned char *buf __attribute__((unused)))
 
738
uint32 ha_archive::max_row_length(const uchar *buf __attribute__((__unused__)))
694
739
{
695
 
  uint32_t length= (uint32_t)(table->getRecordLength() + table->sizeFields()*2);
 
740
  uint32 length= (uint32)(table->s->reclength + table->s->fields*2);
696
741
  length+= ARCHIVE_ROW_HEADER_SIZE;
697
742
 
698
 
  uint32_t *ptr, *end;
699
 
  for (ptr= table->getBlobField(), end=ptr + table->sizeBlobFields();
 
743
  uint *ptr, *end;
 
744
  for (ptr= table->s->blob_field, end=ptr + table->s->blob_fields ;
700
745
       ptr != end ;
701
746
       ptr++)
702
747
  {
707
752
}
708
753
 
709
754
 
710
 
unsigned int ha_archive::pack_row(unsigned char *record)
 
755
unsigned int ha_archive::pack_row(uchar *record)
711
756
{
712
 
  unsigned char *ptr;
 
757
  uchar *ptr;
 
758
 
 
759
  DBUG_ENTER("ha_archive::pack_row");
 
760
 
713
761
 
714
762
  if (fix_rec_buff(max_row_length(record)))
715
 
    return(HA_ERR_OUT_OF_MEM); /* purecov: inspected */
 
763
    DBUG_RETURN(HA_ERR_OUT_OF_MEM); /* purecov: inspected */
716
764
 
717
765
  /* Copy null bits */
718
766
  memcpy(record_buffer->buffer, record, table->s->null_bytes);
724
772
      ptr= (*field)->pack(ptr, record + (*field)->offset(record));
725
773
  }
726
774
 
727
 
  return((unsigned int) (ptr - record_buffer->buffer));
 
775
  DBUG_PRINT("ha_archive",("Pack row length %u", (unsigned int)
 
776
                           (ptr - record_buffer->buffer - 
 
777
                             ARCHIVE_ROW_HEADER_SIZE)));
 
778
 
 
779
  DBUG_RETURN((unsigned int) (ptr - record_buffer->buffer));
728
780
}
729
781
 
730
782
 
737
789
  for implementing start_bulk_insert() is that we could skip 
738
790
  setting dirty to true each time.
739
791
*/
740
 
int ha_archive::write_row(unsigned char *buf)
 
792
int ha_archive::write_row(uchar *buf)
741
793
{
742
794
  int rc;
743
 
  unsigned char *read_buf= NULL;
 
795
  uchar *read_buf= NULL;
744
796
  uint64_t temp_auto;
745
 
  unsigned char *record=  table->record[0];
 
797
  uchar *record=  table->record[0];
 
798
  DBUG_ENTER("ha_archive::write_row");
746
799
 
747
800
  if (share->crashed)
748
 
    return(HA_ERR_CRASHED_ON_USAGE);
 
801
    DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
749
802
 
750
803
  ha_statistic_increment(&SSV::ha_write_count);
751
804
  if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
754
807
 
755
808
  if (share->archive_write_open == false)
756
809
    if (init_archive_writer())
757
 
      return(HA_ERR_CRASHED_ON_USAGE);
 
810
      DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
758
811
 
759
812
 
760
813
  if (table->next_number_field && record == table->record[0])
785
838
        First we create a buffer that we can use for reading rows, and can pass
786
839
        to get_row().
787
840
      */
788
 
      if (!(read_buf= (unsigned char*) my_malloc(table->s->reclength, MYF(MY_WME))))
 
841
      if (!(read_buf= (uchar*) my_malloc(table->s->reclength, MYF(MY_WME))))
789
842
      {
790
843
        rc= HA_ERR_OUT_OF_MEM;
791
844
        goto error;
835
888
error:
836
889
  pthread_mutex_unlock(&share->mutex);
837
890
  if (read_buf)
838
 
    free((unsigned char*) read_buf);
 
891
    my_free((uchar*) read_buf, MYF(0));
839
892
 
840
 
  return(rc);
 
893
  DBUG_RETURN(rc);
841
894
}
842
895
 
843
896
 
844
 
void ha_archive::get_auto_increment(uint64_t offset __attribute__((unused)),
845
 
                                    uint64_t increment __attribute__((unused)),
846
 
                                    uint64_t nb_desired_values __attribute__((unused)),
847
 
                                    uint64_t *first_value __attribute__((unused)),
848
 
                                    uint64_t *nb_reserved_values __attribute__((unused)))
 
897
void ha_archive::get_auto_increment(uint64_t offset __attribute__((__unused__)),
 
898
                                    uint64_t increment __attribute__((__unused__)),
 
899
                                    uint64_t nb_desired_values __attribute__((__unused__)),
 
900
                                    uint64_t *first_value __attribute__((__unused__)),
 
901
                                    uint64_t *nb_reserved_values __attribute__((__unused__)))
849
902
{
850
903
  *nb_reserved_values= UINT64_MAX;
851
904
  *first_value= share->archive_write.auto_increment + 1;
852
905
}
853
906
 
854
907
/* Initialized at each key walk (called multiple times unlike rnd_init()) */
855
 
int ha_archive::index_init(uint32_t keynr, bool sorted __attribute__((unused)))
 
908
int ha_archive::index_init(uint keynr, bool sorted __attribute__((__unused__)))
856
909
{
 
910
  DBUG_ENTER("ha_archive::index_init");
857
911
  active_index= keynr;
858
 
  return(0);
 
912
  DBUG_RETURN(0);
859
913
}
860
914
 
861
915
 
863
917
  No indexes, so if we get a request for an index search since we tell
864
918
  the optimizer that we have unique indexes, we scan
865
919
*/
866
 
int ha_archive::index_read(unsigned char *buf, const unsigned char *key,
867
 
                             uint32_t key_len, enum ha_rkey_function find_flag)
 
920
int ha_archive::index_read(uchar *buf, const uchar *key,
 
921
                             uint key_len, enum ha_rkey_function find_flag)
868
922
{
869
923
  int rc;
 
924
  DBUG_ENTER("ha_archive::index_read");
870
925
  rc= index_read_idx(buf, active_index, key, key_len, find_flag);
871
 
  return(rc);
 
926
  DBUG_RETURN(rc);
872
927
}
873
928
 
874
929
 
875
 
int ha_archive::index_read_idx(unsigned char *buf, uint32_t index, const unsigned char *key,
876
 
                               uint32_t key_len,
877
 
                               enum ha_rkey_function find_flag __attribute__((unused)))
 
930
int ha_archive::index_read_idx(uchar *buf, uint index, const uchar *key,
 
931
                               uint key_len,
 
932
                               enum ha_rkey_function find_flag __attribute__((__unused__)))
878
933
{
879
934
  int rc;
880
935
  bool found= 0;
883
938
  current_key= key;
884
939
  current_key_len= key_len;
885
940
 
 
941
 
 
942
  DBUG_ENTER("ha_archive::index_read_idx");
 
943
 
886
944
  rc= rnd_init(true);
887
945
 
888
946
  if (rc)
898
956
  }
899
957
 
900
958
  if (found)
901
 
    return(0);
 
959
    DBUG_RETURN(0);
902
960
 
903
961
error:
904
 
  return(rc ? rc : HA_ERR_END_OF_FILE);
 
962
  DBUG_RETURN(rc ? rc : HA_ERR_END_OF_FILE);
905
963
}
906
964
 
907
965
 
908
 
int ha_archive::index_next(unsigned char * buf) 
 
966
int ha_archive::index_next(uchar * buf) 
909
967
910
968
  bool found= 0;
911
969
 
 
970
  DBUG_ENTER("ha_archive::index_next");
 
971
 
912
972
  while (!(get_row(&archive, buf)))
913
973
  {
914
974
    if (!memcmp(current_key, buf+current_k_offset, current_key_len))
918
978
    }
919
979
  }
920
980
 
921
 
  return(found ? 0 : HA_ERR_END_OF_FILE); 
 
981
  DBUG_RETURN(found ? 0 : HA_ERR_END_OF_FILE); 
922
982
}
923
983
 
924
984
/*
929
989
 
930
990
int ha_archive::rnd_init(bool scan)
931
991
{
 
992
  DBUG_ENTER("ha_archive::rnd_init");
 
993
  
932
994
  if (share->crashed)
933
 
      return(HA_ERR_CRASHED_ON_USAGE);
 
995
      DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
934
996
 
935
997
  init_archive_reader();
936
998
 
937
999
  /* We rewind the file so that we can read from the beginning if scan */
938
1000
  if (scan)
939
1001
  {
 
1002
    DBUG_PRINT("info", ("archive will retrieve %llu rows", 
 
1003
                        (uint64_t) scan_rows));
 
1004
 
940
1005
    if (read_data_header(&archive))
941
 
      return(HA_ERR_CRASHED_ON_USAGE);
 
1006
      DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
942
1007
  }
943
1008
 
944
 
  return(0);
 
1009
  DBUG_RETURN(0);
945
1010
}
946
1011
 
947
1012
 
949
1014
  This is the method that is used to read a row. It assumes that the row is 
950
1015
  positioned where you want it.
951
1016
*/
952
 
int ha_archive::get_row(azio_stream *file_to_read, unsigned char *buf)
 
1017
int ha_archive::get_row(azio_stream *file_to_read, uchar *buf)
953
1018
{
954
1019
  int rc;
955
 
 
 
1020
  DBUG_ENTER("ha_archive::get_row");
 
1021
  DBUG_PRINT("ha_archive", ("Picking version for get_row() %d -> %d", 
 
1022
                            (uchar)file_to_read->version, 
 
1023
                            ARCHIVE_VERSION));
956
1024
  if (file_to_read->version == ARCHIVE_VERSION)
957
1025
    rc= get_row_version3(file_to_read, buf);
958
1026
  else
959
1027
    rc= -1;
960
1028
 
961
 
  return(rc);
 
1029
  DBUG_PRINT("ha_archive", ("Return %d\n", rc));
 
1030
 
 
1031
  DBUG_RETURN(rc);
962
1032
}
963
1033
 
964
1034
/* Reallocate buffer if needed */
965
1035
bool ha_archive::fix_rec_buff(unsigned int length)
966
1036
{
967
 
  assert(record_buffer->buffer);
 
1037
  DBUG_ENTER("ha_archive::fix_rec_buff");
 
1038
  DBUG_PRINT("ha_archive", ("Fixing %u for %u", 
 
1039
                            length, record_buffer->length));
 
1040
  DBUG_ASSERT(record_buffer->buffer);
968
1041
 
969
1042
  if (length > record_buffer->length)
970
1043
  {
971
 
    unsigned char *newptr;
972
 
    if (!(newptr=(unsigned char*) my_realloc((unsigned char*) record_buffer->buffer, 
 
1044
    uchar *newptr;
 
1045
    if (!(newptr=(uchar*) my_realloc((uchar*) record_buffer->buffer, 
973
1046
                                    length,
974
1047
                                    MYF(MY_ALLOW_ZERO_PTR))))
975
 
      return(1);
 
1048
      DBUG_RETURN(1);
976
1049
    record_buffer->buffer= newptr;
977
1050
    record_buffer->length= length;
978
1051
  }
979
1052
 
980
 
  assert(length <= record_buffer->length);
 
1053
  DBUG_ASSERT(length <= record_buffer->length);
981
1054
 
982
 
  return(0);
 
1055
  DBUG_RETURN(0);
983
1056
}
984
1057
 
985
 
int ha_archive::unpack_row(azio_stream *file_to_read, unsigned char *record)
 
1058
int ha_archive::unpack_row(azio_stream *file_to_read, uchar *record)
986
1059
{
 
1060
  DBUG_ENTER("ha_archive::unpack_row");
 
1061
 
987
1062
  unsigned int read;
988
1063
  int error;
989
 
  const unsigned char *ptr;
 
1064
  const uchar *ptr;
990
1065
 
991
1066
  read= azread_row(file_to_read, &error);
992
 
  ptr= (const unsigned char *)file_to_read->row_ptr;
 
1067
  ptr= (const uchar *)file_to_read->row_ptr;
993
1068
 
994
1069
  if (error || read == 0)
995
1070
  {
996
 
    return(-1);
 
1071
    DBUG_RETURN(-1);
997
1072
  }
998
1073
 
999
1074
  /* Copy null bits */
1000
 
  memcpy(record, ptr, table->getNullBytes());
1001
 
  ptr+= table->getNullBytes();
 
1075
  memcpy(record, ptr, table->s->null_bytes);
 
1076
  ptr+= table->s->null_bytes;
1002
1077
  for (Field **field=table->field ; *field ; field++)
1003
1078
  {
1004
1079
    if (!((*field)->is_null()))
1006
1081
      ptr= (*field)->unpack(record + (*field)->offset(table->record[0]), ptr);
1007
1082
    }
1008
1083
  }
1009
 
  return(0);
 
1084
  DBUG_RETURN(0);
1010
1085
}
1011
1086
 
1012
1087
 
1013
 
int ha_archive::get_row_version3(azio_stream *file_to_read, unsigned char *buf)
 
1088
int ha_archive::get_row_version3(azio_stream *file_to_read, uchar *buf)
1014
1089
{
 
1090
  DBUG_ENTER("ha_archive::get_row_version3");
 
1091
 
1015
1092
  int returnable= unpack_row(file_to_read, buf);
1016
1093
 
1017
 
  return(returnable);
 
1094
  DBUG_RETURN(returnable);
1018
1095
}
1019
1096
 
1020
1097
 
1023
1100
  or by having had ha_archive::rnd_pos() called before it is called.
1024
1101
*/
1025
1102
 
1026
 
int ha_archive::rnd_next(unsigned char *buf)
 
1103
int ha_archive::rnd_next(uchar *buf)
1027
1104
{
1028
1105
  int rc;
 
1106
  DBUG_ENTER("ha_archive::rnd_next");
1029
1107
 
1030
1108
  if (share->crashed)
1031
 
      return(HA_ERR_CRASHED_ON_USAGE);
 
1109
      DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
1032
1110
 
1033
1111
  if (!scan_rows)
1034
 
    return(HA_ERR_END_OF_FILE);
 
1112
    DBUG_RETURN(HA_ERR_END_OF_FILE);
1035
1113
  scan_rows--;
1036
1114
 
1037
1115
  ha_statistic_increment(&SSV::ha_read_rnd_next_count);
1040
1118
 
1041
1119
  table->status=rc ? STATUS_NOT_FOUND: 0;
1042
1120
 
1043
 
  return(rc);
 
1121
  DBUG_RETURN(rc);
1044
1122
}
1045
1123
 
1046
1124
 
1050
1128
  needed.
1051
1129
*/
1052
1130
 
1053
 
void ha_archive::position(const unsigned char *record __attribute__((unused)))
 
1131
void ha_archive::position(const uchar *record __attribute__((__unused__)))
1054
1132
{
 
1133
  DBUG_ENTER("ha_archive::position");
1055
1134
  my_store_ptr(ref, ref_length, current_position);
1056
 
  return;
 
1135
  DBUG_VOID_RETURN;
1057
1136
}
1058
1137
 
1059
1138
 
1064
1143
  correctly ordered row.
1065
1144
*/
1066
1145
 
1067
 
int ha_archive::rnd_pos(unsigned char * buf, unsigned char *pos)
 
1146
int ha_archive::rnd_pos(uchar * buf, uchar *pos)
1068
1147
{
 
1148
  DBUG_ENTER("ha_archive::rnd_pos");
1069
1149
  ha_statistic_increment(&SSV::ha_read_rnd_next_count);
1070
1150
  current_position= (my_off_t)my_get_ptr(pos, ref_length);
1071
1151
  if (azseek(&archive, (size_t)current_position, SEEK_SET) == (size_t)(-1L))
1072
 
    return(HA_ERR_CRASHED_ON_USAGE);
1073
 
  return(get_row(&archive, buf));
 
1152
    DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
 
1153
  DBUG_RETURN(get_row(&archive, buf));
1074
1154
}
1075
1155
 
1076
1156
/*
1080
1160
*/
1081
1161
int ha_archive::repair(THD* thd, HA_CHECK_OPT* check_opt)
1082
1162
{
 
1163
  DBUG_ENTER("ha_archive::repair");
1083
1164
  check_opt->flags= T_EXTEND;
1084
1165
  int rc= optimize(thd, check_opt);
1085
1166
 
1086
1167
  if (rc)
1087
 
    return(HA_ERR_CRASHED_ON_REPAIR);
 
1168
    DBUG_RETURN(HA_ERR_CRASHED_ON_REPAIR);
1088
1169
 
1089
1170
  share->crashed= false;
1090
 
  return(0);
 
1171
  DBUG_RETURN(0);
1091
1172
}
1092
1173
 
1093
1174
/*
1094
1175
  The table can become fragmented if data was inserted, read, and then
1095
1176
  inserted again. What we do is open up the file and recompress it completely. 
1096
1177
*/
1097
 
int ha_archive::optimize(THD* thd __attribute__((unused)),
1098
 
                         HA_CHECK_OPT* check_opt __attribute__((unused)))
 
1178
int ha_archive::optimize(THD* thd __attribute__((__unused__)),
 
1179
                         HA_CHECK_OPT* check_opt __attribute__((__unused__)))
1099
1180
{
 
1181
  DBUG_ENTER("ha_archive::optimize");
1100
1182
  int rc= 0;
1101
1183
  azio_stream writer;
1102
1184
  char writer_filename[FN_REFLEN];
1115
1197
            MY_REPLACE_EXT | MY_UNPACK_FILENAME);
1116
1198
 
1117
1199
  if (!(azopen(&writer, writer_filename, O_CREAT|O_RDWR|O_BINARY, AZ_METHOD_BLOCK)))
1118
 
    return(HA_ERR_CRASHED_ON_USAGE); 
 
1200
    DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); 
1119
1201
 
1120
1202
  /* 
1121
1203
    An extended rebuild is a lot more effort. We open up each row and re-record it. 
1126
1208
  */
1127
1209
  if (1)
1128
1210
  {
 
1211
    DBUG_PRINT("ha_archive", ("archive extended rebuild"));
 
1212
 
1129
1213
    /*
1130
1214
      Now we will rewind the archive file so that we are positioned at the 
1131
1215
      start of the file.
1144
1228
      share->rows_recorded= 0;
1145
1229
      stats.auto_increment_value= 1;
1146
1230
      share->archive_write.auto_increment= 0;
 
1231
      my_bitmap_map *org_bitmap= dbug_tmp_use_all_columns(table, table->read_set);
1147
1232
 
1148
1233
      rows_restored= archive.rows;
1149
1234
 
1170
1255
              (share->archive_write.auto_increment= auto_value) + 1;
1171
1256
        }
1172
1257
      }
 
1258
      dbug_tmp_restore_column_map(table->read_set, org_bitmap);
1173
1259
      share->rows_recorded= (ha_rows)writer.rows;
1174
1260
    }
1175
1261
 
 
1262
    DBUG_PRINT("info", ("recovered %llu archive rows", 
 
1263
                        (uint64_t)share->rows_recorded));
 
1264
 
 
1265
    DBUG_PRINT("ha_archive", ("recovered %llu archive rows", 
 
1266
                        (uint64_t)share->rows_recorded));
 
1267
 
1176
1268
    if (rc && rc != HA_ERR_END_OF_FILE)
1177
1269
    {
1178
1270
      goto error;
1188
1280
  rc = my_rename(writer_filename,share->data_file_name,MYF(0));
1189
1281
 
1190
1282
 
1191
 
  return(rc);
 
1283
  DBUG_RETURN(rc);
1192
1284
error:
 
1285
  DBUG_PRINT("ha_archive", ("Failed to recover, error was %d", rc));
1193
1286
  azclose(&writer);
1194
1287
 
1195
 
  return(rc); 
 
1288
  DBUG_RETURN(rc); 
1196
1289
}
1197
1290
 
1198
1291
/* 
1212
1305
    /* 
1213
1306
      Here is where we get into the guts of a row level lock.
1214
1307
      If TL_UNLOCK is set 
1215
 
      If we are not doing a LOCK Table or DISCARD/IMPORT
 
1308
      If we are not doing a LOCK TABLE or DISCARD/IMPORT
1216
1309
      TABLESPACE, then allow multiple writers 
1217
1310
    */
1218
1311
 
1242
1335
 
1243
1336
void ha_archive::update_create_info(HA_CREATE_INFO *create_info)
1244
1337
{
 
1338
  DBUG_ENTER("ha_archive::update_create_info");
 
1339
 
1245
1340
  ha_archive::info(HA_STATUS_AUTO);
1246
1341
  if (!(create_info->used_fields & HA_CREATE_USED_AUTO))
1247
1342
  {
1251
1346
  if (!(my_readlink(share->real_path, share->data_file_name, MYF(0))))
1252
1347
    create_info->data_file_name= share->real_path;
1253
1348
 
1254
 
  return;
 
1349
  DBUG_VOID_RETURN;
1255
1350
}
1256
1351
 
1257
1352
 
1258
1353
/*
1259
1354
  Hints for optimizer, see ha_tina for more information
1260
1355
*/
1261
 
int ha_archive::info(uint32_t flag)
 
1356
int ha_archive::info(uint flag)
1262
1357
{
 
1358
  DBUG_ENTER("ha_archive::info");
 
1359
 
1263
1360
  /* 
1264
1361
    If dirty, we lock, and then reset/flush the data.
1265
1362
    I found that just calling azflush() doesn't always work.
1267
1364
  pthread_mutex_lock(&share->mutex);
1268
1365
  if (share->dirty == true)
1269
1366
  {
 
1367
    DBUG_PRINT("ha_archive", ("archive flushing out rows for scan"));
1270
1368
    azflush(&(share->archive_write), Z_SYNC_FLUSH);
1271
1369
    share->rows_recorded= share->archive_write.rows;
1272
1370
    share->dirty= false;
1288
1386
  scan_rows= stats.records;
1289
1387
  stats.deleted= 0;
1290
1388
 
 
1389
  DBUG_PRINT("ha_archive", ("Stats rows is %d\n", (int)stats.records));
1291
1390
  /* Costs quite a bit more to get all information */
1292
1391
  if (flag & HA_STATUS_TIME)
1293
1392
  {
1294
1393
    struct stat file_stat;  // Stat information for the data file
1295
1394
 
1296
 
    stat(share->data_file_name, &file_stat);
 
1395
    VOID(stat(share->data_file_name, &file_stat));
1297
1396
 
1298
 
    stats.mean_rec_length= table->getRecordLength()+ buffer.alloced_length();
 
1397
    stats.mean_rec_length= table->s->reclength + buffer.alloced_length();
1299
1398
    stats.data_file_length= file_stat.st_size;
1300
1399
    stats.create_time= file_stat.st_ctime;
1301
1400
    stats.update_time= file_stat.st_mtime;
1313
1412
    stats.auto_increment_value= archive.auto_increment + 1;
1314
1413
  }
1315
1414
 
1316
 
  return(0);
 
1415
  DBUG_RETURN(0);
1317
1416
}
1318
1417
 
1319
1418
 
1325
1424
*/
1326
1425
void ha_archive::start_bulk_insert(ha_rows rows)
1327
1426
{
 
1427
  DBUG_ENTER("ha_archive::start_bulk_insert");
1328
1428
  if (!rows || rows >= ARCHIVE_MIN_ROWS_TO_USE_BULK_INSERT)
1329
1429
    bulk_insert= true;
1330
 
  return;
 
1430
  DBUG_VOID_RETURN;
1331
1431
}
1332
1432
 
1333
1433
 
1337
1437
*/
1338
1438
int ha_archive::end_bulk_insert()
1339
1439
{
 
1440
  DBUG_ENTER("ha_archive::end_bulk_insert");
1340
1441
  bulk_insert= false;
1341
1442
  share->dirty= true;
1342
 
  return(0);
 
1443
  DBUG_RETURN(0);
1343
1444
}
1344
1445
 
1345
1446
/*
1349
1450
*/
1350
1451
int ha_archive::delete_all_rows()
1351
1452
{
1352
 
  return(HA_ERR_WRONG_COMMAND);
 
1453
  DBUG_ENTER("ha_archive::delete_all_rows");
 
1454
  DBUG_RETURN(HA_ERR_WRONG_COMMAND);
1353
1455
}
1354
1456
 
1355
1457
/*
1357
1459
*/
1358
1460
bool ha_archive::is_crashed() const 
1359
1461
{
1360
 
  return(share->crashed); 
 
1462
  DBUG_ENTER("ha_archive::is_crashed");
 
1463
  DBUG_RETURN(share->crashed); 
1361
1464
}
1362
1465
 
1363
1466
/*
1365
1468
*/
1366
1469
 
1367
1470
int ha_archive::check(THD* thd,
1368
 
                      HA_CHECK_OPT* check_opt __attribute__((unused)))
 
1471
                      HA_CHECK_OPT* check_opt __attribute__((__unused__)))
1369
1472
{
1370
1473
  int rc= 0;
1371
1474
  const char *old_proc_info;
1372
1475
  uint64_t x;
 
1476
  DBUG_ENTER("ha_archive::check");
1373
1477
 
1374
1478
  old_proc_info= thd_proc_info(thd, "Checking table");
1375
1479
  /* Flush any waiting data */
1397
1501
  if ((rc && rc != HA_ERR_END_OF_FILE))  
1398
1502
  {
1399
1503
    share->crashed= false;
1400
 
    return(HA_ADMIN_CORRUPT);
 
1504
    DBUG_RETURN(HA_ADMIN_CORRUPT);
1401
1505
  }
1402
1506
  else
1403
1507
  {
1404
 
    return(HA_ADMIN_OK);
 
1508
    DBUG_RETURN(HA_ADMIN_OK);
1405
1509
  }
1406
1510
}
1407
1511
 
1411
1515
bool ha_archive::check_and_repair(THD *thd) 
1412
1516
{
1413
1517
  HA_CHECK_OPT check_opt;
 
1518
  DBUG_ENTER("ha_archive::check_and_repair");
1414
1519
 
1415
1520
  check_opt.init();
1416
1521
 
1417
 
  return(repair(thd, &check_opt));
 
1522
  DBUG_RETURN(repair(thd, &check_opt));
1418
1523
}
1419
1524
 
1420
1525
archive_record_buffer *ha_archive::create_record_buffer(unsigned int length) 
1421
1526
{
 
1527
  DBUG_ENTER("ha_archive::create_record_buffer");
1422
1528
  archive_record_buffer *r;
1423
1529
  if (!(r= 
1424
1530
        (archive_record_buffer*) my_malloc(sizeof(archive_record_buffer),
1425
1531
                                           MYF(MY_WME))))
1426
1532
  {
1427
 
    return(NULL); /* purecov: inspected */
 
1533
    DBUG_RETURN(NULL); /* purecov: inspected */
1428
1534
  }
1429
1535
  r->length= (int)length;
1430
1536
 
1431
 
  if (!(r->buffer= (unsigned char*) my_malloc(r->length,
 
1537
  if (!(r->buffer= (uchar*) my_malloc(r->length,
1432
1538
                                    MYF(MY_WME))))
1433
1539
  {
1434
 
    free((char*) r);
1435
 
    return(NULL); /* purecov: inspected */
 
1540
    my_free((char*) r, MYF(MY_ALLOW_ZERO_PTR));
 
1541
    DBUG_RETURN(NULL); /* purecov: inspected */
1436
1542
  }
1437
1543
 
1438
 
  return(r);
 
1544
  DBUG_RETURN(r);
1439
1545
}
1440
1546
 
1441
1547
void ha_archive::destroy_record_buffer(archive_record_buffer *r) 
1442
1548
{
1443
 
  free((char*) r->buffer);
1444
 
  free((char*) r);
1445
 
  return;
 
1549
  DBUG_ENTER("ha_archive::destroy_record_buffer");
 
1550
  my_free((char*) r->buffer, MYF(MY_ALLOW_ZERO_PTR));
 
1551
  my_free((char*) r, MYF(MY_ALLOW_ZERO_PTR));
 
1552
  DBUG_VOID_RETURN;
1446
1553
}
1447
1554
 
1448
 
static DRIZZLE_SYSVAR_BOOL(aio, archive_use_aio,
 
1555
static MYSQL_SYSVAR_BOOL(aio, archive_use_aio,
1449
1556
  PLUGIN_VAR_NOCMDOPT,
1450
1557
  "Whether or not to use asynchronous IO.",
1451
1558
  NULL, NULL, true);
1452
1559
 
1453
1560
static struct st_mysql_sys_var* archive_system_variables[]= {
1454
 
  DRIZZLE_SYSVAR(aio),
 
1561
  MYSQL_SYSVAR(aio),
1455
1562
  NULL
1456
1563
};
1457
1564
 
 
1565
struct st_mysql_storage_engine archive_storage_engine=
 
1566
{ MYSQL_HANDLERTON_INTERFACE_VERSION };
 
1567
 
1458
1568
mysql_declare_plugin(archive)
1459
1569
{
1460
 
  DRIZZLE_STORAGE_ENGINE_PLUGIN,
 
1570
  MYSQL_STORAGE_ENGINE_PLUGIN,
 
1571
  &archive_storage_engine,
1461
1572
  "ARCHIVE",
1462
 
  "3.5",
1463
1573
  "Brian Aker, MySQL AB",
1464
1574
  "Archive storage engine",
1465
1575
  PLUGIN_LICENSE_GPL,
1466
1576
  archive_db_init, /* Plugin Init */
1467
1577
  archive_db_done, /* Plugin Deinit */
 
1578
  0x0350 /* 3.0 */,
1468
1579
  NULL,                       /* status variables                */
1469
1580
  archive_system_variables,   /* system variables                */
1470
1581
  NULL                        /* config options                  */