Drizzled Public API Documentation

table_writer.cc
1 /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3  *
4  * Copyright (C) 2009 Sun Microsystems, Inc.
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 
20 #include <config.h>
21 
22 #include <iostream>
23 #include <fstream>
24 #include <string>
25 #include <drizzled/message/table.pb.h>
26 
27 #include <boost/program_options.hpp>
28 
29 using namespace std;
30 using namespace drizzled;
31 
32 namespace po=boost::program_options;
33 
34 /*
35  Written from Google proto example
36 */
37 
38 static void fill_engine(message::Engine *engine)
39 {
40  engine->set_name("InnoDB");
42 
43  string option_names[2]= {
44  "INDEX_DIRECTORY"
45  , "DATA_DIRECTORY"
46  };
47 
48  string option_values[2]= {
49  "/var/drizzle/indexdir"
50  , "/var/drizzle/datadir"
51  };
52 
53  /* Add some engine options */
54  for (int16_t x= 0; x < 2; x++)
55  {
56  option= engine->add_options();
57  option->set_name(option_names[x]);
58  option->set_state(option_values[x]);
59  }
60 }
61 
62 static void new_index_to_table(message::Table *table,
63  const string name,
64  uint16_t num_index_parts,
65  uint32_t field_indexes[],
66  uint32_t compare_lengths[],
67  bool is_primary,
68  bool is_unique)
69 {
70  uint16_t x= 0;
71 
72  message::Table::Index *index;
74 
75  index= table->add_indexes();
76 
77  index->set_name(name);
78  index->set_type(message::Table::Index::BTREE);
79  index->set_is_primary(is_primary);
80  index->set_is_unique(is_unique);
81 
82  int key_length= 0;
83 
84  for(int i=0; i< num_index_parts; i++)
85  key_length+= compare_lengths[i];
86 
87  index->set_key_length(key_length);
88 
89  while (x < num_index_parts)
90  {
91  index_part= index->add_index_part();
92 
93  index_part->set_fieldnr(field_indexes[x]);
94 
95  if (compare_lengths[x] > 0)
96  index_part->set_compare_length(compare_lengths[x]);
97 
98  x++;
99  }
100 }
101 
102 static void fill_table(message::Table *table, const char *name)
103 {
104  uint16_t x;
105 
106  message::Table::Field *field;
107  message::Table::Field::FieldConstraints *field_constraints;
108  message::Table::Field::StringFieldOptions *string_field_options;
109  message::Table::Field::NumericFieldOptions *numeric_field_options;
110  message::Table::Field::EnumerationValues *enumeration_options;
111 
112  table->set_name(name);
113  table->set_type(message::Table::STANDARD);
114 
115  /* Write out some random varchar */
116  for (x= 0; x < 3; x++)
117  {
118  char buffer[1024];
119  field= table->add_field();
120  field_constraints= field->mutable_constraints();
121  string_field_options= field->mutable_string_options();
122 
123  snprintf(buffer, sizeof(buffer), "sample%u", x);
124 
125  field->set_name(buffer);
126  field->set_type(message::Table::Field::VARCHAR);
127 
128  field_constraints->set_is_notnull((x % 2));
129 
130  string_field_options->set_length(rand() % 100);
131 
132  if (x % 3)
133  {
134  string_field_options->set_collation("utf8_swedish_ci");
135  }
136  }
137 
138  /* Write out an INTEGER */
139  {
140  field= table->add_field();
141  field->set_name("number");
142  field->set_type(message::Table::Field::INTEGER);
143  }
144  /* Write out a ENUM */
145  {
146  field= table->add_field();
147  field->set_type(message::Table::Field::ENUM);
148  field->set_name("colors");
149 
150  enumeration_options= field->mutable_enumeration_values();
151  enumeration_options->add_field_value("red");
152  enumeration_options->add_field_value("blue");
153  enumeration_options->add_field_value("green");
154  }
155  /* Write out a BLOB */
156  {
157  field= table->add_field();
158  field->set_name("some_btye_string");
159  field->set_type(message::Table::Field::BLOB);
160  }
161 
162  /* Write out a DECIMAL */
163  {
164  field= table->add_field();
165  field->set_name("important_number");
166  field->set_type(message::Table::Field::DECIMAL);
167 
168  field_constraints= field->mutable_constraints();
169  field_constraints->set_is_notnull(false);
170 
171  numeric_field_options= field->mutable_numeric_options();
172  numeric_field_options->set_precision(8);
173  numeric_field_options->set_scale(3);
174  }
175 
176  {
177  uint32_t fields_in_index[1]= {6};
178  uint32_t compare_lengths_in_index[1]= {0};
179  bool is_unique= true;
180  bool is_primary= false;
181  /* Add a single-column index on important_number field */
182  new_index_to_table(table, "idx_important_decimal", 1, fields_in_index, compare_lengths_in_index, is_primary, is_unique);
183  }
184 
185  {
186  /* Add a double-column index on first two varchar fields */
187  uint32_t fields_in_index[2]= {0,1};
188  uint32_t compare_lengths_in_index[2]= {20,35};
189  bool is_unique= true;
190  bool is_primary= true;
191  new_index_to_table(table, "idx_varchar1_2", 2, fields_in_index, compare_lengths_in_index, is_primary, is_unique);
192  }
193 
194  /* Do engine-specific stuff */
195  message::Engine *engine= table->mutable_engine();
196  fill_engine(engine);
197 
198 }
199 
200 static void fill_table1(message::Table *table)
201 {
202  message::Table::Field *field;
203  message::Table::TableOptions *tableopts;
204 
205  table->set_name("t1");
206  table->set_catalog("LOCAL");
207  table->set_type(message::Table::INTERNAL);
208 
209  tableopts= table->mutable_options();
210  tableopts->set_comment("Table without a StorageEngine message");
211 
212  {
213  field= table->add_field();
214  field->set_name("number");
215  field->set_type(message::Table::Field::INTEGER);
216  }
217 
218 }
219 
220 
221 int main(int argc, char* argv[])
222 {
223  int table_number= 0;
224 
225  GOOGLE_PROTOBUF_VERIFY_VERSION;
226 
227  po::options_description desc("Allowed options");
228  desc.add_options()
229  ("help", "produce help message")
230  ("table-number,t", po::value<int>(&table_number)->default_value(0), "Table Number");
231 
232  po::variables_map vm;
233  po::positional_options_description p;
234  p.add("table-name", 1);
235 
236  // Disable allow_guessing
237  int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
238 
239  po::store(po::command_line_parser(argc, argv).options(desc).style(style).
240  positional(p).run(), vm);
241 
242  if (not vm.count("table-name"))
243  {
244  fprintf(stderr, "Expected Table name argument\n\n");
245  cerr << desc << endl;
246  exit(EXIT_FAILURE);
247  }
248 
249  message::Table table;
250 
251  switch (table_number)
252  {
253  case 0:
254  fill_table(&table, "example_table");
255  break;
256  case 1:
257  fill_table1(&table);
258  break;
259  default:
260  fprintf(stderr, "Invalid table number.\n\n");
261  cerr << desc << endl;
262  exit(EXIT_FAILURE);
263  }
264 
265  fstream output(vm["table-name"].as<string>().c_str(),
266  ios::out | ios::trunc | ios::binary);
267  if (not table.SerializeToOstream(&output))
268  {
269  cerr << "Failed to write schema." << endl;
270  return -1;
271  }
272 
273  return 0;
274 }
TODO: Rename this file - func.h is stupid.