~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/message/command_reader.cc

Merging command2sql library work.

Show diffs side-by-side

added added

removed removed

Lines of Context:
10
10
#include <cstdio>
11
11
#include <drizzled/message/replication.pb.h>
12
12
 
 
13
#include "drizzled/message/command_transform.h"
 
14
 
13
15
#include "drizzled/korr.h"
14
16
 
15
17
using namespace std;
16
18
using namespace drizzled;
17
19
 
18
 
/**
19
 
 * @file Example application for reading change records (Command messages)
20
 
 *
21
 
 * @note
22
 
 *
23
 
 * This program is used in the serial_event_log test suite to verify
24
 
 * the log written by that plugin.
25
 
 */
26
 
 
27
 
static void printInsert(const message::Command &container,
28
 
                        const message::InsertRecord &record)
29
 
{
30
 
 
31
 
  cout << "INSERT INTO `" << container.schema() << "`.`" << container.table() << "` (";
32
 
  
33
 
  assert(record.insert_field_size() > 0);
34
 
  assert(record.insert_value_size() > 0);
35
 
  assert(record.insert_value_size() % record.insert_field_size() == 0);
36
 
 
37
 
  int32_t num_fields= record.insert_field_size();
38
 
 
39
 
  int32_t x;
40
 
  for (x= 0; x < num_fields; x++)
41
 
  {
42
 
    if (x != 0)
43
 
      cout << ", ";
44
 
 
45
 
    const message::Table::Field f= record.insert_field(x);
46
 
 
47
 
    cout << "`" << f.name() << "`";
48
 
  }
49
 
 
50
 
  cout << ") VALUES ";
51
 
 
52
 
  /* 
53
 
   * There may be an INSERT VALUES (),() type statement.  We know the
54
 
   * number of records is equal to the field_values array size divided
55
 
   * by the number of fields.
56
 
   *
57
 
   * So, we do an inner and an outer loop.  Outer loop is on the number
58
 
   * of records and the inner loop on the number of fields.  In this way, 
59
 
   * we know that record.field_values(outer_loop * num_fields) + inner_loop))
60
 
   * always gives us our correct field value.
61
 
   */
62
 
  int32_t num_records= (record.insert_value_size() / num_fields);
63
 
  int32_t y;
64
 
  for (x= 0; x < num_records; x++)
65
 
  {
66
 
    if (x != 0)
67
 
      cout << ", ";
68
 
 
69
 
    cout << "(";
70
 
    for (y= 0; y < num_fields; y++)
71
 
    {
72
 
      if (y != 0)
73
 
        cout << ", ";
74
 
 
75
 
      cout << "\"" << record.insert_value((x * num_fields) + y) << "\"";
76
 
    }
77
 
    cout << ")";
78
 
  }
79
 
 
80
 
  cout << ";";
81
 
}
82
 
 
83
 
static void printDeleteWithPK(const message::Command &container,
84
 
                              const message::DeleteRecord &record)
85
 
{
86
 
  cout << "DELETE FROM `" << container.schema() << "`.`" << container.table() << "`";
87
 
  
88
 
  assert(record.where_field_size() > 0);
89
 
  assert(record.where_value_size() == record.where_field_size());
90
 
 
91
 
  int32_t num_where_fields= record.where_field_size();
92
 
  /* 
93
 
   * Make sure we catch anywhere we're not aligning the fields with
94
 
   * the field_values arrays...
95
 
   */
96
 
  assert(num_where_fields == record.where_value_size());
97
 
 
98
 
  cout << " WHERE ";
99
 
  int32_t x;
100
 
  for (x= 0; x < num_where_fields; x++)
101
 
  {
102
 
    if (x != 0)
103
 
      cout << " AND "; /* Always AND condition with a multi-column PK */
104
 
 
105
 
    const message::Table::Field f= record.where_field(x);
106
 
 
107
 
    /* Always equality conditions */
108
 
    cout << "`" << f.name() << "` = \"" << record.where_value(x) << "\"";
109
 
  }
110
 
 
111
 
  cout << ";";
112
 
}
113
 
 
114
 
static void printUpdateWithPK(const message::Command &container,
115
 
                              const message::UpdateRecord &record)
116
 
{
117
 
  int32_t num_update_fields= record.update_field_size();
118
 
  int32_t x;
119
 
  
120
 
  assert(record.update_field_size() > 0);
121
 
  assert(record.where_field_size() > 0);
122
 
  assert(record.where_value_size() == record.where_field_size());
123
 
 
124
 
  cout << "UPDATE `" << container.schema() << "`.`" << container.table() << "` SET ";
125
 
 
126
 
  for (x= 0;x < num_update_fields; x++)
127
 
  {
128
 
    message::Table::Field f= record.update_field(x);
129
 
    
130
 
    if (x != 0)
131
 
      cout << ", ";
132
 
 
133
 
    cout << "`" << f.name() << "` = \"" << record.after_value(x) << "\"";
134
 
  }
135
 
 
136
 
  int32_t num_where_fields= record.where_field_size();
137
 
  /* 
138
 
   * Make sure we catch anywhere we're not aligning the fields with
139
 
   * the field_values arrays...
140
 
   */
141
 
  assert(num_where_fields == record.where_value_size());
142
 
 
143
 
  cout << " WHERE ";
144
 
  for (x= 0;x < num_where_fields; x++)
145
 
  {
146
 
    if (x != 0)
147
 
      cout << " AND "; /* Always AND condition with a multi-column PK */
148
 
 
149
 
    const message::Table::Field f= record.where_field(x);
150
 
 
151
 
    /* Always equality conditions */
152
 
    cout << "`" << f.name() << "` = \"" << record.where_value(x) << "\"";
153
 
  }
154
 
  cout << ";";
155
 
}
156
 
 
157
20
static void printCommand(const message::Command &command)
158
21
{
159
22
  cout << "/* Timestamp: " << command.timestamp() << " */"<< endl;
167
30
 
168
31
  cout << " */ ";
169
32
 
170
 
  switch (command.type())
171
 
  {
172
 
    case message::Command::START_TRANSACTION:
173
 
      cout << "START TRANSACTION;";
174
 
      break;
175
 
    case message::Command::COMMIT:
176
 
      cout << "COMMIT;";
177
 
      break;
178
 
    case message::Command::ROLLBACK:
179
 
      cout << "ROLLBACK;";
180
 
      break;
181
 
    case message::Command::INSERT:
182
 
    {
183
 
      printInsert(command, command.insert_record());
184
 
      break;
185
 
    }
186
 
    case message::Command::DELETE:
187
 
    {
188
 
      printDeleteWithPK(command, command.delete_record());
189
 
      break;
190
 
    }
191
 
    case message::Command::UPDATE:
192
 
    {
193
 
      printUpdateWithPK(command, command.update_record());
194
 
      break;
195
 
    }
196
 
    case message::Command::RAW_SQL:
197
 
    {
198
 
      std::string sql= command.sql();
199
 
      /* Replace \n with spaces */
200
 
      const std::string newline= "\n";
201
 
      while (sql.find(newline) != std::string::npos)
202
 
        sql.replace(sql.find(newline), 1, " ");
203
 
 
204
 
      cout << sql << ";";
205
 
      break;
206
 
    }
207
 
    default:
208
 
      cout << "Received an unknown Command type: " << (int32_t) command.type();
209
 
  }
210
 
  cout << endl;
 
33
  string sql("");
 
34
 
 
35
  message::transformCommand2Sql(command, &sql, message::DRIZZLE);
 
36
 
 
37
  /* 
 
38
   * Replace \n with spaces so that SQL statements 
 
39
   * are always on a single line 
 
40
   */
 
41
  const std::string newline= "\n";
 
42
  while (sql.find(newline) != std::string::npos)
 
43
    sql.replace(sql.find(newline), 1, " ");
 
44
 
 
45
  cout << sql << ';' << endl;
211
46
}
212
47
 
213
48
int main(int argc, char* argv[])