00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "drizzledump_data.h"
00021 #include "drizzledump_drizzle.h"
00022 #include "client_priv.h"
00023 #include <string>
00024 #include <iostream>
00025 #include <drizzled/gettext.h>
00026 #include <boost/lexical_cast.hpp>
00027
00028 extern bool verbose;
00029 extern bool ignore_errors;
00030
00031 bool DrizzleDumpDatabaseDrizzle::populateTables()
00032 {
00033 drizzle_result_st *result;
00034 drizzle_row_t row;
00035 std::string query;
00036
00037 if (not dcon->setDB(databaseName))
00038 return false;
00039
00040 if (verbose)
00041 std::cerr << _("-- Retrieving table structures for ") << databaseName << "..." << std::endl;
00042
00043 query="SELECT TABLE_NAME, TABLE_COLLATION, ENGINE, AUTO_INCREMENT, TABLE_COMMENT, IS_REPLICATED FROM DATA_DICTIONARY.TABLES WHERE TABLE_SCHEMA='";
00044 query.append(databaseName);
00045 query.append("' ORDER BY TABLE_NAME");
00046
00047 result= dcon->query(query);
00048
00049 if (result == NULL)
00050 return false;
00051
00052 while ((row= drizzle_row_next(result)))
00053 {
00054 size_t* row_sizes= drizzle_row_field_sizes(result);
00055 std::string tableName(row[0]);
00056 std::string displayName(tableName);
00057 cleanTableName(displayName);
00058 if (not ignoreTable(displayName))
00059 continue;
00060
00061 DrizzleDumpTable *table = new DrizzleDumpTableDrizzle(tableName, dcon);
00062 table->displayName= displayName;
00063 table->collate= row[1];
00064 table->engineName= row[2];
00065 table->autoIncrement= boost::lexical_cast<uint64_t>(row[3]);
00066 if (row[4])
00067 table->comment= DrizzleDumpData::escape(row[4], row_sizes[4]);
00068 else
00069 table->comment= "";
00070
00071 table->replicate= (strcmp(row[5], "1") == 0) ? true : false;
00072 table->database= this;
00073 if ((not table->populateFields()) or (not table->populateIndexes()) or
00074 (not table->populateFkeys()))
00075 {
00076 delete table;
00077 if (not ignore_errors)
00078 return false;
00079 else
00080 continue;
00081 }
00082 tables.push_back(table);
00083 }
00084
00085 dcon->freeResult(result);
00086
00087 return true;
00088 }
00089
00090 bool DrizzleDumpDatabaseDrizzle::populateTables(const std::vector<std::string> &table_names)
00091 {
00092 drizzle_result_st *result;
00093 drizzle_row_t row;
00094 std::string query;
00095
00096 if (not dcon->setDB(databaseName))
00097 return false;
00098
00099 if (verbose)
00100 std::cerr << _("-- Retrieving table structures for ") << databaseName << "..." << std::endl;
00101 for (std::vector<std::string>::const_iterator it= table_names.begin(); it != table_names.end(); ++it)
00102 {
00103 std::string tableName= *it;
00104 std::string displayName(tableName);
00105 cleanTableName(displayName);
00106 if (not ignoreTable(displayName))
00107 continue;
00108
00109 query="SELECT TABLE_NAME, TABLE_COLLATION, ENGINE, IS_REPLICATED FROM DATA_DICTIONARY.TABLES WHERE TABLE_SCHEMA='";
00110 query.append(databaseName);
00111 query.append("' AND TABLE_NAME = '");
00112 query.append(tableName);
00113 query.append("'");
00114
00115 result= dcon->query(query);
00116
00117 if (result == NULL)
00118 {
00119 std::cerr << "Error: Could not obtain schema for table " << displayName << std::endl;
00120 return false;
00121 }
00122
00123 if ((row= drizzle_row_next(result)))
00124 {
00125 DrizzleDumpTableDrizzle *table = new DrizzleDumpTableDrizzle(tableName, dcon);
00126 table->displayName= displayName;
00127 table->collate= row[1];
00128 table->engineName= row[2];
00129 table->replicate= (strcmp(row[3], "1") == 0) ? true : false;
00130 table->autoIncrement= 0;
00131 table->database= this;
00132 if ((not table->populateFields()) or (not table->populateIndexes()))
00133 {
00134 std::cerr << "Error: Could not get fields and/ot indexes for table " << displayName << std::endl;
00135 delete table;
00136 dcon->freeResult(result);
00137 if (not ignore_errors)
00138 return false;
00139 else
00140 continue;
00141 }
00142 tables.push_back(table);
00143 dcon->freeResult(result);
00144 }
00145 else
00146 {
00147 std::cerr << "Error: Table " << displayName << " not found." << std::endl;
00148 dcon->freeResult(result);
00149 if (not ignore_errors)
00150 return false;
00151 else
00152 continue;
00153 }
00154 }
00155
00156 return true;
00157
00158 }
00159
00160 void DrizzleDumpDatabaseDrizzle::setCollate(const char* newCollate)
00161 {
00162 if (newCollate)
00163 collate= newCollate;
00164 else
00165 collate= "utf8_general_ci";
00166 }
00167
00168 bool DrizzleDumpTableDrizzle::populateFields()
00169 {
00170 drizzle_result_st *result;
00171 drizzle_row_t row;
00172 std::string query;
00173
00174 if (verbose)
00175 std::cerr << _("-- Retrieving fields for ") << tableName << "..." << std::endl;
00176
00177 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='";
00178 query.append(database->databaseName);
00179 query.append("' AND TABLE_NAME='");
00180 query.append(tableName);
00181 query.append("'");
00182
00183 result= dcon->query(query);
00184
00185 if (result == NULL)
00186 return false;
00187
00188 while ((row= drizzle_row_next(result)))
00189 {
00190 std::string fieldName(row[0]);
00191 DrizzleDumpField *field = new DrizzleDumpFieldDrizzle(fieldName, dcon);
00192
00193 field->convertDateTime= false;
00194
00195 field->setType(row[1], row[8]);
00196 if (row[2])
00197 field->defaultValue= row[2];
00198 else
00199 field->defaultValue= "";
00200
00201 field->isNull= (boost::lexical_cast<uint32_t>(row[4])) ? true : false;
00202 field->isAutoIncrement= (boost::lexical_cast<uint32_t>(row[9])) ? true : false;
00203 field->defaultIsNull= (boost::lexical_cast<uint32_t>(row[3])) ? true : false;
00204 field->enumValues= (row[10]) ? row[10] : "";
00205 field->length= (row[5]) ? boost::lexical_cast<uint32_t>(row[5]) : 0;
00206 field->decimalPrecision= (row[6]) ? boost::lexical_cast<uint32_t>(row[6]) : 0;
00207 field->decimalScale= (row[7]) ? boost::lexical_cast<uint32_t>(row[7]) : 0;
00208 field->comment= (row[11]) ? row[11] : "";
00209
00210 fields.push_back(field);
00211 }
00212
00213 dcon->freeResult(result);
00214 return true;
00215 }
00216
00217
00218 bool DrizzleDumpTableDrizzle::populateIndexes()
00219 {
00220 drizzle_result_st *result;
00221 drizzle_row_t row;
00222 std::string query;
00223 std::string lastKey;
00224 bool firstIndex= true;
00225 DrizzleDumpIndex *index;
00226
00227 if (verbose)
00228 std::cerr << _("-- Retrieving indexes for ") << tableName << "..." << std::endl;
00229
00230 query= "SELECT INDEX_NAME, COLUMN_NAME, IS_USED_IN_PRIMARY, IS_UNIQUE, COMPARE_LENGTH FROM DATA_DICTIONARY.INDEX_PARTS WHERE TABLE_SCHEMA='";
00231 query.append(database->databaseName);
00232 query.append("' AND TABLE_NAME='");
00233 query.append(tableName);
00234 query.append("'");
00235
00236 result= dcon->query(query);
00237
00238 if (result == NULL)
00239 return false;
00240
00241 while ((row= drizzle_row_next(result)))
00242 {
00243 std::string indexName(row[0]);
00244 if (indexName.compare(lastKey) != 0)
00245 {
00246 if (!firstIndex)
00247 indexes.push_back(index);
00248 index = new DrizzleDumpIndexDrizzle(indexName, dcon);
00249 index->isPrimary= (strcmp(row[0], "PRIMARY") == 0);
00250 index->isUnique= boost::lexical_cast<uint32_t>(row[3]);
00251 index->isHash= 0;
00252 lastKey= row[0];
00253 firstIndex= false;
00254 }
00255 uint32_t length= (row[4]) ? boost::lexical_cast<uint32_t>(row[4]) : 0;
00256 index->columns.push_back(std::make_pair(row[1],length));
00257 }
00258 if (!firstIndex)
00259 indexes.push_back(index);
00260
00261 dcon->freeResult(result);
00262 return true;
00263 }
00264
00265 bool DrizzleDumpTableDrizzle::populateFkeys()
00266 {
00267 drizzle_result_st *result;
00268 drizzle_row_t row;
00269 std::string query;
00270 DrizzleDumpForeignKey *fkey;
00271
00272 if (verbose)
00273 std::cerr << _("-- Retrieving foreign keys for ") << tableName << "..." << std::endl;
00274
00275 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='";
00276 query.append(database->databaseName);
00277 query.append("' AND CONSTRAINT_TABLE='");
00278 query.append(tableName);
00279 query.append("'");
00280
00281 result= dcon->query(query);
00282
00283 if (result == NULL)
00284 return false;
00285
00286 while ((row= drizzle_row_next(result)))
00287 {
00288 fkey= new DrizzleDumpForeignKey(row[0], dcon);
00289 fkey->parentColumns= row[1];
00290 fkey->childTable= row[2];
00291 fkey->childColumns= row[3];
00292 fkey->matchOption= (strcmp(row[4], "NONE") != 0) ? row[4] : "";
00293 fkey->deleteRule= (strcmp(row[5], "UNDEFINED") != 0) ? row[5] : "";
00294 fkey->updateRule= (strcmp(row[6], "UNDEFINED") != 0) ? row[6] : "";
00295
00296 fkeys.push_back(fkey);
00297 }
00298 dcon->freeResult(result);
00299 return true;
00300 }
00301
00302 DrizzleDumpData* DrizzleDumpTableDrizzle::getData(void)
00303 {
00304 try
00305 {
00306 return new DrizzleDumpDataDrizzle(this, dcon);
00307 }
00308 catch(...)
00309 {
00310 return NULL;
00311 }
00312 }
00313
00314
00315 void DrizzleDumpFieldDrizzle::setType(const char* raw_type, const char* raw_collation)
00316 {
00317 collation= raw_collation;
00318 if (strcmp(raw_type, "BLOB") == 0)
00319 {
00320 if (strcmp(raw_collation, "binary") != 0)
00321 type= "TEXT";
00322 else
00323 type= raw_type;
00324 return;
00325 }
00326
00327 if (strcmp(raw_type, "VARCHAR") == 0)
00328 {
00329 if (strcmp(raw_collation, "binary") != 0)
00330 type= "VARCHAR";
00331 else
00332 type= "VARBINARY";
00333 return;
00334 }
00335
00336 if (strcmp(raw_type, "INTEGER") == 0)
00337 {
00338 type= "INT";
00339 return;
00340 }
00341
00342 type= raw_type;
00343 }
00344
00345 DrizzleDumpDataDrizzle::DrizzleDumpDataDrizzle(DrizzleDumpTable *dataTable,
00346 DrizzleDumpConnection *connection)
00347 : DrizzleDumpData(dataTable, connection)
00348 {
00349 std::string query;
00350 query= "SELECT * FROM `";
00351 query.append(table->displayName);
00352 query.append("`");
00353
00354 result= dcon->query(query);
00355
00356 if (result == NULL)
00357 throw std::exception();
00358 }
00359
00360 DrizzleDumpDataDrizzle::~DrizzleDumpDataDrizzle()
00361 {
00362 dcon->freeResult(result);
00363 }