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 (Command messages)
19
* This program is used in the serial_event_log test suite to verify
20
* the log written by that plugin.
23
void printInsert(const drizzled::message::Command &container, const drizzled::message::InsertRecord &record)
26
cout << "INSERT INTO `" << container.schema() << "`.`" << container.table() << "` (";
28
int32_t num_fields= record.insert_field_size();
31
for (x= 0; x < num_fields; x++)
36
const Table::Field f= record.insert_field(x);
38
cout << "`" << f.name() << "`";
44
* There may be an INSERT VALUES (),() type statement. We know the
45
* number of records is equal to the field_values array size divided
46
* by the number of fields.
48
* So, we do an inner and an outer loop. Outer loop is on the number
49
* of records and the inner loop on the number of fields. In this way,
50
* we know that record.field_values(outer_loop * num_fields) + inner_loop))
51
* always gives us our correct field value.
53
int32_t num_records= (record.insert_value_size() / num_fields);
55
for (x= 0; x < num_records; x++)
61
for (y= 0; y < num_fields; y++)
66
cout << "\"" << record.insert_value((x * num_fields) + y) << "\"";
74
void printDeleteWithPK(const drizzled::message::Command &container, const drizzled::message::DeleteRecord &record)
76
cout << "DELETE FROM `" << container.schema() << "`.`" << container.table() << "`";
78
int32_t num_where_fields= record.where_field_size();
80
* Make sure we catch anywhere we're not aligning the fields with
81
* the field_values arrays...
83
assert(num_where_fields == record.where_value_size());
87
for (x= 0; x < num_where_fields; x++)
90
cout << " AND "; /* Always AND condition with a multi-column PK */
92
const Table::Field f= record.where_field(x);
94
/* Always equality conditions */
95
cout << "`" << f.name() << "` = \"" << record.where_value(x) << "\"";
99
void printUpdateWithPK(const drizzled::message::Command &container, const drizzled::message::UpdateRecord &record)
101
int32_t num_update_fields= record.update_field_size();
104
cout << "UPDATE `" << container.schema() << "`.`" << container.table() << "` SET ";
106
for (x= 0;x < num_update_fields; x++)
108
Table::Field f= record.update_field(x);
113
cout << "`" << f.name() << "` = \"" << record.after_value(x) << "\"";
116
int32_t num_where_fields= record.where_field_size();
118
* Make sure we catch anywhere we're not aligning the fields with
119
* the field_values arrays...
121
assert(num_where_fields == record.where_value_size());
124
for (x= 0;x < num_where_fields; x++)
127
cout << " AND "; /* Always AND condition with a multi-column PK */
129
const Table::Field f= record.where_field(x);
131
/* Always equality conditions */
132
cout << "`" << f.name() << "` = \"" << record.where_value(x) << "\"";
136
void printCommand(const drizzled::message::Command &command)
138
cout << "/* Timestamp: " << command.timestamp() << " */"<< endl;
140
drizzled::message::TransactionContext trx= command.transaction_context();
142
cout << "/* SID: " << trx.server_id() << " XID: " << trx.transaction_id() << " */ ";
144
switch (command.type())
146
case Command::START_TRANSACTION:
147
cout << "START TRANSACTION;";
149
case Command::COMMIT:
152
case Command::ROLLBACK:
155
case Command::INSERT:
157
printInsert(command, command.insert_record());
160
case Command::DELETE:
162
printDeleteWithPK(command, command.delete_record());
165
case Command::UPDATE:
167
printUpdateWithPK(command, command.update_record());
170
case Command::RAW_SQL:
172
std::string sql= command.sql();
173
/* Replace \n with spaces */
174
const std::string newline= "\n";
175
while (sql.find(newline) != std::string::npos)
176
sql.replace(sql.find(newline), 1, " ");
182
cout << "Received an unknown Command type: " << (int32_t) command.type();
187
int main(int argc, char* argv[])
189
GOOGLE_PROTOBUF_VERIFY_VERSION;
194
cerr << "Usage: " << argv[0] << " TRANSACTION_LOG" << endl;
200
if ((file= open(argv[1], O_RDONLY)) == -1)
202
cerr << "Can not open file: " << argv[1] << endl;
213
if (read(file, &length, sizeof(uint64_t)) != sizeof(uint64_t))
216
if (length > SIZE_MAX)
218
cerr << "Attempted to read record bigger than SIZE_MAX" << endl;
222
temp_buffer= (char *)realloc(buffer, (size_t)length);
223
if (temp_buffer == NULL)
225
cerr << "Memory allocation failure trying to allocate " << length << " bytes." << endl;
228
memset(temp_buffer, 0, (size_t)length);
230
size_t read_bytes= 0;
232
/* Read the transaction */
233
if ((read_bytes= read(file, buffer, (size_t)length)) != (size_t)length)
235
cerr << "Could not read entire transaction. Read " << read_bytes << " bytes instead of " << length << " bytes." << endl;
238
command.ParseFromArray(buffer, (int) length);
240
/* Print the command */
241
printCommand(command);