| 1 | /* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. | 
|---|
| 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */ | 
|---|
| 15 |  | 
|---|
| 16 | #ifdef USE_PRAGMA_INTERFACE | 
|---|
| 17 | #pragma interface			/* gcc class implementation */ | 
|---|
| 18 | #endif | 
|---|
| 19 |  | 
|---|
| 20 | #include <zlib.h> | 
|---|
| 21 | #include "azlib.h" | 
|---|
| 22 |  | 
|---|
| 23 | /* | 
|---|
| 24 | Please read ha_archive.cc first. If you are looking for more general | 
|---|
| 25 | answers on how storage engines work, look at ha_example.cc and | 
|---|
| 26 | ha_example.h. | 
|---|
| 27 | */ | 
|---|
| 28 |  | 
|---|
| 29 | typedef struct st_archive_record_buffer { | 
|---|
| 30 | uchar *buffer; | 
|---|
| 31 | uint32 length; | 
|---|
| 32 | } archive_record_buffer; | 
|---|
| 33 |  | 
|---|
| 34 |  | 
|---|
| 35 | class Archive_share : public Handler_share | 
|---|
| 36 | { | 
|---|
| 37 | public: | 
|---|
| 38 | mysql_mutex_t mutex; | 
|---|
| 39 | THR_LOCK lock; | 
|---|
| 40 | azio_stream archive_write;     /* Archive file we are working with */ | 
|---|
| 41 | ha_rows rows_recorded;    /* Number of rows in tables */ | 
|---|
| 42 | char table_name[FN_REFLEN]; | 
|---|
| 43 | char data_file_name[FN_REFLEN]; | 
|---|
| 44 | bool in_optimize; | 
|---|
| 45 | bool archive_write_open; | 
|---|
| 46 | bool dirty;               /* Flag for if a flush should occur */ | 
|---|
| 47 | bool crashed;             /* Meta file is crashed */ | 
|---|
| 48 | Archive_share(); | 
|---|
| 49 | ~Archive_share() | 
|---|
| 50 | { | 
|---|
| 51 | DBUG_PRINT( "ha_archive", ( "~Archive_share: %p", | 
|---|
| 52 | this)); | 
|---|
| 53 | if (archive_write_open) | 
|---|
| 54 | { | 
|---|
| 55 | mysql_mutex_lock(&mutex); | 
|---|
| 56 | (void) close_archive_writer(); | 
|---|
| 57 | mysql_mutex_unlock(&mutex); | 
|---|
| 58 | } | 
|---|
| 59 | thr_lock_delete(&lock); | 
|---|
| 60 | mysql_mutex_destroy(&mutex); | 
|---|
| 61 | } | 
|---|
| 62 | int init_archive_writer(); | 
|---|
| 63 | void close_archive_writer(); | 
|---|
| 64 | int write_v1_metafile(); | 
|---|
| 65 | int read_v1_metafile(); | 
|---|
| 66 | }; | 
|---|
| 67 |  | 
|---|
| 68 | /* | 
|---|
| 69 | Version for file format. | 
|---|
| 70 | 1 - Initial Version (Never Released) | 
|---|
| 71 | 2 - Stream Compression, seperate blobs, no packing | 
|---|
| 72 | 3 - One stream (row and blobs), with packing | 
|---|
| 73 | */ | 
|---|
| 74 | #define ARCHIVE_VERSION 3 | 
|---|
| 75 |  | 
|---|
| 76 | class ha_archive: public handler | 
|---|
| 77 | { | 
|---|
| 78 | THR_LOCK_DATA lock;        /* MySQL lock */ | 
|---|
| 79 | Archive_share *share;      /* Shared lock info */ | 
|---|
| 80 |  | 
|---|
| 81 | azio_stream archive;            /* Archive file we are working with */ | 
|---|
| 82 | my_off_t current_position;  /* The position of the row we just read */ | 
|---|
| 83 | uchar byte_buffer[IO_SIZE]; /* Initial buffer for our string */ | 
|---|
| 84 | String buffer;             /* Buffer used for blob storage */ | 
|---|
| 85 | ha_rows scan_rows;         /* Number of rows left in scan */ | 
|---|
| 86 | bool delayed_insert;       /* If the insert is delayed */ | 
|---|
| 87 | bool bulk_insert;          /* If we are performing a bulk insert */ | 
|---|
| 88 | const uchar *current_key; | 
|---|
| 89 | uint current_key_len; | 
|---|
| 90 | uint current_k_offset; | 
|---|
| 91 | archive_record_buffer *record_buffer; | 
|---|
| 92 | bool archive_reader_open; | 
|---|
| 93 |  | 
|---|
| 94 | archive_record_buffer *create_record_buffer(unsigned int length); | 
|---|
| 95 | void destroy_record_buffer(archive_record_buffer *r); | 
|---|
| 96 | int frm_copy(azio_stream *src, azio_stream *dst); | 
|---|
| 97 | int frm_compare(azio_stream *src); | 
|---|
| 98 | unsigned int pack_row_v1(uchar *record); | 
|---|
| 99 |  | 
|---|
| 100 | public: | 
|---|
| 101 | ha_archive(handlerton *hton, TABLE_SHARE *table_arg); | 
|---|
| 102 | ~ha_archive() | 
|---|
| 103 | { | 
|---|
| 104 | } | 
|---|
| 105 | const char *index_type(uint inx) { return "NONE"; } | 
|---|
| 106 | ulonglong table_flags() const | 
|---|
| 107 | { | 
|---|
| 108 | return (HA_NO_TRANSACTIONS | HA_REC_NOT_IN_SEQ | HA_CAN_BIT_FIELD | | 
|---|
| 109 | HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE | | 
|---|
| 110 | HA_STATS_RECORDS_IS_EXACT | HA_CAN_EXPORT | | 
|---|
| 111 | HA_HAS_RECORDS | HA_CAN_REPAIR | | 
|---|
| 112 | HA_FILE_BASED | HA_CAN_INSERT_DELAYED | HA_CAN_GEOMETRY); | 
|---|
| 113 | } | 
|---|
| 114 | ulong index_flags(uint idx, uint part, bool all_parts) const | 
|---|
| 115 | { | 
|---|
| 116 | return HA_ONLY_WHOLE_INDEX; | 
|---|
| 117 | } | 
|---|
| 118 | virtual void get_auto_increment(ulonglong offset, ulonglong increment, | 
|---|
| 119 | ulonglong nb_desired_values, | 
|---|
| 120 | ulonglong *first_value, | 
|---|
| 121 | ulonglong *nb_reserved_values); | 
|---|
| 122 | uint max_supported_keys()          const { return 1; } | 
|---|
| 123 | uint max_supported_key_length()    const { return sizeof(ulonglong); } | 
|---|
| 124 | uint max_supported_key_part_length() const { return sizeof(ulonglong); } | 
|---|
| 125 | ha_rows records() { return share->rows_recorded; } | 
|---|
| 126 | int index_init(uint keynr, bool sorted); | 
|---|
| 127 | virtual int index_read(uchar * buf, const uchar * key, | 
|---|
| 128 | uint key_len, enum ha_rkey_function find_flag); | 
|---|
| 129 | virtual int index_read_idx(uchar * buf, uint index, const uchar * key, | 
|---|
| 130 | uint key_len, enum ha_rkey_function find_flag); | 
|---|
| 131 | int index_next(uchar * buf); | 
|---|
| 132 | int open(const char *name, int mode, uint test_if_locked); | 
|---|
| 133 | int close(void); | 
|---|
| 134 | int write_row(uchar * buf); | 
|---|
| 135 | int real_write_row(uchar *buf, azio_stream *writer); | 
|---|
| 136 | int truncate(); | 
|---|
| 137 | int rnd_init(bool scan=1); | 
|---|
| 138 | int rnd_next(uchar *buf); | 
|---|
| 139 | int rnd_pos(uchar * buf, uchar *pos); | 
|---|
| 140 | int get_row(azio_stream *file_to_read, uchar *buf); | 
|---|
| 141 | int get_row_version2(azio_stream *file_to_read, uchar *buf); | 
|---|
| 142 | int get_row_version3(azio_stream *file_to_read, uchar *buf); | 
|---|
| 143 | Archive_share *get_share(const char *table_name, int *rc); | 
|---|
| 144 | int init_archive_reader(); | 
|---|
| 145 | // Always try auto_repair in case of HA_ERR_CRASHED_ON_USAGE | 
|---|
| 146 | bool auto_repair(int error) const | 
|---|
| 147 | { return error == HA_ERR_CRASHED_ON_USAGE; } | 
|---|
| 148 | int (azio_stream *file_to_read); | 
|---|
| 149 | void position(const uchar *record); | 
|---|
| 150 | int info(uint); | 
|---|
| 151 | void update_create_info(HA_CREATE_INFO *create_info); | 
|---|
| 152 | int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info); | 
|---|
| 153 | int optimize(THD* thd, HA_CHECK_OPT* check_opt); | 
|---|
| 154 | int repair(THD* thd, HA_CHECK_OPT* check_opt); | 
|---|
| 155 | int check_for_upgrade(HA_CHECK_OPT *check_opt); | 
|---|
| 156 | void start_bulk_insert(ha_rows rows, uint flags); | 
|---|
| 157 | int end_bulk_insert(); | 
|---|
| 158 | enum row_type get_row_type() const | 
|---|
| 159 | { | 
|---|
| 160 | return ROW_TYPE_COMPRESSED; | 
|---|
| 161 | } | 
|---|
| 162 | THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, | 
|---|
| 163 | enum thr_lock_type lock_type); | 
|---|
| 164 | bool is_crashed() const; | 
|---|
| 165 | int check(THD* thd, HA_CHECK_OPT* check_opt); | 
|---|
| 166 | bool check_and_repair(THD *thd); | 
|---|
| 167 | uint32 max_row_length(const uchar *buf); | 
|---|
| 168 | bool fix_rec_buff(unsigned int length); | 
|---|
| 169 | int unpack_row(azio_stream *file_to_read, uchar *record); | 
|---|
| 170 | unsigned int pack_row(uchar *record, azio_stream *writer); | 
|---|
| 171 | bool check_if_incompatible_data(HA_CREATE_INFO *info, uint table_changes); | 
|---|
| 172 | }; | 
|---|
| 173 |  | 
|---|
| 174 |  | 
|---|