Drizzled Public API Documentation

drizzledump_drizzle.cc

00001 /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
00002  *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
00003  *
00004  *  Copyright (C) 2010 Andrew Hutchings
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; version 2 of the License.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with this program; if not, write to the Free Software
00017  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
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     /* Stop valgrind warning */
00193     field->convertDateTime= false;
00194     /* Also sets collation */
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 }