1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2010 Andrew Hutchings
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.
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.
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
20
#include "drizzledump_data.h"
21
#include "drizzledump_drizzle.h"
22
#include "client_priv.h"
25
#include <drizzled/gettext.h>
26
#include <boost/lexical_cast.hpp>
29
extern bool ignore_errors;
31
bool DrizzleDumpDatabaseDrizzle::populateTables()
33
drizzle_result_st *result;
37
if (not dcon->setDB(databaseName))
41
std::cerr << _("-- Retrieving table structures for ") << databaseName << "..." << std::endl;
43
query="SELECT TABLE_NAME, TABLE_COLLATION, ENGINE, AUTO_INCREMENT, TABLE_COMMENT FROM DATA_DICTIONARY.TABLES WHERE TABLE_SCHEMA='";
44
query.append(databaseName);
45
query.append("' ORDER BY TABLE_NAME");
47
result= dcon->query(query);
52
while ((row= drizzle_row_next(result)))
54
size_t* row_sizes= drizzle_row_field_sizes(result);
55
std::string tableName(row[0]);
56
std::string displayName(tableName);
57
cleanTableName(displayName);
58
if (not ignoreTable(displayName))
61
DrizzleDumpTable *table = new DrizzleDumpTableDrizzle(tableName, dcon);
62
table->displayName= displayName;
63
table->collate= row[1];
64
table->engineName= row[2];
65
table->autoIncrement= boost::lexical_cast<uint64_t>(row[3]);
67
table->comment= DrizzleDumpData::escape(row[4], row_sizes[4]);
70
table->database= this;
71
if ((not table->populateFields()) or (not table->populateIndexes()) or
72
(not table->populateFkeys()))
75
if (not ignore_errors)
80
tables.push_back(table);
83
dcon->freeResult(result);
88
bool DrizzleDumpDatabaseDrizzle::populateTables(const std::vector<std::string> &table_names)
90
drizzle_result_st *result;
94
if (not dcon->setDB(databaseName))
98
std::cerr << _("-- Retrieving table structures for ") << databaseName << "..." << std::endl;
99
for (std::vector<std::string>::const_iterator it= table_names.begin(); it != table_names.end(); ++it)
101
std::string tableName= *it;
102
std::string displayName(tableName);
103
cleanTableName(displayName);
104
if (not ignoreTable(displayName))
107
query="SELECT TABLE_NAME, TABLE_COLLATION, ENGINE FROM DATA_DICTIONARY.TABLES WHERE TABLE_SCHEMA='";
108
query.append(databaseName);
109
query.append("' AND TABLE_NAME = '");
110
query.append(tableName);
113
result= dcon->query(query);
117
std::cerr << "Error: Could not obtain schema for table " << displayName << std::endl;
121
if ((row= drizzle_row_next(result)))
123
DrizzleDumpTableDrizzle *table = new DrizzleDumpTableDrizzle(tableName, dcon);
124
table->displayName= displayName;
125
table->collate= row[1];
126
table->engineName= row[2];
127
table->autoIncrement= 0;
128
table->database= this;
129
if ((not table->populateFields()) or (not table->populateIndexes()))
131
std::cerr << "Error: Could not get fields and/ot indexes for table " << displayName << std::endl;
133
dcon->freeResult(result);
134
if (not ignore_errors)
139
tables.push_back(table);
140
dcon->freeResult(result);
144
std::cerr << "Error: Table " << displayName << " not found." << std::endl;
145
dcon->freeResult(result);
146
if (not ignore_errors)
157
void DrizzleDumpDatabaseDrizzle::setCollate(const char* newCollate)
162
collate= "utf8_general_ci";
165
bool DrizzleDumpTableDrizzle::populateFields()
167
drizzle_result_st *result;
172
std::cerr << _("-- Retrieving fields for ") << tableName << "..." << std::endl;
174
query= "SELECT COLUMN_NAME, DATA_TYPE, COLUMN_DEFAULT, COLUMN_DEFAULT_IS_NULL, IS_NULLABLE, CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION, NUMERIC_SCALE, COLLATION_NAME, IS_AUTO_INCREMENT, ENUM_VALUES, COLUMN_COMMENT FROM DATA_DICTIONARY.COLUMNS WHERE TABLE_SCHEMA='";
175
query.append(database->databaseName);
176
query.append("' AND TABLE_NAME='");
177
query.append(tableName);
180
result= dcon->query(query);
185
while ((row= drizzle_row_next(result)))
187
std::string fieldName(row[0]);
188
DrizzleDumpField *field = new DrizzleDumpFieldDrizzle(fieldName, dcon);
189
/* Stop valgrind warning */
190
field->convertDateTime= false;
191
/* Also sets collation */
192
field->setType(row[1], row[8]);
194
field->defaultValue= row[2];
196
field->defaultValue= "";
198
field->isNull= (strcmp(row[4], "YES") == 0) ? true : false;
199
field->isAutoIncrement= (strcmp(row[9], "YES") == 0) ? true : false;
200
field->defaultIsNull= (strcmp(row[3], "YES") == 0) ? true : false;
201
field->enumValues= (row[10]) ? row[10] : "";
202
field->length= (row[5]) ? boost::lexical_cast<uint32_t>(row[5]) : 0;
203
field->decimalPrecision= (row[6]) ? boost::lexical_cast<uint32_t>(row[6]) : 0;
204
field->decimalScale= (row[7]) ? boost::lexical_cast<uint32_t>(row[7]) : 0;
205
field->comment= (row[11]) ? row[11] : "";
207
fields.push_back(field);
210
dcon->freeResult(result);
215
bool DrizzleDumpTableDrizzle::populateIndexes()
217
drizzle_result_st *result;
221
bool firstIndex= true;
222
DrizzleDumpIndex *index;
225
std::cerr << _("-- Retrieving indexes for ") << tableName << "..." << std::endl;
227
query= "SELECT INDEX_NAME, COLUMN_NAME, IS_USED_IN_PRIMARY, IS_UNIQUE, COMPARE_LENGTH FROM DATA_DICTIONARY.INDEX_PARTS WHERE TABLE_SCHEMA='";
228
query.append(database->databaseName);
229
query.append("' AND TABLE_NAME='");
230
query.append(tableName);
233
result= dcon->query(query);
238
while ((row= drizzle_row_next(result)))
240
std::string indexName(row[0]);
241
if (indexName.compare(lastKey) != 0)
244
indexes.push_back(index);
245
index = new DrizzleDumpIndexDrizzle(indexName, dcon);
246
index->isPrimary= (strcmp(row[0], "PRIMARY") == 0);
247
index->isUnique= (strcmp(row[3], "YES") == 0);
249
index->length= (row[4]) ? boost::lexical_cast<uint32_t>(row[4]) : 0;
253
index->columns.push_back(row[1]);
256
indexes.push_back(index);
258
dcon->freeResult(result);
262
bool DrizzleDumpTableDrizzle::populateFkeys()
264
drizzle_result_st *result;
267
DrizzleDumpForeignKey *fkey;
270
std::cerr << _("-- Retrieving foreign keys for ") << tableName << "..." << std::endl;
272
query= "SELECT CONSTRAINT_NAME, CONSTRAINT_COLUMNS, REFERENCED_TABLE_NAME, REFERENCED_TABLE_COLUMNS, MATCH_OPTION, DELETE_RULE, UPDATE_RULE FROM DATA_DICTIONARY.FOREIGN_KEYS WHERE CONSTRAINT_SCHEMA='";
273
query.append(database->databaseName);
274
query.append("' AND CONSTRAINT_TABLE='");
275
query.append(tableName);
278
result= dcon->query(query);
283
while ((row= drizzle_row_next(result)))
285
fkey= new DrizzleDumpForeignKey(row[0], dcon);
286
fkey->parentColumns= row[1];
287
fkey->childTable= row[2];
288
fkey->childColumns= row[3];
289
fkey->matchOption= (strcmp(row[4], "NONE") != 0) ? row[4] : "";
290
fkey->deleteRule= (strcmp(row[5], "UNDEFINED") != 0) ? row[5] : "";
291
fkey->updateRule= (strcmp(row[6], "UNDEFINED") != 0) ? row[6] : "";
293
fkeys.push_back(fkey);
295
dcon->freeResult(result);
299
DrizzleDumpData* DrizzleDumpTableDrizzle::getData(void)
303
return new DrizzleDumpDataDrizzle(this, dcon);
312
void DrizzleDumpFieldDrizzle::setType(const char* raw_type, const char* raw_collation)
314
collation= raw_collation;
315
if (strcmp(raw_type, "BLOB") == 0)
317
if (strcmp(raw_collation, "binary") != 0)
324
if (strcmp(raw_type, "VARCHAR") == 0)
326
if (strcmp(raw_collation, "binary") != 0)
333
if (strcmp(raw_type, "INTEGER") == 0)
342
DrizzleDumpDataDrizzle::DrizzleDumpDataDrizzle(DrizzleDumpTable *dataTable,
343
DrizzleDumpConnection *connection)
344
: DrizzleDumpData(dataTable, connection)
347
query= "SELECT * FROM `";
348
query.append(table->displayName);
351
result= dcon->query(query);
354
throw std::exception();
357
DrizzleDumpDataDrizzle::~DrizzleDumpDataDrizzle()
359
dcon->freeResult(result);