Drizzled Public API Documentation

storage_engine.h
00001 /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
00002  *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
00003  *
00004  *  Copyright (C) 2008 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 #pragma once
00021 
00022 #include <drizzled/definitions.h>
00023 #include <drizzled/error_t.h>
00024 #include <drizzled/handler_structs.h>
00025 #include <drizzled/message.h>
00026 #include <drizzled/message/cache.h>
00027 #include <drizzled/plugin.h>
00028 #include <drizzled/plugin/monitored_in_transaction.h>
00029 #include <drizzled/plugin/plugin.h>
00030 #include <drizzled/sql_string.h>
00031 
00032 #include <bitset>
00033 #include <string>
00034 #include <vector>
00035 #include <set>
00036 
00037 #include <drizzled/visibility.h>
00038 
00039 namespace drizzled {
00040 
00041 struct HASH;
00042 
00043 typedef bool (stat_print_fn)(Session *session, const char *type, uint32_t type_len,
00044                              const char *file, uint32_t file_len,
00045                              const char *status, uint32_t status_len);
00046 
00047 /* Possible flags of a StorageEngine (there can be 32 of them) */
00048 enum engine_flag_bits {
00049   HTON_BIT_ALTER_NOT_SUPPORTED,       // Engine does not support alter
00050   HTON_BIT_HIDDEN,                    // Engine does not appear in lists
00051   HTON_BIT_NOT_USER_SELECTABLE,
00052   HTON_BIT_TEMPORARY_NOT_SUPPORTED,   // Having temporary tables not supported
00053   HTON_BIT_TEMPORARY_ONLY,
00054   HTON_BIT_DOES_TRANSACTIONS,
00055   HTON_BIT_STATS_RECORDS_IS_EXACT,
00056   HTON_BIT_NULL_IN_KEY,
00057   HTON_BIT_CAN_INDEX_BLOBS,
00058   HTON_BIT_PRIMARY_KEY_IN_READ_INDEX,
00059   HTON_BIT_PARTIAL_COLUMN_READ,
00060   HTON_BIT_TABLE_SCAN_ON_INDEX,
00061   HTON_BIT_FAST_KEY_READ,
00062   HTON_BIT_NO_BLOBS,
00063   HTON_BIT_HAS_RECORDS,
00064   HTON_BIT_NO_AUTO_INCREMENT,
00065   HTON_BIT_DUPLICATE_POS,
00066   HTON_BIT_AUTO_PART_KEY,
00067   HTON_BIT_REQUIRE_PRIMARY_KEY,
00068   HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE,
00069   HTON_BIT_PRIMARY_KEY_REQUIRED_FOR_DELETE,
00070   HTON_BIT_NO_PREFIX_CHAR_KEYS,
00071   HTON_BIT_HAS_CHECKSUM,
00072   HTON_BIT_SKIP_STORE_LOCK,
00073   HTON_BIT_SCHEMA_DICTIONARY,
00074   HTON_BIT_FOREIGN_KEYS,
00075   HTON_BIT_SIZE
00076 };
00077 
00078 static const std::bitset<HTON_BIT_SIZE> HTON_NO_FLAGS(0);
00079 static const std::bitset<HTON_BIT_SIZE> HTON_ALTER_NOT_SUPPORTED(1 << HTON_BIT_ALTER_NOT_SUPPORTED);
00080 static const std::bitset<HTON_BIT_SIZE> HTON_HIDDEN(1 << HTON_BIT_HIDDEN);
00081 static const std::bitset<HTON_BIT_SIZE> HTON_NOT_USER_SELECTABLE(1 << HTON_BIT_NOT_USER_SELECTABLE);
00082 static const std::bitset<HTON_BIT_SIZE> HTON_TEMPORARY_NOT_SUPPORTED(1 << HTON_BIT_TEMPORARY_NOT_SUPPORTED);
00083 static const std::bitset<HTON_BIT_SIZE> HTON_TEMPORARY_ONLY(1 << HTON_BIT_TEMPORARY_ONLY);
00084 static const std::bitset<HTON_BIT_SIZE> HTON_HAS_DOES_TRANSACTIONS(1 << HTON_BIT_DOES_TRANSACTIONS);
00085 static const std::bitset<HTON_BIT_SIZE> HTON_STATS_RECORDS_IS_EXACT(1 << HTON_BIT_STATS_RECORDS_IS_EXACT);
00086 static const std::bitset<HTON_BIT_SIZE> HTON_NULL_IN_KEY(1 << HTON_BIT_NULL_IN_KEY);
00087 static const std::bitset<HTON_BIT_SIZE> HTON_CAN_INDEX_BLOBS(1 << HTON_BIT_CAN_INDEX_BLOBS);
00088 static const std::bitset<HTON_BIT_SIZE> HTON_PRIMARY_KEY_IN_READ_INDEX(1 << HTON_BIT_PRIMARY_KEY_IN_READ_INDEX);
00089 static const std::bitset<HTON_BIT_SIZE> HTON_PARTIAL_COLUMN_READ(1 << HTON_BIT_PARTIAL_COLUMN_READ);
00090 static const std::bitset<HTON_BIT_SIZE> HTON_TABLE_SCAN_ON_INDEX(1 << HTON_BIT_TABLE_SCAN_ON_INDEX);
00091 static const std::bitset<HTON_BIT_SIZE> HTON_FAST_KEY_READ(1 << HTON_BIT_FAST_KEY_READ);
00092 static const std::bitset<HTON_BIT_SIZE> HTON_NO_BLOBS(1 << HTON_BIT_NO_BLOBS);
00093 static const std::bitset<HTON_BIT_SIZE> HTON_HAS_RECORDS(1 << HTON_BIT_HAS_RECORDS);
00094 static const std::bitset<HTON_BIT_SIZE> HTON_NO_AUTO_INCREMENT(1 << HTON_BIT_NO_AUTO_INCREMENT);
00095 static const std::bitset<HTON_BIT_SIZE> HTON_DUPLICATE_POS(1 << HTON_BIT_DUPLICATE_POS);
00096 static const std::bitset<HTON_BIT_SIZE> HTON_AUTO_PART_KEY(1 << HTON_BIT_AUTO_PART_KEY);
00097 static const std::bitset<HTON_BIT_SIZE> HTON_REQUIRE_PRIMARY_KEY(1 << HTON_BIT_REQUIRE_PRIMARY_KEY);
00098 static const std::bitset<HTON_BIT_SIZE> HTON_REQUIRES_KEY_COLUMNS_FOR_DELETE(1 << HTON_BIT_REQUIRES_KEY_COLUMNS_FOR_DELETE);
00099 static const std::bitset<HTON_BIT_SIZE> HTON_PRIMARY_KEY_REQUIRED_FOR_DELETE(1 << HTON_BIT_PRIMARY_KEY_REQUIRED_FOR_DELETE);
00100 static const std::bitset<HTON_BIT_SIZE> HTON_NO_PREFIX_CHAR_KEYS(1 << HTON_BIT_NO_PREFIX_CHAR_KEYS);
00101 static const std::bitset<HTON_BIT_SIZE> HTON_HAS_CHECKSUM(1 << HTON_BIT_HAS_CHECKSUM);
00102 static const std::bitset<HTON_BIT_SIZE> HTON_SKIP_STORE_LOCK(1 << HTON_BIT_SKIP_STORE_LOCK);
00103 static const std::bitset<HTON_BIT_SIZE> HTON_HAS_SCHEMA_DICTIONARY(1 << HTON_BIT_SCHEMA_DICTIONARY);
00104 static const std::bitset<HTON_BIT_SIZE> HTON_HAS_FOREIGN_KEYS(1 << HTON_BIT_FOREIGN_KEYS);
00105 
00106 
00107 namespace plugin {
00108 
00109 typedef std::vector<StorageEngine *> EngineVector;
00110 
00111 typedef std::set<std::string> TableNameList;
00112 
00113 extern const std::string UNKNOWN_STRING;
00114 extern DRIZZLED_API const std::string DEFAULT_DEFINITION_FILE_EXT;
00115 
00116 
00117 /*
00118   StorageEngine is a singleton structure - one instance per storage engine -
00119   to provide access to storage engine functionality that works on the
00120   "global" level (unlike Cursor class that works on a per-table basis)
00121 
00122   usually StorageEngine instance is defined statically in ha_xxx.cc as
00123 
00124   static StorageEngine { ... } xxx_engine;
00125 */
00126 class DRIZZLED_API StorageEngine :
00127   public Plugin,
00128   public MonitoredInTransaction
00129 {
00130   friend class SEAPITester;
00131 public:
00132   typedef uint64_t Table_flags;
00133 
00134 private:
00135   static EngineVector &getSchemaEngines();
00136   const std::bitset<HTON_BIT_SIZE> flags; /* global Cursor flags */
00137 
00138 
00139   virtual void setTransactionReadWrite(Session& session);
00140 
00141   /*
00142    * Indicates to a storage engine the start of a
00143    * new SQL statement.
00144    */
00145   virtual void doStartStatement(Session *session)
00146   {
00147     (void) session;
00148   }
00149 
00150   /*
00151    * Indicates to a storage engine the end of
00152    * the current SQL statement in the supplied
00153    * Session.
00154    */
00155   virtual void doEndStatement(Session *session)
00156   {
00157     (void) session;
00158   }
00159 
00160 protected:
00161   std::string table_definition_ext;
00162 
00163 public:
00164   const std::string& getTableDefinitionFileExtension()
00165   {
00166     return table_definition_ext;
00167   }
00168 
00169   virtual message::Table::Index::IndexType default_index_type() const
00170   {
00171     return message::Table::Index::BTREE;
00172   }
00173 
00174 private:
00175   std::vector<std::string> aliases;
00176 
00177 public:
00178   const std::vector<std::string>& getAliases() const
00179   {
00180     return aliases;
00181   }
00182 
00183   void addAlias(std::string alias)
00184   {
00185     aliases.push_back(alias);
00186   }
00187 
00188 protected:
00189 
00194   typedef std::map <std::string, message::Table> ProtoCache;
00195   ProtoCache proto_cache;
00196   pthread_mutex_t proto_cache_mutex;
00197 
00198 public:
00199   StorageEngine(const std::string &name_arg,
00200                 const std::bitset<HTON_BIT_SIZE> &flags_arg= HTON_NO_FLAGS);
00201 
00202   virtual ~StorageEngine();
00203 
00204 protected:
00205   virtual int doGetTableDefinition(Session &session,
00206                                    const drizzled::identifier::Table &identifier,
00207                                    message::Table &table_message)
00208   {
00209     (void)session;
00210     (void)identifier;
00211     (void)table_message;
00212 
00213     return ENOENT;
00214   }
00215 
00216   /* Old style cursor errors */
00217   void print_keydup_error(uint32_t key_nr, const char *msg, const Table &table) const;
00218   virtual bool get_error_message(int error, String *buf) const;
00219 
00220 public:
00221   virtual void print_error(int error, myf errflag, const Table& table) const;
00222 
00223   bool is_user_selectable() const
00224   {
00225     return not flags.test(HTON_BIT_NOT_USER_SELECTABLE);
00226   }
00227 
00228   bool check_flag(const engine_flag_bits flag) const
00229   {
00230     return flags.test(flag);
00231   }
00232 
00233   // @todo match check_flag interface
00234   virtual uint32_t index_flags(enum  ha_key_alg) const { return 0; }
00235   virtual void startStatement(Session *session)
00236   {
00237     doStartStatement(session);
00238   }
00239   virtual void endStatement(Session *session)
00240   {
00241     doEndStatement(session);
00242   }
00243 
00244   /*
00245    * Called during Session::cleanup() for all engines
00246    */
00247   virtual int close_connection(Session  *)
00248   {
00249     return 0;
00250   }
00251 
00252   virtual Cursor *create(Table &)= 0;
00253   /* args: path */
00254   virtual bool flush_logs() { return false; }
00255   virtual bool show_status(Session *, stat_print_fn *, enum ha_stat_type)
00256   {
00257     return false;
00258   }
00259 
00271   virtual const char **bas_ext() const =0;
00272 
00273 protected:
00274   virtual int doCreateTable(Session &session,
00275                             Table &table_arg,
00276                             const drizzled::identifier::Table &identifier,
00277                             const message::Table &message)= 0;
00278 
00279   virtual int doRenameTable(Session &session,
00280                             const drizzled::identifier::Table &from, const drizzled::identifier::Table &to)= 0;
00281 
00282   virtual int doDropTable(Session &session,
00283                           const drizzled::identifier::Table &identifier)= 0;
00284 
00285   virtual void doGetTableIdentifiers(CachedDirectory &directory,
00286                                      const drizzled::identifier::Schema &schema_identifier,
00287                                      identifier::table::vector &set_of_identifiers)= 0;
00288 
00289   virtual bool doDoesTableExist(Session& session, const drizzled::identifier::Table &identifier);
00290 
00291   virtual bool doCanCreateTable(const drizzled::identifier::Table &identifier)
00292   { (void)identifier;  return true; }
00293 
00294 public:
00295 
00296   friend class AddSchemaNames;
00297   friend class AddTableIdentifier;
00298   friend class AlterSchema;
00299   friend class CanCreateTable;
00300   friend class CreateSchema;
00301   friend class DropSchema;
00302   friend class DropTable;
00303   friend class DropTables;
00304   friend class FindEngineByName;
00305   friend class Ha_delete_table_error_handler;
00306   friend class StorageEngineCloseConnection;
00307   friend class StorageEngineDoesTableExist;
00308   friend class StorageEngineGetSchemaDefinition;
00309   friend class StorageEngineGetTableDefinition;
00310   friend class DropTableByIdentifier;
00311 
00312   int renameTable(Session &session, const drizzled::identifier::Table &from, const drizzled::identifier::Table &to);
00313 
00314   /* Class Methods for operating on plugin */
00315   static bool addPlugin(plugin::StorageEngine *engine);
00316   static void removePlugin(plugin::StorageEngine *engine);
00317 
00318   static message::table::shared_ptr getTableMessage(Session& session,
00319                                                     const drizzled::identifier::Table &identifier,
00320                                                     bool include_temporary_tables= true);
00321   static bool doesTableExist(Session &session,
00322                              const drizzled::identifier::Table &identifier,
00323                              bool include_temporary_tables= true);
00324 
00325   static plugin::StorageEngine *findByName(const std::string &find_str);
00326   static plugin::StorageEngine *findByName(Session& session, const std::string &find_str);
00327 
00328   static void closeConnection(Session&);
00329   static void dropDatabase(char* path);
00330   static bool flushLogs(plugin::StorageEngine *db_type);
00331 
00332   static bool dropTable(Session& session,
00333                         const drizzled::identifier::Table &identifier);
00334   static bool dropTable(Session& session,
00335                         const drizzled::identifier::Table &identifier,
00336                         drizzled::error_t &error);
00337 
00338   static bool dropTable(Session& session,
00339                         StorageEngine &engine,
00340                         const identifier::Table& identifier,
00341                         drizzled::error_t &error);
00342 
00343   static void getIdentifiers(Session &session,
00344                              const identifier::Schema &schema_identifier,
00345                              identifier::table::vector &set_of_identifiers);
00346 
00347   // Check to see if any SE objects to creation.
00348   static bool canCreateTable(const drizzled::identifier::Table &identifier);
00349 
00350   // @note All schema methods defined here
00351   static void getIdentifiers(Session &session, identifier::schema::vector &schemas);
00352   static message::schema::shared_ptr getSchemaDefinition(const drizzled::identifier::Table &identifier);
00353   static message::schema::shared_ptr getSchemaDefinition(const drizzled::identifier::Schema &identifier);
00354   static bool doesSchemaExist(const drizzled::identifier::Schema &identifier);
00355   static const charset_info_st *getSchemaCollation(const drizzled::identifier::Schema &identifier);
00356   static bool createSchema(const drizzled::message::Schema &schema_message);
00357   static bool dropSchema(Session &session,
00358                          const identifier::Schema& identifier,
00359                          message::schema::const_reference schema_message);
00360   static bool alterSchema(const drizzled::message::Schema &schema_message);
00361 
00362   // @note make private/protected
00363 protected:
00364   virtual void doGetSchemaIdentifiers(identifier::schema::vector&)
00365   { }
00366 
00367   virtual drizzled::message::schema::shared_ptr doGetSchemaDefinition(const drizzled::identifier::Schema&)
00368   { 
00369     return drizzled::message::schema::shared_ptr(); 
00370   }
00371 
00372   virtual bool doCreateSchema(const drizzled::message::Schema&)
00373   { return false; }
00374 
00375   virtual bool doAlterSchema(const drizzled::message::Schema&)
00376   { return false; }
00377 
00378   virtual bool doDropSchema(const drizzled::identifier::Schema&)
00379   { return false; }
00380 
00381 public:
00382   static inline const std::string &resolveName(const StorageEngine *engine)
00383   {
00384     return engine == NULL ? UNKNOWN_STRING : engine->getName();
00385   }
00386 
00387   static bool createTable(Session &session,
00388                           const identifier::Table &identifier,
00389                           message::Table& table_message);
00390 
00391   static void removeLostTemporaryTables(Session &session, const char *directory);
00392 
00393   Cursor *getCursor(Table &share);
00394 
00395   uint32_t max_record_length() const
00396   { return std::min(HA_MAX_REC_LENGTH, max_supported_record_length()); }
00397   uint32_t max_keys() const
00398   { return std::min(MAX_KEY, max_supported_keys()); }
00399   uint32_t max_key_parts() const
00400   { return std::min(MAX_REF_PARTS, max_supported_key_parts()); }
00401   uint32_t max_key_length() const
00402   { return std::min(MAX_KEY_LENGTH, max_supported_key_length()); }
00403   uint32_t max_key_part_length(void) const
00404   { return std::min(MAX_KEY_LENGTH, max_supported_key_part_length()); }
00405 
00406   virtual uint32_t max_supported_record_length(void) const
00407   { return HA_MAX_REC_LENGTH; }
00408   virtual uint32_t max_supported_keys(void) const { return 0; }
00409   virtual uint32_t max_supported_key_parts(void) const { return MAX_REF_PARTS; }
00410   virtual uint32_t max_supported_key_length(void) const { return MAX_KEY_LENGTH; }
00411   virtual uint32_t max_supported_key_part_length(void) const { return 255; }
00412 
00413   /* TODO-> Make private */
00414 protected:
00415   static int deleteDefinitionFromPath(const drizzled::identifier::Table &identifier);
00416   static int renameDefinitionFromPath(const drizzled::identifier::Table &dest, const drizzled::identifier::Table &src);
00417   static int writeDefinitionFromPath(const drizzled::identifier::Table &identifier, const message::Table &proto);
00418   static bool readTableFile(const std::string &path, message::Table &table_message);
00419 
00420 public:
00421   /* 
00422    * The below are simple virtual overrides for the plugin::MonitoredInTransaction
00423    * interface.
00424    */
00425   virtual bool participatesInSqlTransaction() const
00426   {
00427     return false; /* plugin::StorageEngine is non-transactional in terms of SQL */
00428   }
00429   virtual bool participatesInXaTransaction() const
00430   {
00431     return false; /* plugin::StorageEngine is non-transactional in terms of XA */
00432   }
00433   virtual bool alwaysRegisterForXaTransaction() const
00434   {
00435     return false;
00436   }
00437 
00438   virtual bool validateCreateTableOption(const std::string &key, const std::string &state)
00439   {
00440     (void)key;
00441     (void)state;
00442 
00443     return false;
00444   }
00445 
00446   virtual bool validateCreateSchemaOption(const std::string &key, const std::string &state)
00447   {
00448     (void)key;
00449     (void)state;
00450 
00451     return false;
00452   }
00453 };
00454 
00455 std::ostream& operator<<(std::ostream& output, const StorageEngine &engine);
00456 
00457 } /* namespace plugin */
00458 } /* namespace drizzled */
00459