~drizzle-trunk/drizzle/development

873.2.20 by Monty Taylor
Fixed 32-bit compile issue.
1
#include <drizzled/global.h>
671 by Brian Aker
Cleaned up events for writing in replication (using simple file
2
#include <sys/types.h>
3
#include <sys/stat.h>
4
#include <fcntl.h>
636 by Brian Aker
First pass with new event API (yeah... it will be better).
5
#include <iostream>
6
#include <fstream>
7
#include <string>
685.1.32 by Monty Taylor
Added missing header.
8
#include <unistd.h>
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
9
#include <drizzled/message/transaction.pb.h>
779.3.18 by Monty Taylor
Cleaned up warnings up through innodb.
10
636 by Brian Aker
First pass with new event API (yeah... it will be better).
11
using namespace std;
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
12
using namespace drizzled::message;
636 by Brian Aker
First pass with new event API (yeah... it will be better).
13
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
14
/**
15
 * @file Example application for reading change records and transactions
16
 */
17
1085.1.2 by Monty Taylor
Fixed -Wmissing-declarations
18
static void printInsert(const drizzled::message::Command &container, const drizzled::message::InsertRecord &record)
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
19
{
20
21
  cout << "INSERT INTO `" << container.schema() << "`.`" << container.table() << "` (";
22
23
  int32_t num_fields= record.insert_field_size();
24
25
  int32_t x;
26
  for (x= 0; x < num_fields; x++)
27
  {
28
    if (x != 0)
29
      cout << ", ";
30
31
    const Table::Field f= record.insert_field(x);
32
33
    cout << "`" << f.name() << "`";
34
  }
35
36
  cout << ") VALUES ";
37
38
  /* 
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.
42
   *
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.
47
   */
48
  int32_t num_records= (record.insert_value_size() / num_fields);
49
  int32_t y;
50
  for (x= 0; x < num_records; x++)
51
  {
52
    if (x != 0)
53
      cout << ", ";
54
55
    cout << "(";
56
    for (y= 0; y < num_fields; y++)
57
    {
58
      if (y != 0)
59
        cout << ", ";
60
61
      cout << "\"" << record.insert_value((x * num_fields) + y) << "\"";
62
    }
63
    cout << ")";
64
  }
65
66
  cout << ";";
67
}
68
1085.1.2 by Monty Taylor
Fixed -Wmissing-declarations
69
static void printDeleteWithPK(const drizzled::message::Command &container, const drizzled::message::DeleteRecord &record)
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
70
{
71
  cout << "DELETE FROM `" << container.schema() << "`.`" << container.table() << "`";
72
73
  int32_t num_where_fields= record.where_field_size();
74
  /* 
75
   * Make sure we catch anywhere we're not aligning the fields with
76
   * the field_values arrays...
77
   */
78
  assert(num_where_fields == record.where_value_size());
79
80
  cout << " WHERE ";
81
  int32_t x;
82
  for (x= 0; x < num_where_fields; x++)
83
  {
84
    if (x != 0)
85
      cout << " AND "; /* Always AND condition with a multi-column PK */
86
87
    const Table::Field f= record.where_field(x);
88
89
    /* Always equality conditions */
90
    cout << "`" << f.name() << "` = \"" << record.where_value(x) << "\"";
91
  }
92
}
93
1085.1.2 by Monty Taylor
Fixed -Wmissing-declarations
94
static void printUpdateWithPK(const drizzled::message::Command &container, const drizzled::message::UpdateRecord &record)
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
95
{
96
  int32_t num_update_fields= record.update_field_size();
97
  int32_t x;
98
99
  cout << "UPDATE `" << container.schema() << "`.`" << container.table() << "` SET ";
100
101
  for (x= 0;x < num_update_fields; x++)
102
  {
103
    Table::Field f= record.update_field(x);
104
    
105
    if (x != 0)
106
      cout << ", ";
107
108
    cout << "`" << f.name() << "` = \"" << record.after_value(x) << "\"";
109
  }
110
111
  int32_t num_where_fields= record.where_field_size();
112
  /* 
113
   * Make sure we catch anywhere we're not aligning the fields with
114
   * the field_values arrays...
115
   */
116
  assert(num_where_fields == record.where_value_size());
117
118
  cout << " WHERE ";
119
  for (x= 0;x < num_where_fields; x++)
120
  {
121
    if (x != 0)
122
      cout << " AND "; /* Always AND condition with a multi-column PK */
123
124
    const Table::Field f= record.where_field(x);
125
126
    /* Always equality conditions */
127
    cout << "`" << f.name() << "` = \"" << record.where_value(x) << "\"";
128
  }
129
}
130
1085.1.2 by Monty Taylor
Fixed -Wmissing-declarations
131
static void printTransaction(const drizzled::message::Transaction &transaction)
636 by Brian Aker
First pass with new event API (yeah... it will be better).
132
{
779.3.18 by Monty Taylor
Cleaned up warnings up through innodb.
133
  int32_t e_size;
636 by Brian Aker
First pass with new event API (yeah... it will be better).
134
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
135
  cout << "/* Start Time: " << transaction.start_timestamp() << " */ START TRANSACTION;"<< endl;
136
137
  for (e_size= 0; e_size < transaction.command_size(); e_size++)
636 by Brian Aker
First pass with new event API (yeah... it will be better).
138
  {
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
139
    const drizzled::message::Command command= transaction.command(e_size);
140
141
    drizzled::message::TransactionContext trx= command.transaction_context();
142
143
    cout << "/* SID: " << trx.server_id() << " XID: " << trx.transaction_id() << " */ ";
144
145
    switch (command.type())
636 by Brian Aker
First pass with new event API (yeah... it will be better).
146
    {
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
147
      case Command::START_TRANSACTION:
148
        cout << "START TRANSACTION;";
149
        break;
150
      case Command::COMMIT:
151
        cout << "COMMIT;";
152
        break;
153
      case Command::ROLLBACK:
154
        cout << "ROLLBACK;";
155
        break;
156
      case Command::INSERT:
157
      {
158
        printInsert(command, command.insert_record());
159
        break;
160
      }
161
      case Command::DELETE:
162
      {
163
        printDeleteWithPK(command, command.delete_record());
164
        break;
165
      }
166
      case Command::UPDATE:
167
      {
168
        printUpdateWithPK(command, command.update_record());
169
        break;
170
      }
171
      default:
172
      assert(0);
636 by Brian Aker
First pass with new event API (yeah... it will be better).
173
    }
174
    cout << endl;
175
  }
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
176
  cout << "/* Commit Time: " << transaction.end_timestamp() << " */ COMMIT;" << endl;
636 by Brian Aker
First pass with new event API (yeah... it will be better).
177
}
178
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
179
int main(int argc, char* argv[])
636 by Brian Aker
First pass with new event API (yeah... it will be better).
180
{
181
  GOOGLE_PROTOBUF_VERIFY_VERSION;
671 by Brian Aker
Cleaned up events for writing in replication (using simple file
182
  int file;
636 by Brian Aker
First pass with new event API (yeah... it will be better).
183
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
184
  if (argc != 2)
636 by Brian Aker
First pass with new event API (yeah... it will be better).
185
  {
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
186
    cerr << "Usage:  " << argv[0] << " TRANSACTION_LOG" << endl;
636 by Brian Aker
First pass with new event API (yeah... it will be better).
187
    return -1;
188
  }
189
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
190
  Transaction transaction;
636 by Brian Aker
First pass with new event API (yeah... it will be better).
191
671 by Brian Aker
Cleaned up events for writing in replication (using simple file
192
  if ((file= open(argv[1], O_RDONLY)) == -1)
193
  {
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
194
    cerr << "Can not open file: " << argv[1] << endl;
671 by Brian Aker
Cleaned up events for writing in replication (using simple file
195
  }
196
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
197
  char *buffer= NULL;
198
  char *temp_buffer;
199
671 by Brian Aker
Cleaned up events for writing in replication (using simple file
200
  while (1)
201
  {
873.2.20 by Monty Taylor
Fixed 32-bit compile issue.
202
    uint64_t length;
671 by Brian Aker
Cleaned up events for writing in replication (using simple file
203
204
    /* Read the size */
205
    if (read(file, &length, sizeof(uint64_t)) != sizeof(uint64_t))
206
      break;
207
873.2.20 by Monty Taylor
Fixed 32-bit compile issue.
208
    if (length > SIZE_MAX)
209
    {
210
      cerr << "Attempted to read record bigger than SIZE_MAX" << endl;
211
      exit(1);
212
    }
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
213
873.2.20 by Monty Taylor
Fixed 32-bit compile issue.
214
    temp_buffer= (char *)realloc(buffer, (size_t)length);
671 by Brian Aker
Cleaned up events for writing in replication (using simple file
215
    if (temp_buffer == NULL)
216
    {
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
217
      cerr << "Memory allocation failure trying to allocate " << length << " bytes."  << endl;
671 by Brian Aker
Cleaned up events for writing in replication (using simple file
218
      exit(1);
219
    }
994.1.1 by Trond Norbye
memset and read specify the length as size_t, not uint64_t
220
    memset(temp_buffer, 0, (size_t)length);
671 by Brian Aker
Cleaned up events for writing in replication (using simple file
221
    buffer= temp_buffer;
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
222
    size_t read_bytes= 0;
671 by Brian Aker
Cleaned up events for writing in replication (using simple file
223
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
224
    /* Read the transaction */
994.1.1 by Trond Norbye
memset and read specify the length as size_t, not uint64_t
225
    if ((read_bytes= read(file, buffer, (size_t)length)) != (size_t)length)
671 by Brian Aker
Cleaned up events for writing in replication (using simple file
226
    {
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
227
      cerr << "Could not read entire transaction. Read " << read_bytes << " bytes instead of " << length << " bytes." << endl;
671 by Brian Aker
Cleaned up events for writing in replication (using simple file
228
      exit(1);
229
    }
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
230
    transaction.ParseFromArray(buffer, (int) length);
671 by Brian Aker
Cleaned up events for writing in replication (using simple file
231
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
232
    /* Print the transaction */
233
    printTransaction(transaction);
671 by Brian Aker
Cleaned up events for writing in replication (using simple file
234
  }
636 by Brian Aker
First pass with new event API (yeah... it will be better).
235
  return 0;
236
}