~drizzle-trunk/drizzle/development

1122.2.2 by Monty Taylor
Added missing copyright headers. Added drizzled/global.h to a few things that
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 *
4
 *  Copyright (C) 2009 Sun Microsystems
5
 *
6
 *  This program is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; version 2 of the License.
9
 *
10
 *  This program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *  GNU General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU General Public License
16
 *  along with this program; if not, write to the Free Software
17
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
 */
19
873.2.20 by Monty Taylor
Fixed 32-bit compile issue.
20
#include <drizzled/global.h>
671 by Brian Aker
Cleaned up events for writing in replication (using simple file
21
#include <sys/types.h>
22
#include <sys/stat.h>
23
#include <fcntl.h>
636 by Brian Aker
First pass with new event API (yeah... it will be better).
24
#include <iostream>
25
#include <fstream>
26
#include <string>
685.1.32 by Monty Taylor
Added missing header.
27
#include <unistd.h>
1039.5.31 by Jay Pipes
This patch does a few things:
28
#include <drizzled/message/replication.pb.h>
779.3.18 by Monty Taylor
Cleaned up warnings up through innodb.
29
636 by Brian Aker
First pass with new event API (yeah... it will be better).
30
using namespace std;
1101.2.1 by Monty Taylor
Fixed the first set of using namespace
31
using namespace drizzled;
636 by Brian Aker
First pass with new event API (yeah... it will be better).
32
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
33
/**
34
 * @file Example application for reading change records and transactions
35
 */
36
1101.2.1 by Monty Taylor
Fixed the first set of using namespace
37
static void printInsert(const message::Command &container,
38
                        const message::InsertRecord &record)
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
39
{
40
1101.2.1 by Monty Taylor
Fixed the first set of using namespace
41
  cout << "INSERT INTO `" << container.schema() << "`.`"
42
       << container.table() << "` (";
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
43
44
  int32_t num_fields= record.insert_field_size();
45
46
  int32_t x;
47
  for (x= 0; x < num_fields; x++)
48
  {
49
    if (x != 0)
50
      cout << ", ";
51
1101.2.1 by Monty Taylor
Fixed the first set of using namespace
52
    const message::Table::Field f= record.insert_field(x);
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
53
54
    cout << "`" << f.name() << "`";
55
  }
56
57
  cout << ") VALUES ";
58
59
  /* 
60
   * There may be an INSERT VALUES (),() type statement.  We know the
61
   * number of records is equal to the field_values array size divided
62
   * by the number of fields.
63
   *
64
   * So, we do an inner and an outer loop.  Outer loop is on the number
65
   * of records and the inner loop on the number of fields.  In this way, 
66
   * we know that record.field_values(outer_loop * num_fields) + inner_loop))
67
   * always gives us our correct field value.
68
   */
69
  int32_t num_records= (record.insert_value_size() / num_fields);
70
  int32_t y;
71
  for (x= 0; x < num_records; x++)
72
  {
73
    if (x != 0)
74
      cout << ", ";
75
76
    cout << "(";
77
    for (y= 0; y < num_fields; y++)
78
    {
79
      if (y != 0)
80
        cout << ", ";
81
82
      cout << "\"" << record.insert_value((x * num_fields) + y) << "\"";
83
    }
84
    cout << ")";
85
  }
86
87
  cout << ";";
88
}
89
1101.2.1 by Monty Taylor
Fixed the first set of using namespace
90
static void printDeleteWithPK(const message::Command &container,
91
                              const message::DeleteRecord &record)
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
92
{
93
  cout << "DELETE FROM `" << container.schema() << "`.`" << container.table() << "`";
94
95
  int32_t num_where_fields= record.where_field_size();
96
  /* 
97
   * Make sure we catch anywhere we're not aligning the fields with
98
   * the field_values arrays...
99
   */
100
  assert(num_where_fields == record.where_value_size());
101
102
  cout << " WHERE ";
103
  int32_t x;
104
  for (x= 0; x < num_where_fields; x++)
105
  {
106
    if (x != 0)
107
      cout << " AND "; /* Always AND condition with a multi-column PK */
108
1101.2.1 by Monty Taylor
Fixed the first set of using namespace
109
    const message::Table::Field f= record.where_field(x);
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
110
111
    /* Always equality conditions */
112
    cout << "`" << f.name() << "` = \"" << record.where_value(x) << "\"";
113
  }
114
}
115
1101.2.1 by Monty Taylor
Fixed the first set of using namespace
116
static void printUpdateWithPK(const message::Command &container,
117
                              const message::UpdateRecord &record)
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
118
{
119
  int32_t num_update_fields= record.update_field_size();
120
  int32_t x;
121
122
  cout << "UPDATE `" << container.schema() << "`.`" << container.table() << "` SET ";
123
124
  for (x= 0;x < num_update_fields; x++)
125
  {
1101.2.1 by Monty Taylor
Fixed the first set of using namespace
126
    message::Table::Field f= record.update_field(x);
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
127
    
128
    if (x != 0)
129
      cout << ", ";
130
131
    cout << "`" << f.name() << "` = \"" << record.after_value(x) << "\"";
132
  }
133
134
  int32_t num_where_fields= record.where_field_size();
135
  /* 
136
   * Make sure we catch anywhere we're not aligning the fields with
137
   * the field_values arrays...
138
   */
139
  assert(num_where_fields == record.where_value_size());
140
141
  cout << " WHERE ";
142
  for (x= 0;x < num_where_fields; x++)
143
  {
144
    if (x != 0)
145
      cout << " AND "; /* Always AND condition with a multi-column PK */
146
1101.2.1 by Monty Taylor
Fixed the first set of using namespace
147
    const message::Table::Field f= record.where_field(x);
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
148
149
    /* Always equality conditions */
150
    cout << "`" << f.name() << "` = \"" << record.where_value(x) << "\"";
151
  }
152
}
153
1101.2.1 by Monty Taylor
Fixed the first set of using namespace
154
static void printTransaction(const message::Transaction &transaction)
636 by Brian Aker
First pass with new event API (yeah... it will be better).
155
{
779.3.18 by Monty Taylor
Cleaned up warnings up through innodb.
156
  int32_t e_size;
636 by Brian Aker
First pass with new event API (yeah... it will be better).
157
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
158
  cout << "/* Start Time: " << transaction.start_timestamp() << " */ START TRANSACTION;"<< endl;
159
160
  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).
161
  {
1101.2.1 by Monty Taylor
Fixed the first set of using namespace
162
    const message::Command command= transaction.command(e_size);
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
163
1101.2.1 by Monty Taylor
Fixed the first set of using namespace
164
    message::TransactionContext trx= command.transaction_context();
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
165
166
    cout << "/* SID: " << trx.server_id() << " XID: " << trx.transaction_id() << " */ ";
167
168
    switch (command.type())
636 by Brian Aker
First pass with new event API (yeah... it will be better).
169
    {
1101.2.1 by Monty Taylor
Fixed the first set of using namespace
170
      case message::Command::START_TRANSACTION:
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
171
        cout << "START TRANSACTION;";
172
        break;
1101.2.1 by Monty Taylor
Fixed the first set of using namespace
173
      case message::Command::COMMIT:
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
174
        cout << "COMMIT;";
175
        break;
1101.2.1 by Monty Taylor
Fixed the first set of using namespace
176
      case message::Command::ROLLBACK:
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
177
        cout << "ROLLBACK;";
178
        break;
1101.2.1 by Monty Taylor
Fixed the first set of using namespace
179
      case message::Command::INSERT:
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
180
      {
181
        printInsert(command, command.insert_record());
182
        break;
183
      }
1101.2.1 by Monty Taylor
Fixed the first set of using namespace
184
      case message::Command::DELETE:
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
185
      {
186
        printDeleteWithPK(command, command.delete_record());
187
        break;
188
      }
1101.2.1 by Monty Taylor
Fixed the first set of using namespace
189
      case message::Command::UPDATE:
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
190
      {
191
        printUpdateWithPK(command, command.update_record());
192
        break;
193
      }
194
      default:
195
      assert(0);
636 by Brian Aker
First pass with new event API (yeah... it will be better).
196
    }
197
    cout << endl;
198
  }
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
199
  cout << "/* Commit Time: " << transaction.end_timestamp() << " */ COMMIT;" << endl;
636 by Brian Aker
First pass with new event API (yeah... it will be better).
200
}
201
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
202
int main(int argc, char* argv[])
636 by Brian Aker
First pass with new event API (yeah... it will be better).
203
{
204
  GOOGLE_PROTOBUF_VERIFY_VERSION;
671 by Brian Aker
Cleaned up events for writing in replication (using simple file
205
  int file;
636 by Brian Aker
First pass with new event API (yeah... it will be better).
206
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
207
  if (argc != 2)
636 by Brian Aker
First pass with new event API (yeah... it will be better).
208
  {
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
209
    cerr << "Usage:  " << argv[0] << " TRANSACTION_LOG" << endl;
636 by Brian Aker
First pass with new event API (yeah... it will be better).
210
    return -1;
211
  }
212
1101.2.1 by Monty Taylor
Fixed the first set of using namespace
213
  message::Transaction transaction;
636 by Brian Aker
First pass with new event API (yeah... it will be better).
214
671 by Brian Aker
Cleaned up events for writing in replication (using simple file
215
  if ((file= open(argv[1], O_RDONLY)) == -1)
216
  {
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
217
    cerr << "Can not open file: " << argv[1] << endl;
671 by Brian Aker
Cleaned up events for writing in replication (using simple file
218
  }
219
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
220
  char *buffer= NULL;
221
  char *temp_buffer;
222
671 by Brian Aker
Cleaned up events for writing in replication (using simple file
223
  while (1)
224
  {
873.2.20 by Monty Taylor
Fixed 32-bit compile issue.
225
    uint64_t length;
671 by Brian Aker
Cleaned up events for writing in replication (using simple file
226
227
    /* Read the size */
228
    if (read(file, &length, sizeof(uint64_t)) != sizeof(uint64_t))
229
      break;
230
873.2.20 by Monty Taylor
Fixed 32-bit compile issue.
231
    if (length > SIZE_MAX)
232
    {
233
      cerr << "Attempted to read record bigger than SIZE_MAX" << endl;
234
      exit(1);
235
    }
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
236
873.2.20 by Monty Taylor
Fixed 32-bit compile issue.
237
    temp_buffer= (char *)realloc(buffer, (size_t)length);
671 by Brian Aker
Cleaned up events for writing in replication (using simple file
238
    if (temp_buffer == NULL)
239
    {
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
240
      cerr << "Memory allocation failure trying to allocate " << length << " bytes."  << endl;
671 by Brian Aker
Cleaned up events for writing in replication (using simple file
241
      exit(1);
242
    }
994.1.1 by Trond Norbye
memset and read specify the length as size_t, not uint64_t
243
    memset(temp_buffer, 0, (size_t)length);
671 by Brian Aker
Cleaned up events for writing in replication (using simple file
244
    buffer= temp_buffer;
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
245
    size_t read_bytes= 0;
671 by Brian Aker
Cleaned up events for writing in replication (using simple file
246
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
247
    /* Read the transaction */
994.1.1 by Trond Norbye
memset and read specify the length as size_t, not uint64_t
248
    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
249
    {
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
250
      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
251
      exit(1);
252
    }
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
253
    transaction.ParseFromArray(buffer, (int) length);
671 by Brian Aker
Cleaned up events for writing in replication (using simple file
254
988.1.5 by Jay Pipes
Removal of log.cc (binlog), added Applier plugin and fixed up Replicator
255
    /* Print the transaction */
256
    printTransaction(transaction);
671 by Brian Aker
Cleaned up events for writing in replication (using simple file
257
  }
636 by Brian Aker
First pass with new event API (yeah... it will be better).
258
  return 0;
259
}