Drizzled Public API Documentation

tableprototester.cc
1 /*
2  Copyright (C) 2010 Stewart Smith
3 
4  This program is free software; you can redistribute it and/or
5  modify it under the terms of the GNU General Public License
6  as published by the Free Software Foundation; either version 2
7  of the License, or (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18 
19 #include <config.h>
20 
21 #include "tableprototester.h"
22 
23 #include <fcntl.h>
24 
25 #include <string>
26 #include <map>
27 #include <fstream>
28 
29 #include <drizzled/error.h>
30 #include <drizzled/charset.h>
31 #include <drizzled/internal/m_string.h>
32 #include <drizzled/internal/my_pthread.h>
33 #include <drizzled/message/table.h>
34 #include <drizzled/plugin/storage_engine.h>
35 #include <drizzled/table.h>
36 
37 
38 using namespace std;
39 using namespace google;
40 using namespace drizzled;
41 
42 #define TABLEPROTOTESTER_EXT ".TBT"
43 
44 static const char *TableProtoTesterCursor_exts[] = {
45  NULL
46 };
47 
49 {
50 public:
51  TableProtoTesterEngine(const string &name_arg)
53  HTON_NULL_IN_KEY |
54  HTON_CAN_INDEX_BLOBS |
55  HTON_SKIP_STORE_LOCK |
56  HTON_AUTO_PART_KEY)
57  {
58  table_definition_ext= TABLEPROTOTESTER_EXT;
59  }
60 
61  virtual Cursor *create(Table &table)
62  {
63  return new TableProtoTesterCursor(*this, table);
64  }
65 
66  const char **bas_ext() const {
67  return TableProtoTesterCursor_exts;
68  }
69 
70  int doCreateTable(Session&,
71  Table&,
72  const drizzled::identifier::Table &identifier,
74 
75  int doDropTable(Session&, const drizzled::identifier::Table &identifier);
76 
77  int doGetTableDefinition(Session &session,
78  const drizzled::identifier::Table &identifier,
79  drizzled::message::Table &table_proto);
80 
81  /* The following defines can be increased if necessary */
82  uint32_t max_supported_keys() const { return 64; }
83  uint32_t max_supported_key_length() const { return 1000; }
84  uint32_t max_supported_key_part_length() const { return 1000; }
85 
86  uint32_t index_flags(enum ha_key_alg) const
87  {
88  return (HA_READ_NEXT |
89  HA_READ_PREV |
90  HA_READ_RANGE |
91  HA_READ_ORDER |
92  HA_KEYREAD_ONLY);
93  }
94 
95  bool doDoesTableExist(Session &session, const drizzled::identifier::Table &identifier);
96 
97  int doRenameTable(Session&, const drizzled::identifier::Table&, const drizzled::identifier::Table&)
98  {
99  return HA_ERR_NO_SUCH_TABLE;
100  }
101 
102  void doGetTableIdentifiers(drizzled::CachedDirectory &directory,
103  const drizzled::identifier::Schema &schema_identifier,
104  drizzled::identifier::table::vector &set_of_identifiers);
105 };
106 
107 void TableProtoTesterEngine::doGetTableIdentifiers(drizzled::CachedDirectory&,
108  const drizzled::identifier::Schema &schema_identifier,
109  drizzled::identifier::table::vector &set_of_identifiers)
110 {
111  if (schema_identifier.compare("test"))
112  {
113  set_of_identifiers.push_back(identifier::Table(schema_identifier, "t1"));
114  set_of_identifiers.push_back(identifier::Table(schema_identifier, "too_many_enum_values"));
115  set_of_identifiers.push_back(identifier::Table(schema_identifier, "invalid_table_collation"));
116  }
117 }
118 
119 bool TableProtoTesterEngine::doDoesTableExist(Session&, const drizzled::identifier::Table &identifier)
120 {
121  if (not identifier.getPath().compare("test/t1"))
122  return true;
123  if (not identifier.getPath().compare("test/too_many_enum_values"))
124  return true;
125  if (not identifier.getPath().compare("test/invalid_table_collation"))
126  return true;
127 
128  return false;
129 }
130 
131 TableProtoTesterCursor::TableProtoTesterCursor(drizzled::plugin::StorageEngine &engine_arg,
132  Table &table_arg) :
133  Cursor(engine_arg, table_arg)
134 { }
135 
136 int TableProtoTesterCursor::open(const char *, int, uint32_t)
137 {
138  return 0;
139 }
140 
141 int TableProtoTesterCursor::close(void)
142 {
143  return 0;
144 }
145 
146 int TableProtoTesterEngine::doCreateTable(Session&,
147  Table&,
150 {
151  return EEXIST;
152 }
153 
154 
156 {
157  return HA_ERR_NO_SUCH_TABLE;
158 }
159 
160 static void fill_table1(message::Table &table)
161 {
162  message::Table::Field *field;
163  message::Table::TableOptions *tableopts;
164 
165  table.set_name("t1");
166  table.set_type(message::Table::INTERNAL);
167 
168  tableopts= table.mutable_options();
169  tableopts->set_comment("Table without a StorageEngine message");
170 
171  {
172  field= table.add_field();
173  field->set_name("number");
174  field->set_type(message::Table::Field::INTEGER);
175  }
176 
177 }
178 
179 static void fill_table_too_many_enum_values(message::Table &table)
180 {
181  message::Table::Field *field;
182  message::Table::TableOptions *tableopts;
183 
184  table.set_schema("test");
185  table.set_name("too_many_enum_values");
186  table.set_type(message::Table::STANDARD);
187  table.mutable_engine()->set_name("tableprototester");
188  table.set_creation_timestamp(0);
189  table.set_update_timestamp(0);
190 
191  tableopts= table.mutable_options();
192  tableopts->set_comment("Table with too many enum options");
193  tableopts->set_collation("utf8_general_ci");
194  tableopts->set_collation_id(45);
195 
196  {
197  field= table.add_field();
198  field->set_name("many_values");
199  field->set_type(message::Table::Field::ENUM);
200 
201  message::Table::Field::EnumerationValues *field_options= field->mutable_enumeration_values();
202  for(int i=0; i<70000; i++)
203  {
204  char enum_value[100];
205  snprintf(enum_value, sizeof(enum_value), "a%d", i);
206  field_options->add_field_value(enum_value);
207  }
208  }
209 
210 }
211 
212 static void fill_table_invalid_table_collation(message::Table &table)
213 {
214  message::Table::Field *field;
215  message::Table::TableOptions *tableopts;
216 
217  table.set_name("invalid_table_collation");
218  table.set_type(message::Table::STANDARD);
219  table.set_schema("test");
220  table.set_creation_timestamp(0);
221  table.set_update_timestamp(0);
222  table.mutable_engine()->set_name("tableprototester");
223 
224  tableopts= table.mutable_options();
225  tableopts->set_comment("Invalid table collation ");
226 
227  {
228  field= table.add_field();
229  field->set_name("number");
230  field->set_type(message::Table::Field::INTEGER);
231  }
232 
233  tableopts->set_collation("pi_pi_pi");
234  tableopts->set_collation_id(123456);
235 
236 }
237 
238 int TableProtoTesterEngine::doGetTableDefinition(Session&,
239  const drizzled::identifier::Table &identifier,
240  drizzled::message::Table &table_proto)
241 {
242  if (not identifier.getPath().compare("test/t1"))
243  {
244  fill_table1(table_proto);
245  return EEXIST;
246  }
247  else if (not identifier.getPath().compare("test/too_many_enum_values"))
248  {
249  fill_table_too_many_enum_values(table_proto);
250  return EEXIST;
251  }
252  else if (not identifier.getPath().compare("test/invalid_table_collation"))
253  {
254  fill_table_invalid_table_collation(table_proto);
255  return EEXIST;
256  }
257  return ENOENT;
258 }
259 
260 const char *TableProtoTesterCursor::index_type(uint32_t)
261 {
262  return("BTREE");
263 }
264 
265 int TableProtoTesterCursor::doInsertRecord(unsigned char *)
266 {
267  return(getTable()->next_number_field ? update_auto_increment() : 0);
268 }
269 
271 {
272  return(0);
273 }
274 
275 
276 int TableProtoTesterCursor::rnd_next(unsigned char *)
277 {
278  return(HA_ERR_END_OF_FILE);
279 }
280 
281 
282 int TableProtoTesterCursor::rnd_pos(unsigned char *, unsigned char *)
283 {
284  assert(0);
285  return(0);
286 }
287 
288 
289 void TableProtoTesterCursor::position(const unsigned char *)
290 {
291  assert(0);
292  return;
293 }
294 
295 
296 int TableProtoTesterCursor::info(uint32_t flag)
297 {
298  memset(&stats, 0, sizeof(stats));
299  if (flag & HA_STATUS_AUTO)
300  stats.auto_increment_value= 1;
301  return(0);
302 }
303 
304 
305 int TableProtoTesterCursor::index_read_map(unsigned char *, const unsigned char *,
306  key_part_map, enum ha_rkey_function)
307 {
308  return(HA_ERR_END_OF_FILE);
309 }
310 
311 
312 int TableProtoTesterCursor::index_read_idx_map(unsigned char *, uint32_t, const unsigned char *,
313  key_part_map, enum ha_rkey_function)
314 {
315  return(HA_ERR_END_OF_FILE);
316 }
317 
318 
319 int TableProtoTesterCursor::index_read_last_map(unsigned char *, const unsigned char *, key_part_map)
320 {
321  return(HA_ERR_END_OF_FILE);
322 }
323 
324 
325 int TableProtoTesterCursor::index_next(unsigned char *)
326 {
327  return(HA_ERR_END_OF_FILE);
328 }
329 
330 
331 int TableProtoTesterCursor::index_prev(unsigned char *)
332 {
333  return(HA_ERR_END_OF_FILE);
334 }
335 
336 
337 int TableProtoTesterCursor::index_first(unsigned char *)
338 {
339  return(HA_ERR_END_OF_FILE);
340 }
341 
342 
343 int TableProtoTesterCursor::index_last(unsigned char *)
344 {
345  return(HA_ERR_END_OF_FILE);
346 }
347 
348 static drizzled::plugin::StorageEngine *tableprototester_engine= NULL;
349 
350 static int tableprototester_init(drizzled::module::Context &context)
351 {
352 
353  tableprototester_engine= new TableProtoTesterEngine("TABLEPROTOTESTER");
354  context.add(tableprototester_engine);
355 
356  return 0;
357 }
358 
359 DRIZZLE_DECLARE_PLUGIN
360 {
361  DRIZZLE_VERSION_ID,
362  "TABLEPROTOTESTER",
363  "1.0",
364  "Stewart Smith",
365  N_("StorageEngine module for testing table proto messages"),
366  PLUGIN_LICENSE_GPL,
367  tableprototester_init,
368  NULL,
369  NULL
370 }
371 DRIZZLE_DECLARE_PLUGIN_END;