Drizzled Public API Documentation

tableprototester.cc

00001 /*
00002   Copyright (C) 2010 Stewart Smith
00003 
00004   This program is free software; you can redistribute it and/or
00005   modify it under the terms of the GNU General Public License
00006   as published by the Free Software Foundation; either version 2
00007   of the License, or (at your option) any later version.
00008 
00009   This program is distributed in the hope that it will be useful,
00010   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012   GNU General Public License for more details.
00013 
00014   You should have received a copy of the GNU General Public License
00015   along with this program; if not, write to the Free Software
00016   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00017 */
00018 
00019 #include <config.h>
00020 
00021 #include "tableprototester.h"
00022 
00023 #include <fcntl.h>
00024 
00025 #include <string>
00026 #include <map>
00027 #include <fstream>
00028 
00029 #include <drizzled/error.h>
00030 #include <drizzled/global_charset_info.h>
00031 #include <drizzled/internal/m_string.h>
00032 #include <drizzled/internal/my_pthread.h>
00033 #include <drizzled/message/table.h>
00034 #include <drizzled/plugin/storage_engine.h>
00035 #include <drizzled/table.h>
00036 
00037 
00038 using namespace std;
00039 using namespace google;
00040 using namespace drizzled;
00041 
00042 #define TABLEPROTOTESTER_EXT ".TBT"
00043 
00044 static const char *TableProtoTesterCursor_exts[] = {
00045   NULL
00046 };
00047 
00048 class TableProtoTesterEngine : public drizzled::plugin::StorageEngine
00049 {
00050 public:
00051   TableProtoTesterEngine(const string &name_arg)
00052    : drizzled::plugin::StorageEngine(name_arg,
00053                                      HTON_NULL_IN_KEY |
00054                                      HTON_CAN_INDEX_BLOBS |
00055                                      HTON_SKIP_STORE_LOCK |
00056                                      HTON_AUTO_PART_KEY)
00057   {
00058     table_definition_ext= TABLEPROTOTESTER_EXT;
00059   }
00060 
00061   virtual Cursor *create(Table &table)
00062   {
00063     return new TableProtoTesterCursor(*this, table);
00064   }
00065 
00066   const char **bas_ext() const {
00067     return TableProtoTesterCursor_exts;
00068   }
00069 
00070   int doCreateTable(Session&,
00071                     Table&,
00072                     const drizzled::identifier::Table &identifier,
00073                     const drizzled::message::Table&);
00074 
00075   int doDropTable(Session&, const drizzled::identifier::Table &identifier);
00076 
00077   int doGetTableDefinition(Session &session,
00078                            const drizzled::identifier::Table &identifier,
00079                            drizzled::message::Table &table_proto);
00080 
00081   /* The following defines can be increased if necessary */
00082   uint32_t max_supported_keys()          const { return 64; }
00083   uint32_t max_supported_key_length()    const { return 1000; }
00084   uint32_t max_supported_key_part_length() const { return 1000; }
00085 
00086   uint32_t index_flags(enum  ha_key_alg) const
00087   {
00088     return (HA_READ_NEXT |
00089             HA_READ_PREV |
00090             HA_READ_RANGE |
00091             HA_READ_ORDER |
00092             HA_KEYREAD_ONLY);
00093   }
00094 
00095   bool doDoesTableExist(Session &session, const drizzled::identifier::Table &identifier);
00096 
00097   int doRenameTable(Session&, const drizzled::identifier::Table&, const drizzled::identifier::Table&)
00098   {
00099     return HA_ERR_NO_SUCH_TABLE;
00100   }
00101 
00102   void doGetTableIdentifiers(drizzled::CachedDirectory &directory,
00103                              const drizzled::identifier::Schema &schema_identifier,
00104                              drizzled::identifier::Table::vector &set_of_identifiers);
00105 };
00106 
00107 void TableProtoTesterEngine::doGetTableIdentifiers(drizzled::CachedDirectory&,
00108                                                    const drizzled::identifier::Schema &schema_identifier,
00109                                                    drizzled::identifier::Table::vector &set_of_identifiers)
00110 {
00111   if (schema_identifier.compare("test"))
00112   {
00113     set_of_identifiers.push_back(identifier::Table(schema_identifier, "t1"));
00114     set_of_identifiers.push_back(identifier::Table(schema_identifier, "too_many_enum_values"));
00115     set_of_identifiers.push_back(identifier::Table(schema_identifier, "invalid_table_collation"));
00116   }
00117 }
00118 
00119 bool TableProtoTesterEngine::doDoesTableExist(Session&, const drizzled::identifier::Table &identifier)
00120 {
00121   if (not identifier.getPath().compare("test/t1"))
00122     return true;
00123   if (not identifier.getPath().compare("test/too_many_enum_values"))
00124     return true;
00125   if (not identifier.getPath().compare("test/invalid_table_collation"))
00126     return true;
00127 
00128   return false;
00129 }
00130 
00131 TableProtoTesterCursor::TableProtoTesterCursor(drizzled::plugin::StorageEngine &engine_arg,
00132                                                Table &table_arg) :
00133   Cursor(engine_arg, table_arg)
00134 { }
00135 
00136 int TableProtoTesterCursor::open(const char *, int, uint32_t)
00137 {
00138   return 0;
00139 }
00140 
00141 int TableProtoTesterCursor::close(void)
00142 {
00143   return 0;
00144 }
00145 
00146 int TableProtoTesterEngine::doCreateTable(Session&,
00147                                           Table&,
00148                                           const drizzled::identifier::Table&,
00149                                           const drizzled::message::Table&)
00150 {
00151   return EEXIST;
00152 }
00153 
00154 
00155 int TableProtoTesterEngine::doDropTable(Session&, const drizzled::identifier::Table&)
00156 {
00157   return HA_ERR_NO_SUCH_TABLE;
00158 }
00159 
00160 static void fill_table1(message::Table &table)
00161 {
00162   message::Table::Field *field;
00163   message::Table::TableOptions *tableopts;
00164 
00165   table.set_name("t1");
00166   table.set_type(message::Table::INTERNAL);
00167 
00168   tableopts= table.mutable_options();
00169   tableopts->set_comment("Table without a StorageEngine message");
00170 
00171   {
00172     field= table.add_field();
00173     field->set_name("number");
00174     field->set_type(message::Table::Field::INTEGER);
00175   }
00176 
00177 }
00178 
00179 static void fill_table_too_many_enum_values(message::Table &table)
00180 {
00181   message::Table::Field *field;
00182   message::Table::TableOptions *tableopts;
00183 
00184   table.set_schema("test");
00185   table.set_name("too_many_enum_values");
00186   table.set_type(message::Table::STANDARD);
00187   table.mutable_engine()->set_name("tableprototester");
00188   table.set_creation_timestamp(0);
00189   table.set_update_timestamp(0);
00190 
00191   tableopts= table.mutable_options();
00192   tableopts->set_comment("Table with too many enum options");
00193   tableopts->set_collation("utf8_general_ci");
00194   tableopts->set_collation_id(45);
00195 
00196   {
00197     field= table.add_field();
00198     field->set_name("many_values");
00199     field->set_type(message::Table::Field::ENUM);
00200 
00201     message::Table::Field::EnumerationValues *field_options= field->mutable_enumeration_values();
00202     for(int i=0; i<70000; i++)
00203     {
00204       char enum_value[100];
00205       snprintf(enum_value, sizeof(enum_value), "a%d", i);
00206       field_options->add_field_value(enum_value);
00207     }
00208   }
00209 
00210 }
00211 
00212 static void fill_table_invalid_table_collation(message::Table &table)
00213 {
00214   message::Table::Field *field;
00215   message::Table::TableOptions *tableopts;
00216 
00217   table.set_name("invalid_table_collation");
00218   table.set_type(message::Table::STANDARD);
00219   table.set_schema("test");
00220   table.set_creation_timestamp(0);
00221   table.set_update_timestamp(0);
00222   table.mutable_engine()->set_name("tableprototester");
00223 
00224   tableopts= table.mutable_options();
00225   tableopts->set_comment("Invalid table collation ");
00226 
00227   {
00228     field= table.add_field();
00229     field->set_name("number");
00230     field->set_type(message::Table::Field::INTEGER);
00231   }
00232 
00233   tableopts->set_collation("pi_pi_pi");
00234   tableopts->set_collation_id(123456);
00235 
00236 }
00237 
00238 int TableProtoTesterEngine::doGetTableDefinition(Session&,
00239                                                  const drizzled::identifier::Table &identifier,
00240                                                  drizzled::message::Table &table_proto)
00241 {
00242   if (not identifier.getPath().compare("test/t1"))
00243   {
00244     fill_table1(table_proto);
00245     return EEXIST;
00246   }
00247   else if (not identifier.getPath().compare("test/too_many_enum_values"))
00248   {
00249     fill_table_too_many_enum_values(table_proto);
00250     return EEXIST;
00251   }
00252   else if (not identifier.getPath().compare("test/invalid_table_collation"))
00253   {
00254     fill_table_invalid_table_collation(table_proto);
00255     return EEXIST;
00256   }
00257   return ENOENT;
00258 }
00259 
00260 const char *TableProtoTesterCursor::index_type(uint32_t)
00261 {
00262   return("BTREE");
00263 }
00264 
00265 int TableProtoTesterCursor::doInsertRecord(unsigned char *)
00266 {
00267   return(getTable()->next_number_field ? update_auto_increment() : 0);
00268 }
00269 
00270 int TableProtoTesterCursor::doStartTableScan(bool)
00271 {
00272   return(0);
00273 }
00274 
00275 
00276 int TableProtoTesterCursor::rnd_next(unsigned char *)
00277 {
00278   return(HA_ERR_END_OF_FILE);
00279 }
00280 
00281 
00282 int TableProtoTesterCursor::rnd_pos(unsigned char *, unsigned char *)
00283 {
00284   assert(0);
00285   return(0);
00286 }
00287 
00288 
00289 void TableProtoTesterCursor::position(const unsigned char *)
00290 {
00291   assert(0);
00292   return;
00293 }
00294 
00295 
00296 int TableProtoTesterCursor::info(uint32_t flag)
00297 {
00298   memset(&stats, 0, sizeof(stats));
00299   if (flag & HA_STATUS_AUTO)
00300     stats.auto_increment_value= 1;
00301   return(0);
00302 }
00303 
00304 
00305 int TableProtoTesterCursor::index_read_map(unsigned char *, const unsigned char *,
00306                                  key_part_map, enum ha_rkey_function)
00307 {
00308   return(HA_ERR_END_OF_FILE);
00309 }
00310 
00311 
00312 int TableProtoTesterCursor::index_read_idx_map(unsigned char *, uint32_t, const unsigned char *,
00313                                      key_part_map, enum ha_rkey_function)
00314 {
00315   return(HA_ERR_END_OF_FILE);
00316 }
00317 
00318 
00319 int TableProtoTesterCursor::index_read_last_map(unsigned char *, const unsigned char *, key_part_map)
00320 {
00321   return(HA_ERR_END_OF_FILE);
00322 }
00323 
00324 
00325 int TableProtoTesterCursor::index_next(unsigned char *)
00326 {
00327   return(HA_ERR_END_OF_FILE);
00328 }
00329 
00330 
00331 int TableProtoTesterCursor::index_prev(unsigned char *)
00332 {
00333   return(HA_ERR_END_OF_FILE);
00334 }
00335 
00336 
00337 int TableProtoTesterCursor::index_first(unsigned char *)
00338 {
00339   return(HA_ERR_END_OF_FILE);
00340 }
00341 
00342 
00343 int TableProtoTesterCursor::index_last(unsigned char *)
00344 {
00345   return(HA_ERR_END_OF_FILE);
00346 }
00347 
00348 static drizzled::plugin::StorageEngine *tableprototester_engine= NULL;
00349 
00350 static int tableprototester_init(drizzled::module::Context &context)
00351 {
00352 
00353   tableprototester_engine= new TableProtoTesterEngine("TABLEPROTOTESTER");
00354   context.add(tableprototester_engine);
00355 
00356   return 0;
00357 }
00358 
00359 DRIZZLE_DECLARE_PLUGIN
00360 {
00361   DRIZZLE_VERSION_ID,
00362   "TABLEPROTOTESTER",
00363   "1.0",
00364   "Stewart Smith",
00365   "Used to test rest of server with various table proto messages",
00366   PLUGIN_LICENSE_GPL,
00367   tableprototester_init,     /* Plugin Init */
00368   NULL,               /* depends */
00369   NULL                /* config options   */
00370 }
00371 DRIZZLE_DECLARE_PLUGIN_END;