1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2009 Sun Microsystems
8
* Jay Pipes <joinfu@sun.com>
10
* This program is free software; you can redistribute it and/or modify
11
* it under the terms of the GNU General Public License as published by
12
* the Free Software Foundation; version 2 of the License.
14
* This program is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU General Public License for more details.
19
* You should have received a copy of the GNU General Public License
20
* along with this program; if not, write to the Free Software
21
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27
* Implementation of various routines that can be used to convert
28
* Command messages to other formats, including SQL statements.
31
#include "drizzled/message/command_transform.h"
32
#include "drizzled/message/replication.pb.h"
42
void transformCommand2Sql(const Command &source,
43
std::string *destination,
44
enum CommandTransformSqlVariant sql_variant)
47
char quoted_identifier= '`';
48
if (sql_variant == ANSI)
49
quoted_identifier= '"';
51
switch (source.type())
53
case Command::START_TRANSACTION:
54
destination->assign("START TRANSACTION");
57
destination->assign("COMMIT");
59
case Command::ROLLBACK:
60
destination->assign("ROLLBACK");
64
destination->assign("INSERT INTO ");
65
destination->push_back(quoted_identifier);
66
destination->append(source.schema());
67
destination->push_back(quoted_identifier);
68
destination->push_back('.');
69
destination->push_back(quoted_identifier);
70
destination->append(source.table());
71
destination->push_back(quoted_identifier);
72
destination->append(" (");
74
const message::InsertRecord &record= source.insert_record();
76
int32_t num_fields= record.insert_field_size();
79
for (x= 0; x < num_fields; x++)
82
destination->push_back(',');
84
const message::Table::Field f= record.insert_field(x);
86
destination->push_back(quoted_identifier);
87
destination->append(f.name());
88
destination->push_back(quoted_identifier);
91
destination->append(") VALUES ");
94
* There may be an INSERT VALUES (),() type statement. We know the
95
* number of records is equal to the field_values array size divided
96
* by the number of fields.
98
* So, we do an inner and an outer loop. Outer loop is on the number
99
* of records and the inner loop on the number of fields. In this way,
100
* we know that record.field_values(outer_loop * num_fields) + inner_loop))
101
* always gives us our correct field value.
103
int32_t num_records= (record.insert_value_size() / num_fields);
105
for (x= 0; x < num_records; x++)
108
destination->push_back(',');
110
destination->push_back('(');
111
for (y= 0; y < num_fields; y++)
114
destination->push_back(',');
116
destination->push_back('\'');
117
destination->append(record.insert_value((x * num_fields) + y));
118
destination->push_back('\'');
120
destination->push_back(')');
124
case Command::UPDATE:
126
const message::UpdateRecord &record= source.update_record();
127
int32_t num_update_fields= record.update_field_size();
130
destination->assign("UPDATE ");
131
destination->push_back(quoted_identifier);
132
destination->append(source.schema());
133
destination->push_back(quoted_identifier);
134
destination->push_back('.');
135
destination->push_back(quoted_identifier);
136
destination->append(source.table());
137
destination->push_back(quoted_identifier);
138
destination->append(" SET ");
140
for (x= 0;x < num_update_fields; x++)
142
Table::Field f= record.update_field(x);
145
destination->push_back(',');
147
destination->push_back(quoted_identifier);
148
destination->append(f.name());
149
destination->push_back(quoted_identifier);
150
destination->append("='");
151
destination->append(record.after_value(x));
152
destination->push_back('\'');
155
int32_t num_where_fields= record.where_field_size();
157
* Make sure we catch anywhere we're not aligning the fields with
158
* the field_values arrays...
160
assert(num_where_fields == record.where_value_size());
162
destination->append(" WHERE ");
163
for (x= 0;x < num_where_fields; x++)
166
destination->append(" AND "); /* Always AND condition with a multi-column PK */
168
const Table::Field f= record.where_field(x);
170
/* Always equality conditions */
171
destination->push_back(quoted_identifier);
172
destination->append(f.name());
173
destination->push_back(quoted_identifier);
174
destination->append("='");
175
destination->append(record.where_value(x));
176
destination->push_back('\'');
180
case Command::DELETE:
182
const message::DeleteRecord &record= source.delete_record();
183
int32_t num_where_fields= record.where_field_size();
186
destination->assign("DELETE FROM ");
187
destination->push_back(quoted_identifier);
188
destination->append(source.schema());
189
destination->push_back(quoted_identifier);
190
destination->push_back('.');
191
destination->push_back(quoted_identifier);
192
destination->append(source.table());
193
destination->push_back(quoted_identifier);
195
destination->append(" WHERE ");
196
for (x= 0; x < num_where_fields; x++)
199
destination->append(" AND "); /* Always AND condition with a multi-column PK */
201
const Table::Field f= record.where_field(x);
203
/* Always equality conditions */
204
destination->push_back(quoted_identifier);
205
destination->append(f.name());
206
destination->push_back(quoted_identifier);
207
destination->append(" = '");
208
destination->append(record.where_value(x));
209
destination->push_back('\'');
213
case Command::RAW_SQL:
214
destination->assign(source.sql());
219
} /* end namespace drizzled::message */
220
} /* end namespace drizzled */