00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
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,
00368 NULL,
00369 NULL
00370 }
00371 DRIZZLE_DECLARE_PLUGIN_END;