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;
34
static const string engine_name("ARCHIVE");
27
37
First, if you want to understand storage engines you should look at
94
104
/* Variables for archive share methods */
95
105
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);
107
static unsigned int global_version;
109
/* The file extension */
110
#define ARZ ".arz" // The data file
111
#define ARN ".ARN" // Files used during an optimize call
115
static bool archive_use_aio= false;
104
118
Number of rows that will force a bulk insert.
111
125
#define ARCHIVE_ROW_HEADER_SIZE 4
128
We just implement one additional file extension.
130
static const char *ha_archive_exts[] = {
135
class ArchiveEngine : public drizzled::plugin::StorageEngine
137
typedef std::map<string, ArchiveShare*> ArchiveMap;
138
ArchiveMap archive_open_tables;
141
ArchiveEngine(const string &name_arg)
142
: drizzled::plugin::StorageEngine(name_arg,
144
HTON_STATS_RECORDS_IS_EXACT |
146
HTON_HAS_DATA_DICTIONARY)
148
table_definition_ext= ARZ;
151
virtual Cursor *create(TableShare &table,
154
return new (mem_root) ha_archive(*this, table);
157
const char **bas_ext() const {
158
return ha_archive_exts;
161
int doCreateTable(Session *session, const char *table_name,
163
drizzled::message::Table& proto);
165
int doGetTableDefinition(Session& session,
168
const char *table_name,
170
drizzled::message::Table *table_proto);
172
void doGetTableNames(CachedDirectory &directory, string& , set<string>& set_of_names);
174
int doDropTable(Session&, const string table_path);
175
ArchiveShare *findOpenTable(const string table_name);
176
void addOpenTable(const string &table_name, ArchiveShare *);
177
void deleteOpenTable(const string &table_name);
179
uint32_t max_supported_keys() const { return 1; }
180
uint32_t max_supported_key_length() const { return sizeof(uint64_t); }
181
uint32_t max_supported_key_part_length() const { return sizeof(uint64_t); }
113
185
ArchiveShare *ArchiveEngine::findOpenTable(const string table_name)
115
187
ArchiveMap::iterator find_iter=
135
void ArchiveEngine::doGetTableNames(drizzled::CachedDirectory &directory,
207
void ArchiveEngine::doGetTableNames(CachedDirectory &directory,
137
209
set<string>& set_of_names)
139
drizzled::CachedDirectory::Entries entries= directory.getEntries();
211
CachedDirectory::Entries entries= directory.getEntries();
141
for (drizzled::CachedDirectory::Entries::iterator entry_iter= entries.begin();
213
for (CachedDirectory::Entries::iterator entry_iter= entries.begin();
142
214
entry_iter != entries.end(); ++entry_iter)
144
drizzled::CachedDirectory::Entry *entry= *entry_iter;
145
const string *filename= &entry->filename;
216
CachedDirectory::Entry *entry= *entry_iter;
217
string *filename= &entry->filename;
147
219
assert(filename->size());
149
221
const char *ext= strchr(filename->c_str(), '.');
151
223
if (ext == NULL || my_strcasecmp(system_charset_info, ext, ARZ) ||
152
(filename->compare(0, strlen(TMP_FILE_PREFIX), TMP_FILE_PREFIX) == 0))
224
is_prefix(filename->c_str(), TMP_FILE_PREFIX))
251
error= my_errno= errno;
184
257
int ArchiveEngine::doGetTableDefinition(Session&,
185
TableIdentifier &identifier,
186
drizzled::message::Table &table_proto)
262
drizzled::message::Table *table_proto)
188
264
struct stat stat_info;
189
265
int error= ENOENT;
190
266
string proto_path;
192
268
proto_path.reserve(FN_REFLEN);
193
proto_path.assign(identifier.getPath());
269
proto_path.assign(path);
195
271
proto_path.append(ARZ);
304
static ArchiveEngine *archive_engine= NULL;
307
Initialize the archive Cursor.
318
static int archive_db_init(drizzled::plugin::Registry ®istry)
321
pthread_mutex_init(&archive_mutex, MY_MUTEX_INIT_FAST);
322
archive_engine= new ArchiveEngine(engine_name);
323
registry.add(archive_engine);
325
/* When the engine starts up set the first version */
332
Release the archive Cursor.
342
static int archive_db_done(drizzled::plugin::Registry ®istry)
344
registry.remove(archive_engine);
345
delete archive_engine;
347
pthread_mutex_destroy(&archive_mutex);
228
353
ha_archive::ha_archive(drizzled::plugin::StorageEngine &engine_arg,
229
354
TableShare &table_arg)
265
390
memset(&archive_write, 0, sizeof(azio_stream)); /* Archive file we are working with */
266
391
table_name.append(name);
267
internal::fn_format(data_file_name, table_name.c_str(), "",
392
fn_format(data_file_name, table_name.c_str(), "",
268
393
ARZ, MY_REPLACE_EXT | MY_UNPACK_FILENAME);
270
395
We will use this lock for rows.
530
int ArchiveEngine::doCreateTable(Session &,
654
int ArchiveEngine::doCreateTable(Session *,
655
const char *table_name,
531
656
Table& table_arg,
532
drizzled::TableIdentifier &identifier,
533
657
drizzled::message::Table& proto)
535
659
char name_buff[FN_REFLEN];
562
686
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);
688
fn_format(name_buff, table_name, "", ARZ,
689
MY_REPLACE_EXT | MY_UNPACK_FILENAME);
568
692
if (azopen(&create_stream, name_buff, O_CREAT|O_RDWR,
569
693
AZ_METHOD_BLOCK) == 0)
969
1093
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);
1095
ha_statistic_increment(&SSV::ha_read_rnd_next_count);
1096
current_position= (my_off_t)my_get_ptr(pos, ref_length);
973
1097
if (azseek(&archive, (size_t)current_position, SEEK_SET) == (size_t)(-1L))
974
1098
return(HA_ERR_CRASHED_ON_USAGE);
975
1099
return(get_row(&archive, buf));
1019
1143
azread_frm(&archive, proto_string);
1021
1145
/* Lets create a file to contain the new data */
1022
internal::fn_format(writer_filename, share->table_name.c_str(), "", ARN,
1146
fn_format(writer_filename, share->table_name.c_str(), "", ARN,
1023
1147
MY_REPLACE_EXT | MY_UNPACK_FILENAME);
1025
1149
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));
1449
static DRIZZLE_SYSVAR_BOOL(aio, archive_use_aio,
1450
PLUGIN_VAR_NOCMDOPT,
1451
"Whether or not to use asynchronous IO.",
1454
static struct st_mysql_sys_var* archive_system_variables[]= {
1455
DRIZZLE_SYSVAR(aio),
1459
drizzle_declare_plugin
1463
"Brian Aker, MySQL AB",
1464
"Archive storage engine",
1466
archive_db_init, /* Plugin Init */
1467
archive_db_done, /* Plugin Deinit */
1468
NULL, /* status variables */
1469
archive_system_variables, /* system variables */
1470
NULL /* config options */
1472
drizzle_declare_plugin_end;