15
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
20
#include "plugin/archive/archive_engine.h"
17
#include "drizzled/server_includes.h"
18
#include "drizzled/field.h"
19
#include "drizzled/field/blob.h"
20
#include "drizzled/field/timestamp.h"
21
#include "plugin/myisam/myisam.h"
22
#include "drizzled/table.h"
23
#include "drizzled/session.h"
24
#include <mysys/my_dir.h>
26
#include "ha_archive.h"
22
32
using namespace std;
23
using namespace drizzled;
27
35
First, if you want to understand storage engines you should look at
94
102
/* Variables for archive share methods */
95
103
pthread_mutex_t archive_mutex= PTHREAD_MUTEX_INITIALIZER;
97
/* When the engine starts up set the first version */
98
static uint64_t global_version= 1;
100
// We use this to find out the state of the archive aio option.
101
extern bool archive_aio_state(void);
105
static unsigned int global_version;
107
/* The file extension */
108
#define ARZ ".arz" // The data file
109
#define ARN ".ARN" // Files used during an optimize call
113
static bool archive_use_aio= false;
104
116
Number of rows that will force a bulk insert.
111
123
#define ARCHIVE_ROW_HEADER_SIZE 4
126
We just implement one additional file extension.
128
static const char *ha_archive_exts[] = {
133
class ArchiveEngine : public drizzled::plugin::StorageEngine
135
typedef std::map<string, ArchiveShare*> ArchiveMap;
136
ArchiveMap archive_open_tables;
139
ArchiveEngine(const string &name_arg)
140
: drizzled::plugin::StorageEngine(name_arg,
142
HTON_STATS_RECORDS_IS_EXACT |
144
HTON_HAS_DATA_DICTIONARY),
145
archive_open_tables()
147
table_definition_ext= ARZ;
150
virtual Cursor *create(TableShare &table,
153
return new (mem_root) ha_archive(*this, table);
156
const char **bas_ext() const {
157
return ha_archive_exts;
160
int doCreateTable(Session *session, const char *table_name,
162
drizzled::message::Table& proto);
164
int doGetTableDefinition(Session& session,
167
const char *table_name,
169
drizzled::message::Table *table_proto);
171
void doGetTableNames(CachedDirectory &directory, string& , set<string>& set_of_names);
173
int doDropTable(Session&, const string table_path);
174
ArchiveShare *findOpenTable(const string table_name);
175
void addOpenTable(const string &table_name, ArchiveShare *);
176
void deleteOpenTable(const string &table_name);
178
uint32_t max_supported_keys() const { return 1; }
179
uint32_t max_supported_key_length() const { return sizeof(uint64_t); }
180
uint32_t max_supported_key_part_length() const { return sizeof(uint64_t); }
182
uint32_t index_flags(enum ha_key_alg) const
184
return HA_ONLY_WHOLE_INDEX;
113
188
ArchiveShare *ArchiveEngine::findOpenTable(const string table_name)
115
190
ArchiveMap::iterator find_iter=
135
void ArchiveEngine::doGetTableNames(drizzled::CachedDirectory &directory,
210
void ArchiveEngine::doGetTableNames(CachedDirectory &directory,
137
212
set<string>& set_of_names)
139
drizzled::CachedDirectory::Entries entries= directory.getEntries();
214
CachedDirectory::Entries entries= directory.getEntries();
141
for (drizzled::CachedDirectory::Entries::iterator entry_iter= entries.begin();
216
for (CachedDirectory::Entries::iterator entry_iter= entries.begin();
142
217
entry_iter != entries.end(); ++entry_iter)
144
drizzled::CachedDirectory::Entry *entry= *entry_iter;
145
const string *filename= &entry->filename;
219
CachedDirectory::Entry *entry= *entry_iter;
220
string *filename= &entry->filename;
147
222
assert(filename->size());
149
224
const char *ext= strchr(filename->c_str(), '.');
151
226
if (ext == NULL || my_strcasecmp(system_charset_info, ext, ARZ) ||
152
(filename->compare(0, strlen(TMP_FILE_PREFIX), TMP_FILE_PREFIX) == 0))
227
is_prefix(filename->c_str(), TMP_FILE_PREFIX))
254
error= my_errno= errno;
184
260
int ArchiveEngine::doGetTableDefinition(Session&,
185
TableIdentifier &identifier,
186
drizzled::message::Table &table_proto)
265
drizzled::message::Table *table_proto)
188
267
struct stat stat_info;
189
268
int error= ENOENT;
190
269
string proto_path;
192
271
proto_path.reserve(FN_REFLEN);
193
proto_path.assign(identifier.getPath());
272
proto_path.assign(path);
195
274
proto_path.append(ARZ);
307
static ArchiveEngine *archive_engine= NULL;
310
Initialize the archive Cursor.
321
static int archive_db_init(drizzled::plugin::Registry ®istry)
324
pthread_mutex_init(&archive_mutex, MY_MUTEX_INIT_FAST);
325
archive_engine= new ArchiveEngine("ARCHIVE");
326
registry.add(archive_engine);
328
/* When the engine starts up set the first version */
335
Release the archive Cursor.
345
static int archive_db_done(drizzled::plugin::Registry ®istry)
347
registry.remove(archive_engine);
348
delete archive_engine;
350
pthread_mutex_destroy(&archive_mutex);
228
356
ha_archive::ha_archive(drizzled::plugin::StorageEngine &engine_arg,
229
357
TableShare &table_arg)
265
393
memset(&archive_write, 0, sizeof(azio_stream)); /* Archive file we are working with */
266
394
table_name.append(name);
267
internal::fn_format(data_file_name, table_name.c_str(), "",
395
fn_format(data_file_name, table_name.c_str(), "",
268
396
ARZ, MY_REPLACE_EXT | MY_UNPACK_FILENAME);
270
398
We will use this lock for rows.
530
int ArchiveEngine::doCreateTable(Session &,
657
int ArchiveEngine::doCreateTable(Session *,
658
const char *table_name,
531
659
Table& table_arg,
532
drizzled::TableIdentifier &identifier,
533
660
drizzled::message::Table& proto)
535
662
char name_buff[FN_REFLEN];
562
689
We reuse name_buff since it is available.
564
internal::fn_format(name_buff, identifier.getPath().c_str(), "", ARZ,
565
MY_REPLACE_EXT | MY_UNPACK_FILENAME);
691
fn_format(name_buff, table_name, "", ARZ,
692
MY_REPLACE_EXT | MY_UNPACK_FILENAME);
568
695
if (azopen(&create_stream, name_buff, O_CREAT|O_RDWR,
569
696
AZ_METHOD_BLOCK) == 0)
969
1096
int ha_archive::rnd_pos(unsigned char * buf, unsigned char *pos)
971
ha_statistic_increment(&system_status_var::ha_read_rnd_next_count);
972
current_position= (internal::my_off_t)internal::my_get_ptr(pos, ref_length);
1098
ha_statistic_increment(&SSV::ha_read_rnd_next_count);
1099
current_position= (my_off_t)my_get_ptr(pos, ref_length);
973
1100
if (azseek(&archive, (size_t)current_position, SEEK_SET) == (size_t)(-1L))
974
1101
return(HA_ERR_CRASHED_ON_USAGE);
975
1102
return(get_row(&archive, buf));
1019
1146
azread_frm(&archive, proto_string);
1021
1148
/* Lets create a file to contain the new data */
1022
internal::fn_format(writer_filename, share->table_name.c_str(), "", ARN,
1149
fn_format(writer_filename, share->table_name.c_str(), "", ARN,
1023
1150
MY_REPLACE_EXT | MY_UNPACK_FILENAME);
1025
1152
if (!(azopen(&writer, writer_filename, O_CREAT|O_RDWR, AZ_METHOD_BLOCK)))
1325
int ArchiveEngine::doRenameTable(Session&, TableIdentifier &from, TableIdentifier &to)
1329
for (const char **ext= bas_ext(); *ext ; ext++)
1331
if (rename_file_ext(from.getPath().c_str(), to.getPath().c_str(), *ext))
1333
if ((error=errno) != ENOENT)
1342
bool ArchiveEngine::doDoesTableExist(Session&,
1343
TableIdentifier &identifier)
1345
string proto_path(identifier.getPath());
1346
proto_path.append(ARZ);
1348
if (access(proto_path.c_str(), F_OK))
1356
void ArchiveEngine::doGetTableIdentifiers(drizzled::CachedDirectory &directory,
1357
drizzled::SchemaIdentifier &schema_identifier,
1358
drizzled::TableIdentifiers &set_of_identifiers)
1360
drizzled::CachedDirectory::Entries entries= directory.getEntries();
1362
for (drizzled::CachedDirectory::Entries::iterator entry_iter= entries.begin();
1363
entry_iter != entries.end(); ++entry_iter)
1365
drizzled::CachedDirectory::Entry *entry= *entry_iter;
1366
const string *filename= &entry->filename;
1368
assert(filename->size());
1370
const char *ext= strchr(filename->c_str(), '.');
1372
if (ext == NULL || my_strcasecmp(system_charset_info, ext, ARZ) ||
1373
(filename->compare(0, strlen(TMP_FILE_PREFIX), TMP_FILE_PREFIX) == 0))
1377
char uname[NAME_LEN + 1];
1378
uint32_t file_name_len;
1380
file_name_len= filename_to_tablename(filename->c_str(), uname, sizeof(uname));
1381
// TODO: Remove need for memory copy here
1382
uname[file_name_len - sizeof(ARZ) + 1]= '\0'; // Subtract ending, place NULL
1384
set_of_identifiers.push_back(TableIdentifier(schema_identifier, uname));
1452
static DRIZZLE_SYSVAR_BOOL(aio, archive_use_aio,
1453
PLUGIN_VAR_NOCMDOPT,
1454
"Whether or not to use asynchronous IO.",
1457
static drizzle_sys_var* archive_system_variables[]= {
1458
DRIZZLE_SYSVAR(aio),
1462
DRIZZLE_DECLARE_PLUGIN
1466
"Brian Aker, MySQL AB",
1467
"Archive storage engine",
1469
archive_db_init, /* Plugin Init */
1470
archive_db_done, /* Plugin Deinit */
1471
NULL, /* status variables */
1472
archive_system_variables, /* system variables */
1473
NULL /* config options */
1475
DRIZZLE_DECLARE_PLUGIN_END;