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