1
#include <drizzled/global.h>
9
#include <drizzled/message/transaction.pb.h>
12
using namespace drizzled::message;
15
* @file Example application for reading change records and transactions
18
void printInsert(const drizzled::message::Command &container, const drizzled::message::InsertRecord &record)
21
cout << "INSERT INTO `" << container.schema() << "`.`" << container.table() << "` (";
23
int32_t num_fields= record.insert_field_size();
26
for (x= 0; x < num_fields; x++)
31
const Table::Field f= record.insert_field(x);
33
cout << "`" << f.name() << "`";
39
* There may be an INSERT VALUES (),() type statement. We know the
40
* number of records is equal to the field_values array size divided
41
* by the number of fields.
43
* So, we do an inner and an outer loop. Outer loop is on the number
44
* of records and the inner loop on the number of fields. In this way,
45
* we know that record.field_values(outer_loop * num_fields) + inner_loop))
46
* always gives us our correct field value.
48
int32_t num_records= (record.insert_value_size() / num_fields);
50
for (x= 0; x < num_records; x++)
56
for (y= 0; y < num_fields; y++)
61
cout << "\"" << record.insert_value((x * num_fields) + y) << "\"";
69
void printDeleteWithPK(const drizzled::message::Command &container, const drizzled::message::DeleteRecord &record)
71
cout << "DELETE FROM `" << container.schema() << "`.`" << container.table() << "`";
73
int32_t num_where_fields= record.where_field_size();
75
* Make sure we catch anywhere we're not aligning the fields with
76
* the field_values arrays...
78
assert(num_where_fields == record.where_value_size());
82
for (x= 0; x < num_where_fields; x++)
85
cout << " AND "; /* Always AND condition with a multi-column PK */
87
const Table::Field f= record.where_field(x);
89
/* Always equality conditions */
90
cout << "`" << f.name() << "` = \"" << record.where_value(x) << "\"";
94
void printUpdateWithPK(const drizzled::message::Command &container, const drizzled::message::UpdateRecord &record)
96
int32_t num_update_fields= record.update_field_size();
99
cout << "UPDATE `" << container.schema() << "`.`" << container.table() << "` SET ";
101
for (x= 0;x < num_update_fields; x++)
103
Table::Field f= record.update_field(x);
108
cout << "`" << f.name() << "` = \"" << record.after_value(x) << "\"";
111
int32_t num_where_fields= record.where_field_size();
113
* Make sure we catch anywhere we're not aligning the fields with
114
* the field_values arrays...
116
assert(num_where_fields == record.where_value_size());
119
for (x= 0;x < num_where_fields; x++)
122
cout << " AND "; /* Always AND condition with a multi-column PK */
124
const Table::Field f= record.where_field(x);
126
/* Always equality conditions */
127
cout << "`" << f.name() << "` = \"" << record.where_value(x) << "\"";
131
void printTransaction(const drizzled::message::Transaction &transaction)
135
cout << "/* Start Time: " << transaction.start_timestamp() << " */ START TRANSACTION;"<< endl;
137
for (e_size= 0; e_size < transaction.command_size(); e_size++)
139
const drizzled::message::Command command= transaction.command(e_size);
141
drizzled::message::TransactionContext trx= command.transaction_context();
143
cout << "/* SID: " << trx.server_id() << " XID: " << trx.transaction_id() << " */ ";
145
switch (command.type())
147
case Command::START_TRANSACTION:
148
cout << "START TRANSACTION;";
150
case Command::COMMIT:
153
case Command::ROLLBACK:
156
case Command::INSERT:
158
printInsert(command, command.insert_record());
161
case Command::DELETE:
163
printDeleteWithPK(command, command.delete_record());
166
case Command::UPDATE:
168
printUpdateWithPK(command, command.update_record());
176
cout << "/* Commit Time: " << transaction.end_timestamp() << " */ COMMIT;" << endl;
179
int main(int argc, char* argv[])
181
GOOGLE_PROTOBUF_VERIFY_VERSION;
186
cerr << "Usage: " << argv[0] << " TRANSACTION_LOG" << endl;
190
Transaction transaction;
192
if ((file= open(argv[1], O_RDONLY)) == -1)
194
cerr << "Can not open file: " << argv[1] << endl;
205
if (read(file, &length, sizeof(uint64_t)) != sizeof(uint64_t))
208
if (length > SIZE_MAX)
210
cerr << "Attempted to read record bigger than SIZE_MAX" << endl;
214
temp_buffer= (char *)realloc(buffer, (size_t)length);
215
if (temp_buffer == NULL)
217
cerr << "Memory allocation failure trying to allocate " << length << " bytes." << endl;
220
memset(temp_buffer, 0, length);
222
size_t read_bytes= 0;
224
/* Read the transaction */
225
if ((read_bytes= read(file, buffer, (uint64_t)length)) != (uint64_t)length)
227
cerr << "Could not read entire transaction. Read " << read_bytes << " bytes instead of " << length << " bytes." << endl;
230
transaction.ParseFromArray(buffer, (int) length);
232
/* Print the transaction */
233
printTransaction(transaction);