1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
1 |
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
|
2 |
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
|
|
3 |
*
|
|
4 |
* Copyright (C) 2010 Andrew Hutchings
|
|
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 |
||
2463.1.2
by Brian Aker
First pass, drizzle_create() no longer takes an argument. This means that we can now change drizzle_st without being concerned about ABI. |
20 |
#include <config.h> |
21 |
||
22 |
#include "client/drizzledump_data.h" |
|
23 |
#include "client/client_priv.h" |
|
2241.4.14
by Stewart Smith
remove some includes from my_sys.h and instead only include where needed. This helps reduce the number of files that have to be rebuilt when you change some of the more widely included header files (such as the drizzled::identifier ones) |
24 |
#include <drizzled/definitions.h> |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
25 |
#include <drizzled/gettext.h> |
26 |
#include <string> |
|
27 |
#include <iostream> |
|
1751.4.24
by Andrew Hutchings
Fix ignore tables |
28 |
#include <boost/unordered_set.hpp> |
2241.4.14
by Stewart Smith
remove some includes from my_sys.h and instead only include where needed. This helps reduce the number of files that have to be rebuilt when you change some of the more widely included header files (such as the drizzled::identifier ones) |
29 |
#include <boost/lexical_cast.hpp> |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
30 |
|
1751.4.25
by Andrew Hutchings
Fix error handling |
31 |
#define EX_DRIZZLEERR 2
|
32 |
||
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
33 |
extern bool opt_no_create_info; |
34 |
extern bool opt_no_data; |
|
35 |
extern bool opt_create_db; |
|
36 |
extern bool opt_disable_keys; |
|
37 |
extern bool extended_insert; |
|
38 |
extern bool opt_replace_into; |
|
1751.4.25
by Andrew Hutchings
Fix error handling |
39 |
extern bool opt_drop; |
40 |
extern bool verbose; |
|
41 |
extern bool opt_databases; |
|
42 |
extern bool opt_alldbs; |
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
43 |
extern uint32_t show_progress_size; |
1751.4.26
by Andrew Hutchings
Fix up for the drizzledump test cases |
44 |
extern bool opt_ignore; |
1799.7.2
by Andrew Hutchings
Clean up some drizzledump options |
45 |
extern bool opt_compress; |
46 |
extern bool opt_drop_database; |
|
47 |
extern bool opt_autocommit; |
|
1799.7.4
by Andrew Hutchings
Fix up some more options and the docs |
48 |
extern bool ignore_errors; |
1862.2.1
by Andrew Hutchings
Link up --destination-database |
49 |
extern std::string opt_destination_database; |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
50 |
|
1751.4.24
by Andrew Hutchings
Fix ignore tables |
51 |
extern boost::unordered_set<std::string> ignore_table; |
1751.4.25
by Andrew Hutchings
Fix error handling |
52 |
extern void maybe_exit(int error); |
1751.4.24
by Andrew Hutchings
Fix ignore tables |
53 |
|
1751.4.23
by Andrew Hutchings
Fix various bugs |
54 |
enum destinations { |
55 |
DESTINATION_DB, |
|
56 |
DESTINATION_FILES, |
|
57 |
DESTINATION_STDOUT
|
|
58 |
};
|
|
59 |
||
60 |
extern int opt_destination; |
|
61 |
||
2192.4.1
by Olaf van der Spek
Add find_ptr |
62 |
// returns true on keep, false on ignore Olaf: sounds backwards/wrong, shouldn't it be the other way around?
|
1751.4.24
by Andrew Hutchings
Fix ignore tables |
63 |
bool DrizzleDumpDatabase::ignoreTable(std::string tableName) |
64 |
{
|
|
2192.4.1
by Olaf van der Spek
Add find_ptr |
65 |
return ignore_table.find(databaseName + "." + tableName) == ignore_table.end(); |
1751.4.24
by Andrew Hutchings
Fix ignore tables |
66 |
}
|
67 |
||
1751.4.25
by Andrew Hutchings
Fix error handling |
68 |
void DrizzleDumpDatabase::cleanTableName(std::string &tableName) |
69 |
{
|
|
70 |
std::string replace("``"); |
|
71 |
std::string find("`"); |
|
72 |
size_t j = 0; |
|
73 |
for (;(j = tableName.find(find, j)) != std::string::npos;) |
|
74 |
{
|
|
75 |
tableName.replace(j, find.length(), replace); |
|
76 |
j+= replace.length(); |
|
77 |
}
|
|
78 |
||
79 |
}
|
|
80 |
||
1810.6.4
by Andrew Hutchings
Add foreign keys to Drizzle server |
81 |
std::ostream& operator <<(std::ostream &os, const DrizzleDumpForeignKey &obj) |
82 |
{
|
|
83 |
os << " CONSTRAINT `" << obj.constraintName << "` FOREIGN KEY (" |
|
84 |
<< obj.parentColumns << ") REFERENCES `" << obj.childTable << "` (" |
|
85 |
<< obj.childColumns << ")"; |
|
86 |
||
87 |
if (not obj.deleteRule.empty()) |
|
88 |
os << " ON DELETE " << obj.deleteRule; |
|
89 |
||
90 |
if (not obj.updateRule.empty()) |
|
91 |
os << " ON UPDATE " << obj.updateRule; |
|
92 |
||
93 |
return os; |
|
94 |
}
|
|
95 |
||
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
96 |
std::ostream& operator <<(std::ostream &os, const DrizzleDumpIndex &obj) |
97 |
{
|
|
98 |
if (obj.isPrimary) |
|
99 |
{
|
|
100 |
os << " PRIMARY KEY "; |
|
101 |
}
|
|
102 |
else if (obj.isUnique) |
|
103 |
{
|
|
104 |
os << " UNIQUE KEY `" << obj.indexName << "` "; |
|
105 |
}
|
|
106 |
else
|
|
107 |
{
|
|
108 |
os << " KEY `" << obj.indexName << "` "; |
|
109 |
}
|
|
110 |
||
111 |
os << "("; |
|
112 |
||
2228.3.1
by Andrew Hutchings
Fix multi-part index length processing in drizzledump |
113 |
std::vector<DrizzleDumpIndex::columnData>::iterator i; |
114 |
std::vector<DrizzleDumpIndex::columnData> fields = obj.columns; |
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
115 |
for (i= fields.begin(); i != fields.end(); ++i) |
116 |
{
|
|
117 |
if (i != fields.begin()) |
|
118 |
os << ","; |
|
2228.3.1
by Andrew Hutchings
Fix multi-part index length processing in drizzledump |
119 |
os << "`" << (*i).first << "`"; |
120 |
if ((*i).second > 0) |
|
121 |
os << "(" << (*i).second << ")"; |
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
122 |
}
|
123 |
||
124 |
os << ")"; |
|
125 |
||
126 |
return os; |
|
127 |
}
|
|
128 |
||
129 |
std::ostream& operator <<(std::ostream &os, const DrizzleDumpField &obj) |
|
130 |
{
|
|
131 |
os << " `" << obj.fieldName << "` "; |
|
132 |
os << obj.type; |
|
133 |
if (((obj.type.compare("VARCHAR") == 0) or |
|
134 |
(obj.type.compare("VARBINARY") == 0)) and |
|
135 |
(obj.length > 0)) |
|
136 |
{
|
|
137 |
os << "(" << obj.length << ")"; |
|
138 |
}
|
|
1751.4.26
by Andrew Hutchings
Fix up for the drizzledump test cases |
139 |
else if (((obj.type.compare("DECIMAL") == 0) or |
140 |
(obj.type.compare("DOUBLE") == 0)) and |
|
141 |
((obj.decimalPrecision + obj.decimalScale) > 0)) |
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
142 |
{
|
143 |
os << "(" << obj.decimalPrecision << "," << obj.decimalScale << ")"; |
|
144 |
}
|
|
145 |
else if (obj.type.compare("ENUM") == 0) |
|
146 |
{
|
|
147 |
os << "(" << obj.enumValues << ")"; |
|
148 |
}
|
|
149 |
||
150 |
if (not obj.isNull) |
|
151 |
{
|
|
152 |
os << " NOT NULL"; |
|
153 |
}
|
|
154 |
||
155 |
if ((not obj.collation.empty()) and (obj.collation.compare("binary") != 0)) |
|
156 |
{
|
|
157 |
os << " COLLATE " << obj.collation; |
|
158 |
}
|
|
159 |
||
160 |
if (obj.isAutoIncrement) |
|
161 |
os << " AUTO_INCREMENT"; |
|
162 |
||
163 |
if (not obj.defaultValue.empty()) |
|
164 |
{
|
|
165 |
if (obj.defaultValue.compare("CURRENT_TIMESTAMP") != 0) |
|
1971.5.2
by Andrew Hutchings
Add BIT support when converting MySQL. We convert this to a varbinary and covert the bit length to a byte length. |
166 |
{
|
167 |
if (obj.defaultValue.compare(0, 2, "b'") == 0) |
|
168 |
{
|
|
169 |
os << " DEFAULT " << obj.defaultValue; |
|
170 |
}
|
|
171 |
else
|
|
172 |
{
|
|
173 |
os << " DEFAULT '" << obj.defaultValue << "'"; |
|
174 |
}
|
|
175 |
}
|
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
176 |
else
|
1971.5.2
by Andrew Hutchings
Add BIT support when converting MySQL. We convert this to a varbinary and covert the bit length to a byte length. |
177 |
{
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
178 |
os << " DEFAULT CURRENT_TIMESTAMP"; |
1971.5.2
by Andrew Hutchings
Add BIT support when converting MySQL. We convert this to a varbinary and covert the bit length to a byte length. |
179 |
}
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
180 |
}
|
1751.4.26
by Andrew Hutchings
Fix up for the drizzledump test cases |
181 |
else if ((obj.defaultIsNull)) |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
182 |
{
|
183 |
os << " DEFAULT NULL"; |
|
184 |
}
|
|
185 |
||
1976.4.3
by Andrew Hutchings
Add field level comments back in to drizzledump |
186 |
if (not obj.comment.empty()) |
187 |
{
|
|
188 |
os << " COMMENT '" << DrizzleDumpData::escape(obj.comment.c_str(), obj.comment.length()) << "'"; |
|
189 |
}
|
|
190 |
||
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
191 |
return os; |
192 |
}
|
|
193 |
||
194 |
std::ostream& operator <<(std::ostream &os, const DrizzleDumpDatabase &obj) |
|
195 |
{
|
|
1751.4.23
by Andrew Hutchings
Fix various bugs |
196 |
if ((opt_destination == DESTINATION_DB) or opt_databases or opt_alldbs) |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
197 |
{
|
1751.4.26
by Andrew Hutchings
Fix up for the drizzledump test cases |
198 |
if (verbose) |
199 |
{
|
|
200 |
std::cerr << "--" << std::endl |
|
201 |
<< "-- Current Database: `" << obj.databaseName << "`" << std::endl |
|
202 |
<< "--" << std::endl << std::endl; |
|
203 |
}
|
|
1751.4.23
by Andrew Hutchings
Fix various bugs |
204 |
|
205 |
/* Love that this variable is the opposite of its name */
|
|
206 |
if (not opt_create_db) |
|
207 |
{
|
|
1799.7.2
by Andrew Hutchings
Clean up some drizzledump options |
208 |
if (opt_drop_database) |
1862.2.1
by Andrew Hutchings
Link up --destination-database |
209 |
{
|
210 |
os << "DROP DATABASE IF EXISTS `" |
|
211 |
<< ((opt_destination_database.empty()) ? obj.databaseName |
|
212 |
: opt_destination_database) << "`" << std::endl; |
|
213 |
}
|
|
1799.7.2
by Andrew Hutchings
Clean up some drizzledump options |
214 |
|
1862.2.1
by Andrew Hutchings
Link up --destination-database |
215 |
os << "CREATE DATABASE IF NOT EXISTS `" |
216 |
<< ((opt_destination_database.empty()) ? obj.databaseName |
|
217 |
: opt_destination_database) << "`"; |
|
1751.4.23
by Andrew Hutchings
Fix various bugs |
218 |
if (not obj.collate.empty()) |
219 |
os << " COLLATE = " << obj.collate; |
|
220 |
||
221 |
os << ";" << std::endl << std::endl; |
|
222 |
}
|
|
1862.2.1
by Andrew Hutchings
Link up --destination-database |
223 |
os << "USE `" << ((opt_destination_database.empty()) ? obj.databaseName |
224 |
: opt_destination_database) << "`;" << std::endl << std::endl; |
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
225 |
}
|
226 |
||
227 |
std::vector<DrizzleDumpTable*>::iterator i; |
|
228 |
std::vector<DrizzleDumpTable*> output_tables = obj.tables; |
|
229 |
for (i= output_tables.begin(); i != output_tables.end(); ++i) |
|
230 |
{
|
|
231 |
DrizzleDumpTable *table= *i; |
|
232 |
if (not opt_no_create_info) |
|
233 |
os << *table; |
|
234 |
if (not opt_no_data) |
|
235 |
{
|
|
1751.4.21
by Andrew Hutchings
Add database destination settings and connect it all up |
236 |
obj.dcon->setDB(obj.databaseName); |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
237 |
DrizzleDumpData *data= table->getData(); |
1751.4.25
by Andrew Hutchings
Fix error handling |
238 |
if (data == NULL) |
239 |
{
|
|
240 |
std::cerr << "Error: Could not get data for table " << table->displayName << std::endl; |
|
1799.7.4
by Andrew Hutchings
Fix up some more options and the docs |
241 |
if (not ignore_errors) |
242 |
maybe_exit(EX_DRIZZLEERR); |
|
243 |
else
|
|
244 |
continue; |
|
1751.4.25
by Andrew Hutchings
Fix error handling |
245 |
}
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
246 |
os << *data; |
247 |
delete data; |
|
248 |
}
|
|
249 |
}
|
|
250 |
||
251 |
return os; |
|
252 |
}
|
|
253 |
||
254 |
||
255 |
std::ostream& operator <<(std::ostream &os, const DrizzleDumpData &obj) |
|
256 |
{
|
|
257 |
bool new_insert= true; |
|
258 |
bool first= true; |
|
259 |
uint64_t rownr= 0; |
|
1855.1.1
by Andrew Hutchings
Fix several bugs dumping tables with many rows |
260 |
size_t byte_counter= 0; |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
261 |
|
262 |
drizzle_row_t row; |
|
263 |
||
1751.4.23
by Andrew Hutchings
Fix various bugs |
264 |
if (verbose) |
1751.4.25
by Andrew Hutchings
Fix error handling |
265 |
std::cerr << _("-- Retrieving data for ") << obj.table->displayName << "..." << std::endl; |
1751.4.23
by Andrew Hutchings
Fix various bugs |
266 |
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
267 |
if (drizzle_result_row_count(obj.result) < 1) |
268 |
{
|
|
1751.4.26
by Andrew Hutchings
Fix up for the drizzledump test cases |
269 |
if (verbose) |
270 |
{
|
|
271 |
std::cerr << "--" << std::endl |
|
272 |
<< "-- No data to dump for table `" << obj.table->displayName << "`" |
|
273 |
<< std::endl << "--" << std::endl << std::endl; |
|
274 |
}
|
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
275 |
return os; |
276 |
}
|
|
1751.4.26
by Andrew Hutchings
Fix up for the drizzledump test cases |
277 |
else if (verbose) |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
278 |
{
|
1751.4.26
by Andrew Hutchings
Fix up for the drizzledump test cases |
279 |
std::cerr << "--" << std::endl |
280 |
<< "-- Dumping data for table `" << obj.table->displayName << "`" |
|
281 |
<< std::endl << "--" << std::endl << std::endl; |
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
282 |
}
|
283 |
if (opt_disable_keys) |
|
1751.4.25
by Andrew Hutchings
Fix error handling |
284 |
os << "ALTER TABLE `" << obj.table->displayName << "` DISABLE KEYS;" << std::endl; |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
285 |
|
1799.7.2
by Andrew Hutchings
Clean up some drizzledump options |
286 |
/* Another option that does the opposite of its name, makes me sad :( */
|
287 |
if (opt_autocommit) |
|
288 |
os << "START TRANSACTION;" << std::endl; |
|
289 |
||
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
290 |
while((row= drizzle_row_next(obj.result))) |
291 |
{
|
|
292 |
rownr++; |
|
1855.1.1
by Andrew Hutchings
Fix several bugs dumping tables with many rows |
293 |
if (verbose and (rownr % show_progress_size) == 0) |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
294 |
{
|
1802.11.1
by Andrew Hutchings
1. date regex was broken |
295 |
std::cerr << "-- " << rownr << _(" rows dumped for table ") << obj.table->displayName << std::endl; |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
296 |
}
|
297 |
||
298 |
size_t* row_sizes= drizzle_row_field_sizes(obj.result); |
|
1855.1.1
by Andrew Hutchings
Fix several bugs dumping tables with many rows |
299 |
for (uint32_t i= 0; i < drizzle_result_column_count(obj.result); i++) |
300 |
byte_counter+= row_sizes[i]; |
|
301 |
||
302 |
if (not first and not new_insert) |
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
303 |
{
|
304 |
if (extended_insert) |
|
305 |
os << "),("; |
|
306 |
else
|
|
307 |
os << ");" << std::endl; |
|
1855.1.1
by Andrew Hutchings
Fix several bugs dumping tables with many rows |
308 |
byte_counter+= 3; |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
309 |
}
|
310 |
else
|
|
311 |
first= false; |
|
312 |
||
313 |
if (new_insert) |
|
314 |
{
|
|
315 |
if (opt_replace_into) |
|
316 |
os << "REPLACE "; |
|
317 |
else
|
|
1751.4.26
by Andrew Hutchings
Fix up for the drizzledump test cases |
318 |
{
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
319 |
os << "INSERT "; |
1751.4.26
by Andrew Hutchings
Fix up for the drizzledump test cases |
320 |
if (opt_ignore) |
321 |
os << "IGNORE "; |
|
322 |
}
|
|
1751.4.25
by Andrew Hutchings
Fix error handling |
323 |
os << "INTO `" << obj.table->displayName << "` VALUES ("; |
1855.1.1
by Andrew Hutchings
Fix several bugs dumping tables with many rows |
324 |
byte_counter+= 28 + obj.table->displayName.length(); |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
325 |
if (extended_insert) |
326 |
new_insert= false; |
|
327 |
}
|
|
328 |
for (uint32_t i= 0; i < drizzle_result_column_count(obj.result); i++) |
|
329 |
{
|
|
330 |
if (not row[i]) |
|
331 |
{
|
|
332 |
os << "NULL"; |
|
1971.5.3
by Andrew Hutchings
If migrating a BIGINT UNISIGNED value > BIGINT signed max value, error. We cannot store it. |
333 |
if (i != obj.table->fields.size() - 1) |
334 |
os << ","; |
|
335 |
continue; |
|
336 |
}
|
|
337 |
||
1971.5.6
by Andrew Hutchings
Make BIGINT range check only happen on MySQL BIGINT UNSIGNED as it is tripping up on negative BIGINT values. |
338 |
if ((obj.table->fields[i]->rangeCheck) and |
339 |
(obj.table->fields[i]->type.compare("BIGINT") == 0) and |
|
340 |
(boost::lexical_cast<uint64_t>(row[i]) > INT64_MAX)) |
|
1971.5.3
by Andrew Hutchings
If migrating a BIGINT UNISIGNED value > BIGINT signed max value, error. We cannot store it. |
341 |
{
|
342 |
std::cerr << "Error: Data for column " << obj.table->fields[i]->fieldName << " is greater than max BIGINT, cannot migrate automatically" << std::endl; |
|
343 |
if (not ignore_errors) |
|
344 |
maybe_exit(EX_DRIZZLEERR); |
|
345 |
else
|
|
346 |
continue; |
|
347 |
}
|
|
348 |
||
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
349 |
/* time/date conversion for MySQL connections */
|
350 |
else if (obj.table->fields[i]->convertDateTime) |
|
351 |
{
|
|
1802.11.1
by Andrew Hutchings
1. date regex was broken |
352 |
os << obj.checkDateTime(row[i], i); |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
353 |
}
|
354 |
else
|
|
355 |
{
|
|
1971.5.6
by Andrew Hutchings
Make BIGINT range check only happen on MySQL BIGINT UNSIGNED as it is tripping up on negative BIGINT values. |
356 |
if ((obj.table->fields[i]->type.compare("INT") != 0) and |
357 |
(obj.table->fields[i]->type.compare("BIGINT") != 0)) |
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
358 |
{
|
359 |
/* Hex blob processing or escape text */
|
|
360 |
if (((obj.table->fields[i]->type.compare("BLOB") == 0) or |
|
361 |
(obj.table->fields[i]->type.compare("VARBINARY") == 0))) |
|
1855.1.1
by Andrew Hutchings
Fix several bugs dumping tables with many rows |
362 |
{
|
1751.4.26
by Andrew Hutchings
Fix up for the drizzledump test cases |
363 |
os << obj.convertHex((unsigned char*)row[i], row_sizes[i]); |
1855.1.1
by Andrew Hutchings
Fix several bugs dumping tables with many rows |
364 |
byte_counter+= row_sizes[i]; |
365 |
}
|
|
1882.2.1
by Andrew Hutchings
MySQL can contain '' as an ENUM value which is not valid in Drizzle. Convert this to NULL. |
366 |
else if ((obj.table->fields[i]->type.compare("ENUM") == 0) and |
367 |
(strcmp(row[i], "") == 0)) |
|
368 |
{
|
|
369 |
os << "NULL"; |
|
370 |
}
|
|
2187.3.3
by Andrew Hutchings
Add boolean support for drizzledump too |
371 |
else if (obj.table->fields[i]->type.compare("BOOLEAN") == 0) |
372 |
{
|
|
373 |
if (strncmp(row[i], "1", 1) == 0) |
|
374 |
os << "TRUE"; |
|
375 |
else
|
|
376 |
os << "FALSE"; |
|
377 |
}
|
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
378 |
else
|
1810.1.1
by Andrew Hutchings
Add table comments |
379 |
os << "'" << DrizzleDumpData::escape(row[i], row_sizes[i]) << "'"; |
1855.1.1
by Andrew Hutchings
Fix several bugs dumping tables with many rows |
380 |
byte_counter+= 3; |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
381 |
}
|
382 |
else
|
|
383 |
os << row[i]; |
|
384 |
}
|
|
385 |
if (i != obj.table->fields.size() - 1) |
|
386 |
os << ","; |
|
387 |
}
|
|
388 |
/* Break insert up if it is too long */
|
|
1865.2.1
by Andrew Hutchings
Fix drizzledump --skip-extended-insert |
389 |
if ((extended_insert and |
390 |
(byte_counter >= DRIZZLE_MAX_LINE_LENGTH)) or (not extended_insert)) |
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
391 |
{
|
392 |
os << ");" << std::endl; |
|
393 |
new_insert= true; |
|
1855.1.1
by Andrew Hutchings
Fix several bugs dumping tables with many rows |
394 |
byte_counter= 0; |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
395 |
}
|
396 |
}
|
|
1865.2.2
by Andrew Hutchings
Fix possibility of double ");" at end of data dump |
397 |
if (not new_insert) |
398 |
os << ");" << std::endl; |
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
399 |
|
1799.7.2
by Andrew Hutchings
Clean up some drizzledump options |
400 |
if (opt_autocommit) |
401 |
os << "COMMIT;" << std::endl; |
|
402 |
||
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
403 |
if (opt_disable_keys) |
404 |
os << "ALTER TABLE `" << obj.table->tableName << "` ENABLE KEYS;" << std::endl; |
|
405 |
||
406 |
os << std::endl; |
|
407 |
||
408 |
return os; |
|
409 |
}
|
|
410 |
||
1751.4.26
by Andrew Hutchings
Fix up for the drizzledump test cases |
411 |
std::string DrizzleDumpData::convertHex(const unsigned char* from, size_t from_size) const |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
412 |
{
|
413 |
std::ostringstream output; |
|
414 |
if (from_size > 0) |
|
415 |
output << "0x"; |
|
1897.3.1
by Andrew Hutchings
drizzledump MySQL migration fixes: |
416 |
else
|
417 |
output << "''"; |
|
418 |
||
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
419 |
while (from_size > 0) |
420 |
{
|
|
1751.4.26
by Andrew Hutchings
Fix up for the drizzledump test cases |
421 |
/* Would be nice if std::hex liked uint8_t, ah well */
|
422 |
output << std::uppercase << std::hex << std::setw(2) << std::setfill('0') << (unsigned short)(*from); |
|
1831.1.1
by Andrew Hutchings
Fix new warnings in GCC 4.5 |
423 |
(void) *from++; |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
424 |
from_size--; |
425 |
}
|
|
426 |
||
427 |
return output.str(); |
|
428 |
}
|
|
429 |
||
430 |
/* Ripped out of libdrizzle, hopefully a little safer */
|
|
1810.1.1
by Andrew Hutchings
Add table comments |
431 |
std::string DrizzleDumpData::escape(const char* from, size_t from_size) |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
432 |
{
|
433 |
std::string output; |
|
434 |
||
435 |
while (from_size > 0) |
|
436 |
{
|
|
437 |
if (!(*from & 0x80)) |
|
438 |
{
|
|
439 |
switch (*from) |
|
440 |
{
|
|
441 |
case 0: |
|
1855.2.1
by Andrew Hutchings
The escape function is a clone of libdrizzle's but C++'ified. Unfortunately libdrizzle's is broken. Fixed it here, will fix it in libdrizzle at a later date. |
442 |
output.append("\\0"); |
443 |
break; |
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
444 |
case '\n': |
1855.2.1
by Andrew Hutchings
The escape function is a clone of libdrizzle's but C++'ified. Unfortunately libdrizzle's is broken. Fixed it here, will fix it in libdrizzle at a later date. |
445 |
output.append("\\n"); |
446 |
break; |
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
447 |
case '\r': |
1855.2.1
by Andrew Hutchings
The escape function is a clone of libdrizzle's but C++'ified. Unfortunately libdrizzle's is broken. Fixed it here, will fix it in libdrizzle at a later date. |
448 |
output.append("\\r"); |
449 |
break; |
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
450 |
case '\\': |
1855.2.1
by Andrew Hutchings
The escape function is a clone of libdrizzle's but C++'ified. Unfortunately libdrizzle's is broken. Fixed it here, will fix it in libdrizzle at a later date. |
451 |
output.append("\\\\"); |
452 |
break; |
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
453 |
case '\'': |
1855.2.1
by Andrew Hutchings
The escape function is a clone of libdrizzle's but C++'ified. Unfortunately libdrizzle's is broken. Fixed it here, will fix it in libdrizzle at a later date. |
454 |
output.append("\\'"); |
455 |
break; |
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
456 |
case '"': |
1855.2.1
by Andrew Hutchings
The escape function is a clone of libdrizzle's but C++'ified. Unfortunately libdrizzle's is broken. Fixed it here, will fix it in libdrizzle at a later date. |
457 |
output.append("\\\""); |
458 |
break; |
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
459 |
case '\032': |
1855.2.1
by Andrew Hutchings
The escape function is a clone of libdrizzle's but C++'ified. Unfortunately libdrizzle's is broken. Fixed it here, will fix it in libdrizzle at a later date. |
460 |
output.append("\\Z"); |
461 |
break; |
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
462 |
default: |
1855.2.1
by Andrew Hutchings
The escape function is a clone of libdrizzle's but C++'ified. Unfortunately libdrizzle's is broken. Fixed it here, will fix it in libdrizzle at a later date. |
463 |
output.push_back(*from); |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
464 |
break; |
465 |
}
|
|
466 |
}
|
|
1855.2.1
by Andrew Hutchings
The escape function is a clone of libdrizzle's but C++'ified. Unfortunately libdrizzle's is broken. Fixed it here, will fix it in libdrizzle at a later date. |
467 |
else
|
468 |
output.push_back(*from); |
|
1831.1.1
by Andrew Hutchings
Fix new warnings in GCC 4.5 |
469 |
(void) *from++; |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
470 |
from_size--; |
471 |
}
|
|
472 |
||
473 |
return output; |
|
474 |
}
|
|
475 |
||
476 |
std::ostream& operator <<(std::ostream &os, const DrizzleDumpTable &obj) |
|
477 |
{
|
|
1751.4.26
by Andrew Hutchings
Fix up for the drizzledump test cases |
478 |
if (verbose) |
479 |
{
|
|
480 |
std::cerr << "--" << std::endl |
|
481 |
<< "-- Table structure for table `" << obj.displayName << "`" << std::endl |
|
482 |
<< "--" << std::endl << std::endl; |
|
483 |
}
|
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
484 |
|
485 |
if (opt_drop) |
|
1751.4.25
by Andrew Hutchings
Fix error handling |
486 |
os << "DROP TABLE IF EXISTS `" << obj.displayName << "`;" << std::endl; |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
487 |
|
1751.4.25
by Andrew Hutchings
Fix error handling |
488 |
os << "CREATE TABLE `" << obj.displayName << "` (" << std::endl; |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
489 |
std::vector<DrizzleDumpField*>::iterator i; |
490 |
std::vector<DrizzleDumpField*> output_fields = obj.fields; |
|
491 |
for (i= output_fields.begin(); i != output_fields.end(); ++i) |
|
492 |
{
|
|
493 |
if (i != output_fields.begin()) |
|
494 |
os << "," << std::endl; |
|
495 |
DrizzleDumpField *field= *i; |
|
496 |
os << *field; |
|
497 |
}
|
|
498 |
||
499 |
std::vector<DrizzleDumpIndex*>::iterator j; |
|
500 |
std::vector<DrizzleDumpIndex*> output_indexes = obj.indexes; |
|
501 |
for (j= output_indexes.begin(); j != output_indexes.end(); ++j) |
|
502 |
{
|
|
1810.6.4
by Andrew Hutchings
Add foreign keys to Drizzle server |
503 |
os << "," << std::endl; |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
504 |
DrizzleDumpIndex *index= *j; |
505 |
os << *index; |
|
506 |
}
|
|
1810.6.4
by Andrew Hutchings
Add foreign keys to Drizzle server |
507 |
|
508 |
std::vector<DrizzleDumpForeignKey*>::iterator k; |
|
509 |
std::vector<DrizzleDumpForeignKey*> output_fkeys = obj.fkeys; |
|
510 |
for (k= output_fkeys.begin(); k != output_fkeys.end(); ++k) |
|
511 |
{
|
|
512 |
os << "," << std::endl; |
|
513 |
DrizzleDumpForeignKey *fkey= *k; |
|
514 |
os << *fkey; |
|
515 |
}
|
|
516 |
||
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
517 |
os << std::endl; |
1880.2.1
by Andrew Hutchings
Add quoting to the end of the table definition |
518 |
os << ") ENGINE='" << obj.engineName << "' "; |
1802.5.1
by Andrew Hutchings
Adds auto_increment to data_dictionary.tables and drizzledump (when connecting to a Drizzle server) |
519 |
if (obj.autoIncrement > 0) |
1751.4.20
by Andrew Hutchings
Add database connection class and the start of a database output ostream |
520 |
{
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
521 |
os << "AUTO_INCREMENT=" << obj.autoIncrement << " "; |
1751.4.20
by Andrew Hutchings
Add database connection class and the start of a database output ostream |
522 |
}
|
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
523 |
|
1880.2.1
by Andrew Hutchings
Add quoting to the end of the table definition |
524 |
os << "COLLATE='" << obj.collate << "'"; |
1810.1.1
by Andrew Hutchings
Add table comments |
525 |
|
526 |
if (not obj.comment.empty()) |
|
527 |
{
|
|
1880.2.1
by Andrew Hutchings
Add quoting to the end of the table definition |
528 |
os << " COMMENT='" << obj.comment << "'"; |
1810.1.1
by Andrew Hutchings
Add table comments |
529 |
}
|
530 |
||
2228.2.1
by Andrew Hutchings
Add REPLICATE=FALSE support to drizzledump |
531 |
if (not obj.replicate) |
532 |
{
|
|
533 |
os << " REPLICATE=FALSE"; |
|
534 |
}
|
|
535 |
||
1810.1.1
by Andrew Hutchings
Add table comments |
536 |
os << ";" << std::endl << std::endl; |
1751.4.19
by Andrew Hutchings
Put drizzle and mysql processes in seperate classes/files |
537 |
|
538 |
return os; |
|
539 |
}
|
|
1751.4.20
by Andrew Hutchings
Add database connection class and the start of a database output ostream |
540 |
|
541 |
DrizzleDumpConnection::DrizzleDumpConnection(std::string &host, uint16_t port, |
|
542 |
std::string &username, std::string &password, bool drizzle_protocol) : |
|
543 |
hostName(host), |
|
544 |
drizzleProtocol(drizzle_protocol) |
|
545 |
{
|
|
546 |
if (host.empty()) |
|
2463.1.2
by Brian Aker
First pass, drizzle_create() no longer takes an argument. This means that we can now change drizzle_st without being concerned about ABI. |
547 |
{
|
1751.4.20
by Andrew Hutchings
Add database connection class and the start of a database output ostream |
548 |
host= "localhost"; |
2463.1.2
by Brian Aker
First pass, drizzle_create() no longer takes an argument. This means that we can now change drizzle_st without being concerned about ABI. |
549 |
}
|
1751.4.20
by Andrew Hutchings
Add database connection class and the start of a database output ostream |
550 |
|
551 |
std::string protocol= (drizzle_protocol) ? "Drizzle" : "MySQL"; |
|
1751.4.23
by Andrew Hutchings
Fix various bugs |
552 |
if (verbose) |
553 |
{
|
|
554 |
std::cerr << _("-- Connecting to ") << host << _(" using protocol ") |
|
555 |
<< protocol << "..." << std::endl; |
|
556 |
}
|
|
2463.1.2
by Brian Aker
First pass, drizzle_create() no longer takes an argument. This means that we can now change drizzle_st without being concerned about ABI. |
557 |
|
558 |
drizzle= drizzle_create(); |
|
559 |
||
560 |
if (drizzle == NULL) |
|
561 |
{
|
|
562 |
std::cerr << "drizzle_create() failed" << std::endl; |
|
563 |
}
|
|
564 |
||
2463.1.4
by Brian Aker
Remove con from being passed object. |
565 |
connection= drizzle_con_create(drizzle); |
566 |
drizzle_con_set_tcp(connection, (char *)host.c_str(), port); |
|
567 |
drizzle_con_set_auth(connection, (char *)username.c_str(), (char *)password.c_str()); |
|
568 |
drizzle_con_add_options(connection, drizzle_protocol ? DRIZZLE_CON_EXPERIMENTAL : DRIZZLE_CON_MYSQL); |
|
569 |
||
570 |
drizzle_return_t ret= drizzle_con_connect(connection); |
|
1751.4.20
by Andrew Hutchings
Add database connection class and the start of a database output ostream |
571 |
if (ret != DRIZZLE_RETURN_OK) |
572 |
{
|
|
573 |
errorHandler(NULL, ret, "when trying to connect"); |
|
1966.3.1
by Monty Taylor
Use std::exception instead of catch(...) |
574 |
throw std::exception(); |
1751.4.20
by Andrew Hutchings
Add database connection class and the start of a database output ostream |
575 |
}
|
576 |
||
2463.1.4
by Brian Aker
Remove con from being passed object. |
577 |
ServerDetect server_detect= ServerDetect(connection); |
2187.3.2
by Andrew Hutchings
Separate the server detection functions into a .h file |
578 |
|
579 |
serverType= server_detect.getServerType(); |
|
580 |
serverVersion= server_detect.getServerVersion(); |
|
1751.4.20
by Andrew Hutchings
Add database connection class and the start of a database output ostream |
581 |
}
|
582 |
||
583 |
drizzle_result_st* DrizzleDumpConnection::query(std::string &str_query) |
|
584 |
{
|
|
585 |
drizzle_return_t ret; |
|
586 |
drizzle_result_st* result= new drizzle_result_st; |
|
2463.1.4
by Brian Aker
Remove con from being passed object. |
587 |
if (drizzle_query_str(connection, result, str_query.c_str(), &ret) == NULL or |
1751.4.20
by Andrew Hutchings
Add database connection class and the start of a database output ostream |
588 |
ret != DRIZZLE_RETURN_OK) |
589 |
{
|
|
590 |
if (ret == DRIZZLE_RETURN_ERROR_CODE) |
|
591 |
{
|
|
592 |
std::cerr << _("Error executing query: ") << |
|
1751.4.23
by Andrew Hutchings
Fix various bugs |
593 |
drizzle_result_error(result) << std::endl; |
1751.4.20
by Andrew Hutchings
Add database connection class and the start of a database output ostream |
594 |
drizzle_result_free(result); |
595 |
}
|
|
596 |
else
|
|
597 |
{
|
|
2463.1.4
by Brian Aker
Remove con from being passed object. |
598 |
std::cerr << _("Error executing query: ") << drizzle_con_error(connection) << std::endl; |
1751.4.20
by Andrew Hutchings
Add database connection class and the start of a database output ostream |
599 |
}
|
600 |
return NULL; |
|
601 |
}
|
|
602 |
||
603 |
if (drizzle_result_buffer(result) != DRIZZLE_RETURN_OK) |
|
604 |
{
|
|
2463.1.4
by Brian Aker
Remove con from being passed object. |
605 |
std::cerr << _("Could not buffer result: ") << drizzle_con_error(connection) << std::endl; |
1751.4.20
by Andrew Hutchings
Add database connection class and the start of a database output ostream |
606 |
return NULL; |
607 |
}
|
|
608 |
return result; |
|
609 |
}
|
|
610 |
||
611 |
void DrizzleDumpConnection::freeResult(drizzle_result_st* result) |
|
612 |
{
|
|
613 |
drizzle_result_free(result); |
|
614 |
delete result; |
|
615 |
}
|
|
616 |
||
617 |
bool DrizzleDumpConnection::queryNoResult(std::string &str_query) |
|
618 |
{
|
|
619 |
drizzle_return_t ret; |
|
620 |
drizzle_result_st result; |
|
621 |
||
2463.1.4
by Brian Aker
Remove con from being passed object. |
622 |
if (drizzle_query_str(connection, &result, str_query.c_str(), &ret) == NULL or |
1751.4.20
by Andrew Hutchings
Add database connection class and the start of a database output ostream |
623 |
ret != DRIZZLE_RETURN_OK) |
624 |
{
|
|
625 |
if (ret == DRIZZLE_RETURN_ERROR_CODE) |
|
626 |
{
|
|
627 |
std::cerr << _("Error executing query: ") << |
|
1751.4.23
by Andrew Hutchings
Fix various bugs |
628 |
drizzle_result_error(&result) << std::endl; |
1751.4.20
by Andrew Hutchings
Add database connection class and the start of a database output ostream |
629 |
drizzle_result_free(&result); |
630 |
}
|
|
631 |
else
|
|
632 |
{
|
|
2463.1.4
by Brian Aker
Remove con from being passed object. |
633 |
std::cerr << _("Error executing query: ") << drizzle_con_error(connection) << std::endl; |
1751.4.20
by Andrew Hutchings
Add database connection class and the start of a database output ostream |
634 |
}
|
635 |
return false; |
|
636 |
}
|
|
637 |
||
638 |
drizzle_result_free(&result); |
|
639 |
return true; |
|
640 |
}
|
|
641 |
||
642 |
bool DrizzleDumpConnection::setDB(std::string databaseName) |
|
643 |
{
|
|
644 |
drizzle_return_t ret; |
|
645 |
drizzle_result_st result; |
|
2463.1.4
by Brian Aker
Remove con from being passed object. |
646 |
|
647 |
if (drizzle_select_db(connection, &result, databaseName.c_str(), &ret) == NULL or |
|
648 |
ret != DRIZZLE_RETURN_OK) |
|
1751.4.20
by Andrew Hutchings
Add database connection class and the start of a database output ostream |
649 |
{
|
1751.4.25
by Andrew Hutchings
Fix error handling |
650 |
std::cerr << _("Error: Could not set db '") << databaseName << "'" << std::endl; |
651 |
if (ret == DRIZZLE_RETURN_ERROR_CODE) |
|
2463.1.4
by Brian Aker
Remove con from being passed object. |
652 |
{
|
1751.4.25
by Andrew Hutchings
Fix error handling |
653 |
drizzle_result_free(&result); |
2463.1.4
by Brian Aker
Remove con from being passed object. |
654 |
}
|
655 |
||
1751.4.20
by Andrew Hutchings
Add database connection class and the start of a database output ostream |
656 |
return false; |
657 |
}
|
|
658 |
drizzle_result_free(&result); |
|
2463.1.4
by Brian Aker
Remove con from being passed object. |
659 |
|
1751.4.20
by Andrew Hutchings
Add database connection class and the start of a database output ostream |
660 |
return true; |
661 |
}
|
|
662 |
||
1799.7.2
by Andrew Hutchings
Clean up some drizzledump options |
663 |
void DrizzleDumpConnection::errorHandler(drizzle_result_st *res, |
664 |
drizzle_return_t ret, const char *when) |
|
1751.4.20
by Andrew Hutchings
Add database connection class and the start of a database output ostream |
665 |
{
|
1802.6.1
by Andrew Hutchings
Add better error handling and exception handling for database connect |
666 |
if (res == NULL) |
667 |
{
|
|
2463.1.4
by Brian Aker
Remove con from being passed object. |
668 |
std::cerr << _("Got error: ") << drizzle_con_error(connection) << " " << when << std::endl; |
1802.6.1
by Andrew Hutchings
Add better error handling and exception handling for database connect |
669 |
}
|
670 |
else if (ret == DRIZZLE_RETURN_ERROR_CODE) |
|
1751.4.20
by Andrew Hutchings
Add database connection class and the start of a database output ostream |
671 |
{
|
672 |
std::cerr << _("Got error: ") << drizzle_result_error(res) |
|
673 |
<< " (" << drizzle_result_error_code(res) << ") " << when << std::endl; |
|
674 |
drizzle_result_free(res); |
|
675 |
}
|
|
676 |
else
|
|
677 |
{
|
|
678 |
std::cerr << _("Got error: ") << ret << " " << when << std::endl; |
|
679 |
}
|
|
680 |
||
681 |
return; |
|
682 |
}
|
|
683 |
||
684 |
DrizzleDumpConnection::~DrizzleDumpConnection() |
|
685 |
{
|
|
1751.4.23
by Andrew Hutchings
Fix various bugs |
686 |
if (verbose) |
2463.1.2
by Brian Aker
First pass, drizzle_create() no longer takes an argument. This means that we can now change drizzle_st without being concerned about ABI. |
687 |
{
|
1751.4.23
by Andrew Hutchings
Fix various bugs |
688 |
std::cerr << _("-- Disconnecting from ") << hostName << "..." << std::endl; |
2463.1.2
by Brian Aker
First pass, drizzle_create() no longer takes an argument. This means that we can now change drizzle_st without being concerned about ABI. |
689 |
}
|
690 |
||
2463.1.4
by Brian Aker
Remove con from being passed object. |
691 |
drizzle_con_free(connection); |
2463.1.2
by Brian Aker
First pass, drizzle_create() no longer takes an argument. This means that we can now change drizzle_st without being concerned about ABI. |
692 |
drizzle_free(drizzle); |
1751.4.20
by Andrew Hutchings
Add database connection class and the start of a database output ostream |
693 |
}
|