Drizzled Public API Documentation

table_writer.cc
00001 /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
00002  *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
00003  *
00004  *  Copyright (C) 2009 Sun Microsystems, Inc.
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 <config.h>
00021 
00022 #include <iostream>
00023 #include <fstream>
00024 #include <string>
00025 #include <drizzled/message/table.pb.h>
00026 
00027 #include <boost/program_options.hpp>
00028 
00029 using namespace std;
00030 using namespace drizzled;
00031 
00032 namespace po=boost::program_options;
00033 
00034 /*
00035   Written from Google proto example
00036 */
00037 
00038 static void fill_engine(message::Engine *engine)
00039 {
00040   engine->set_name("InnoDB");
00041   message::Engine::Option *option;
00042 
00043   string option_names[2]= {
00044     "INDEX_DIRECTORY"
00045     , "DATA_DIRECTORY"
00046   };
00047 
00048   string option_values[2]= {
00049     "/var/drizzle/indexdir"
00050     , "/var/drizzle/datadir"
00051   };
00052 
00053   /* Add some engine options */
00054   for (int16_t x= 0; x < 2; x++)
00055   {
00056     option= engine->add_options();
00057     option->set_name(option_names[x]);
00058     option->set_state(option_values[x]);
00059   }
00060 }
00061 
00062 static void new_index_to_table(message::Table *table,
00063                                const string name,
00064                                uint16_t num_index_parts,
00065                                uint32_t field_indexes[],
00066                                uint32_t compare_lengths[],
00067                                bool is_primary,
00068                                bool is_unique)
00069 {
00070   uint16_t x= 0;
00071 
00072   message::Table::Index *index;
00073   message::Table::Index::IndexPart *index_part;
00074 
00075   index= table->add_indexes();
00076 
00077   index->set_name(name);
00078   index->set_type(message::Table::Index::BTREE);
00079   index->set_is_primary(is_primary);
00080   index->set_is_unique(is_unique);
00081 
00082   int key_length= 0;
00083 
00084   for(int i=0; i< num_index_parts; i++)
00085     key_length+= compare_lengths[i];
00086 
00087   index->set_key_length(key_length);
00088 
00089   while (x < num_index_parts)
00090   {
00091     index_part= index->add_index_part();
00092 
00093     index_part->set_fieldnr(field_indexes[x]);
00094 
00095     if (compare_lengths[x] > 0)
00096       index_part->set_compare_length(compare_lengths[x]);
00097 
00098     x++;
00099   }
00100 }
00101 
00102 static void fill_table(message::Table *table, const char *name)
00103 {
00104   uint16_t x;
00105 
00106   message::Table::Field *field;
00107   message::Table::Field::FieldConstraints *field_constraints;
00108   message::Table::Field::StringFieldOptions *string_field_options;
00109   message::Table::Field::NumericFieldOptions *numeric_field_options;
00110   message::Table::Field::EnumerationValues *enumeration_options;
00111 
00112   table->set_name(name);
00113   table->set_type(message::Table::STANDARD);
00114 
00115   /* Write out some random varchar */
00116   for (x= 0; x < 3; x++)
00117   {
00118     char buffer[1024];
00119     field= table->add_field();
00120     field_constraints= field->mutable_constraints();
00121     string_field_options= field->mutable_string_options();
00122 
00123     snprintf(buffer, sizeof(buffer), "sample%u", x);
00124 
00125     field->set_name(buffer);
00126     field->set_type(message::Table::Field::VARCHAR);
00127 
00128     field_constraints->set_is_notnull((x % 2));
00129 
00130     string_field_options->set_length(rand() % 100);
00131 
00132     if (x % 3)
00133     {
00134       string_field_options->set_collation("utf8_swedish_ci");
00135     }
00136   }
00137 
00138   /* Write out an INTEGER */
00139   {
00140     field= table->add_field();
00141     field->set_name("number");
00142     field->set_type(message::Table::Field::INTEGER);
00143   }
00144   /* Write out a ENUM */
00145   {
00146     field= table->add_field();
00147     field->set_type(message::Table::Field::ENUM);
00148     field->set_name("colors");
00149 
00150     enumeration_options= field->mutable_enumeration_values();
00151     enumeration_options->add_field_value("red");
00152     enumeration_options->add_field_value("blue");
00153     enumeration_options->add_field_value("green");
00154   }
00155   /* Write out a BLOB */
00156   {
00157     field= table->add_field();
00158     field->set_name("some_btye_string");
00159     field->set_type(message::Table::Field::BLOB);
00160   }
00161 
00162   /* Write out a DECIMAL */
00163   {
00164     field= table->add_field();
00165     field->set_name("important_number");
00166     field->set_type(message::Table::Field::DECIMAL);
00167 
00168     field_constraints= field->mutable_constraints();
00169     field_constraints->set_is_notnull(false);
00170 
00171     numeric_field_options= field->mutable_numeric_options();
00172     numeric_field_options->set_precision(8);
00173     numeric_field_options->set_scale(3);
00174   }
00175 
00176   {
00177     uint32_t fields_in_index[1]= {6};
00178     uint32_t compare_lengths_in_index[1]= {0};
00179     bool is_unique= true;
00180     bool is_primary= false;
00181     /* Add a single-column index on important_number field */
00182     new_index_to_table(table, "idx_important_decimal", 1, fields_in_index, compare_lengths_in_index, is_primary, is_unique);
00183   }
00184 
00185   {
00186     /* Add a double-column index on first two varchar fields */
00187     uint32_t fields_in_index[2]= {0,1};
00188     uint32_t compare_lengths_in_index[2]= {20,35};
00189     bool is_unique= true;
00190     bool is_primary= true;
00191     new_index_to_table(table, "idx_varchar1_2", 2, fields_in_index, compare_lengths_in_index, is_primary, is_unique);
00192   }
00193 
00194   /* Do engine-specific stuff */
00195   message::Engine *engine= table->mutable_engine();
00196   fill_engine(engine);
00197 
00198 }
00199 
00200 static void fill_table1(message::Table *table)
00201 {
00202   message::Table::Field *field;
00203   message::Table::TableOptions *tableopts;
00204 
00205   table->set_name("t1");
00206   table->set_catalog("LOCAL");
00207   table->set_type(message::Table::INTERNAL);
00208 
00209   tableopts= table->mutable_options();
00210   tableopts->set_comment("Table without a StorageEngine message");
00211 
00212   {
00213     field= table->add_field();
00214     field->set_name("number");
00215     field->set_type(message::Table::Field::INTEGER);
00216   }
00217 
00218 }
00219 
00220 
00221 int main(int argc, char* argv[])
00222 {
00223   int table_number= 0;
00224 
00225   GOOGLE_PROTOBUF_VERIFY_VERSION;
00226 
00227   po::options_description desc("Allowed options");
00228   desc.add_options()
00229     ("help", "produce help message")
00230     ("table-number,t", po::value<int>(&table_number)->default_value(0), "Table Number");
00231 
00232   po::variables_map vm;
00233   po::positional_options_description p;
00234   p.add("table-name", 1);
00235 
00236   // Disable allow_guessing
00237   int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
00238 
00239   po::store(po::command_line_parser(argc, argv).options(desc).style(style).
00240             positional(p).run(), vm);
00241 
00242   if (not vm.count("table-name"))
00243   {
00244     fprintf(stderr, "Expected Table name argument\n\n");
00245     cerr << desc << endl;
00246     exit(EXIT_FAILURE);
00247   }
00248 
00249   message::Table table;
00250 
00251   switch (table_number)
00252   {
00253   case 0:
00254     fill_table(&table, "example_table");
00255     break;
00256   case 1:
00257     fill_table1(&table);
00258     break;
00259   default:
00260     fprintf(stderr, "Invalid table number.\n\n");
00261     cerr << desc << endl;
00262     exit(EXIT_FAILURE);
00263   }
00264 
00265   fstream output(vm["table-name"].as<string>().c_str(),
00266                  ios::out | ios::trunc | ios::binary);
00267   if (not table.SerializeToOstream(&output))
00268   {
00269     cerr << "Failed to write schema." << endl;
00270     return -1;
00271   }
00272 
00273   return 0;
00274 }