Drizzled Public API Documentation

base.h
00001 /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
00002  *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
00003  *
00004  *  Copyright (C) 2009 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; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00019  */
00020 
00021 /*
00022   This class is shared between different table objects. There is one
00023   instance of table share per one table in the database.
00024 */
00025 
00026 #pragma once
00027 
00028 #include <string>
00029 
00030 #include <boost/unordered_map.hpp>
00031 #include <boost/thread/condition_variable.hpp>
00032 #include <boost/dynamic_bitset.hpp>
00033 #include <boost/shared_ptr.hpp>
00034 #include <boost/scoped_ptr.hpp>
00035 
00036 #include <drizzled/memory/root.h>
00037 #include <drizzled/message.h>
00038 #include <drizzled/util/string.h>
00039 #include <drizzled/key_map.h>
00040 #include <drizzled/field.h>
00041 #include <drizzled/util/find_ptr.h>
00042 
00043 namespace drizzled {
00044 
00045 const static std::string NO_PROTOBUFFER_AVAILABLE("NO PROTOBUFFER AVAILABLE");
00046 
00047 class TableShare
00048 {
00049   typedef std::vector<std::string> StringVector;
00050 
00051 public:
00052   typedef boost::shared_ptr<TableShare> shared_ptr;
00053   typedef std::vector <shared_ptr> vector;
00054 
00055   TableShare(const identifier::Table::Type type_arg);
00056 
00057   TableShare(const identifier::Table &identifier, const identifier::Table::Key &key); // Used by placeholder
00058 
00059   TableShare(const identifier::Table &identifier); // Just used during createTable()
00060 
00061   TableShare(const identifier::Table::Type type_arg,
00062              const identifier::Table &identifier,
00063              const char *path_arg= NULL, uint32_t path_length_arg= 0); // Shares for cache
00064 
00065   virtual ~TableShare();
00066 
00067 private:
00069   enum_table_category table_category;
00070 
00071 public:
00072   bool isTemporaryCategory() const
00073   {
00074     return (table_category == TABLE_CATEGORY_TEMPORARY);
00075   }
00076 
00077   void setTableCategory(enum_table_category arg)
00078   {
00079     table_category= arg;
00080   }
00081 
00082   /* The following is copied to each Table on OPEN */
00083   typedef std::vector<Field *> Fields;
00084 
00085 private:
00086   Fields _fields;
00087 
00088 public:
00089   const Fields getFields() const
00090   {
00091     return _fields;
00092   }
00093 
00094   Fields getFields()
00095   {
00096     return _fields;
00097   }
00098 
00099   Field ** getFields(bool)
00100   {
00101     return &_fields[0];
00102   }
00103 
00104   void setFields(uint32_t arg)
00105   {
00106     _fields.resize(arg);
00107   }
00108 
00109   uint32_t positionFields(Field **arg) const
00110   {
00111     return (arg - (Field **)&_fields[0]);
00112   }
00113 
00114   void pushField(Field *arg)
00115   {
00116     _field_size++;
00117     _fields.push_back(arg);
00118   }
00119 
00120   Field **found_next_number_field;
00121 
00122 private:
00123   Field *timestamp_field;               /* Used only during open */
00124 
00125 public:
00126 
00127   Field *getTimestampField() const               /* Used only during open */
00128   {
00129     return timestamp_field;
00130   }
00131 
00132   void setTimestampField(Field *arg) /* Used only during open */
00133   {
00134     timestamp_field= arg;
00135   }
00136 
00137 
00138 private:
00139   KeyInfo  *key_info;     /* data of keys in database */
00140 
00141 public:
00142   KeyInfo &getKeyInfo(uint32_t arg) const
00143   {
00144     return key_info[arg];
00145   }
00146   std::vector<uint> blob_field;     /* Index to blobs in Field arrray*/
00147 
00148 private:
00149   /* hash of field names (contains pointers to elements of field array) */
00150   typedef boost::unordered_map<std::string, Field**, util::insensitive_hash, util::insensitive_equal_to> FieldMap;
00151   FieldMap name_hash; /* hash of field names */
00152 
00153 public:
00154   size_t getNamedFieldSize() const
00155   {
00156     return name_hash.size();
00157   }
00158 
00159   Field **getNamedField(const std::string &arg)
00160   {
00161     return find_ptr2(name_hash, arg);
00162   }
00163 
00164 private:
00165   memory::Root mem_root;
00166 
00167   unsigned char* alloc(size_t arg)
00168   {
00169     return mem_root.alloc(arg);
00170   }
00171 
00172   memory::Root& mem()
00173   {
00174     return mem_root;
00175   }
00176 
00177   typedef std::vector<std::string> keynames_t;
00178 
00179   keynames_t _keynames;
00180 
00181   void addKeyName(const std::string& arg)
00182   {
00183     _keynames.push_back(boost::to_upper_copy(arg));
00184   }
00185 
00186 public:
00187   uint32_t doesKeyNameExist(const std::string& arg) const
00188   {
00189     keynames_t::const_iterator it= find(_keynames.begin(), _keynames.end(), boost::to_upper_copy(arg));
00190     return it == _keynames.end() ? UINT32_MAX : it - _keynames.begin(); // historical, required for finding primary key from unique
00191   }
00192 
00193 private:
00194   std::vector<TYPELIB> intervals;     /* pointer to interval info */
00195 
00196 public:
00197   virtual void lock()
00198   { }
00199 
00200   virtual void unlock()
00201   { }
00202 
00203 private:
00204   std::vector<unsigned char> default_values;    /* row with default values */
00205 
00206 public:
00207   // @note This needs to be made to be const in the future
00208   unsigned char *getDefaultValues()
00209   {
00210     return &default_values[0];
00211   }
00212   void resizeDefaultValues(size_t arg)
00213   {
00214     default_values.resize(arg);
00215   }
00216 
00217   const charset_info_st *table_charset; /* Default charset of string fields */
00218 
00219   boost::dynamic_bitset<> all_set;
00220 
00221   /*
00222     Key which is used for looking-up table in table cache and in the list
00223     of thread's temporary tables. Has the form of:
00224     "database_name\0table_name\0" + optional part for temporary tables.
00225 
00226     Note that all three 'table_cache_key', 'db' and 'table_name' members
00227     must be set (and be non-zero) for tables in table cache. They also
00228     should correspond to each other.
00229     To ensure this one can use set_table_cache() methods.
00230   */
00231 private:
00232   identifier::Table::Key private_key_for_cache; // This will not exist in the final design.
00233   std::vector<char> private_normalized_path; // This will not exist in the final design.
00234   str_ref db;                        /* Pointer to db */
00235   str_ref table_name;                /* Table name (for open) */
00236   str_ref path; /* Path to table (from datadir) */
00237   str_ref normalized_path;    /* unpack_filename(path) */
00238 
00239 public:
00240 
00241   const char *getNormalizedPath() const
00242   {
00243     return normalized_path.data();
00244   }
00245 
00246   const char *getPath() const
00247   {
00248     return path.data();
00249   }
00250 
00251   const identifier::Table::Key& getCacheKey() const // This should never be called when we aren't looking at a cache.
00252   {
00253     assert(private_key_for_cache.size());
00254     return private_key_for_cache;
00255   }
00256 
00257   size_t getCacheKeySize() const
00258   {
00259     return private_key_for_cache.size();
00260   }
00261 
00262   str_ref getTableNameRef() const
00263   {
00264     return table_name;
00265   }
00266 
00267   const char *getTableName() const
00268   {
00269     return table_name.data();
00270   }
00271 
00272   str_ref getSchemaNameRef() const
00273   {
00274     return db;
00275   }
00276 
00277   const char *getSchemaName() const
00278   {
00279     return db.data();
00280   }
00281 
00282   uint32_t   block_size;                   /* create information */
00283 
00284 private:
00285   uint64_t   version;
00286 
00287 public:
00288   uint64_t getVersion() const
00289   {
00290     return version;
00291   }
00292 
00293   void refreshVersion();
00294 
00295   void resetVersion()
00296   {
00297     version= 0;
00298   }
00299 
00300 private:
00301   uint32_t   timestamp_offset;    /* Set to offset+1 of record */
00302 
00303   uint32_t reclength;     /* Recordlength */
00304   uint32_t stored_rec_length;         /* Stored record length*/
00305 
00306 public:
00307   uint32_t sizeStoredRecord() const
00308   {
00309     return stored_rec_length;
00310   }
00311 
00312   uint32_t getRecordLength() const
00313   {
00314     return reclength;
00315   }
00316 
00317   void setRecordLength(uint32_t arg)
00318   {
00319     reclength= arg;
00320   }
00321 
00322   const Field_blob *getBlobFieldAt(uint32_t arg) const
00323   {
00324     if (arg < blob_fields)
00325       return (Field_blob*) _fields[blob_field[arg]];
00326 
00327     return NULL;
00328   }
00329 
00330 private:
00331   /* Max rows is a hint to HEAP during a create tmp table */
00332   uint64_t max_rows;
00333 
00334   boost::scoped_ptr<message::Table> _table_message;
00335 
00336 public:
00337   /*
00338     @note Without a _table_message, we assume we are building a STANDARD table.
00339     This will be modified once we use Identifiers in the Share itself.
00340   */
00341   message::Table::TableType getTableType() const
00342   {
00343     return getTableMessage() ? getTableMessage()->type() : message::Table::STANDARD;
00344   }
00345 
00346   const std::string &getTableTypeAsString() const
00347   {
00348     if (getTableMessage())
00349       return message::type(getTableMessage()->type());
00350 
00351     return NO_PROTOBUFFER_AVAILABLE;
00352   }
00353 
00354   /* This is only used in one location currently */
00355   inline message::Table *getTableMessage() const
00356   {
00357     return _table_message.get();
00358   }
00359 
00360   void setTableMessage(const message::Table &arg)
00361   {
00362     assert(not getTableMessage());
00363     _table_message.reset(new message::Table(arg));
00364   }
00365 
00366   const message::Table::Field &field(int32_t field_position) const
00367   {
00368     assert(getTableMessage());
00369     return getTableMessage()->field(field_position);
00370   }
00371 
00372   inline bool hasComment() const
00373   {
00374     return getTableMessage() ?  getTableMessage()->options().has_comment() : false; 
00375   }
00376 
00377   inline const char *getComment()
00378   {
00379     return (getTableMessage() && getTableMessage()->has_options()) ?  getTableMessage()->options().comment().c_str() : NULL; 
00380   }
00381 
00382   inline uint32_t getCommentLength() const
00383   {
00384     return (getTableMessage()) ? getTableMessage()->options().comment().length() : 0; 
00385   }
00386 
00387   inline uint64_t getMaxRows() const
00388   {
00389     return max_rows;
00390   }
00391 
00392   inline void setMaxRows(uint64_t arg)
00393   {
00394     max_rows= arg;
00395   }
00396 
00401   bool fieldInPrimaryKey(Field *field) const;
00402 
00403   plugin::StorageEngine *storage_engine;      /* storage engine plugin */
00404   inline plugin::StorageEngine *db_type() const /* table_type for handler */
00405   {
00406     return storage_engine;
00407   }
00408   inline plugin::StorageEngine *getEngine() const /* table_type for handler */
00409   {
00410     return storage_engine;
00411   }
00412 
00413 private:
00414   identifier::Table::Type tmp_table;
00415 public:
00416 
00417   identifier::Table::Type getType() const
00418   {
00419     return tmp_table;
00420   }
00421 
00422 private:
00423   uint32_t _ref_count;       /* How many Table objects uses this */
00424 
00425 public:
00426   uint32_t getTableCount() const
00427   {
00428     return _ref_count;
00429   }
00430 
00431   void incrementTableCount()
00432   {
00433     lock();
00434     _ref_count++;
00435     unlock();
00436   }
00437 
00438   uint32_t decrementTableCount()
00439   {
00440     return --_ref_count;
00441   }
00442 
00443   uint32_t null_bytes;
00444   uint32_t last_null_bit_pos;
00445 private:
00446   uint32_t _field_size;       /* Number of fields */
00447 
00448 public:
00449   void setFieldSize(uint32_t arg)
00450   {
00451     _field_size= arg;
00452   }
00453 
00454   uint32_t sizeFields() const
00455   {
00456     return _field_size;
00457   }
00458 
00459   uint32_t rec_buff_length;                 /* Size of table->record[] buffer */
00460   uint32_t keys;
00461 
00462   uint32_t sizeKeys() const
00463   {
00464     return keys;
00465   }
00466   uint32_t key_parts;
00467   uint32_t max_key_length, max_unique_length, total_key_length;
00468   uint32_t uniques;                         /* Number of UNIQUE index */
00469   uint32_t null_fields;     /* number of null fields */
00470   uint32_t blob_fields;     /* number of blob fields */
00471 private:
00472   bool has_variable_width;                  /* number of varchar fields */
00473 
00474 public:
00475   bool hasVariableWidth() const
00476   {
00477     return has_variable_width; // We should calculate this.
00478   }
00479   void setVariableWidth()
00480   {
00481     has_variable_width= true;
00482   }
00483   uint32_t db_create_options;   /* Create options from database */
00484   uint32_t db_options_in_use;   /* Options in use */
00485   uint32_t db_record_offset;    /* if HA_REC_IN_SEQ */
00486   uint32_t rowid_field_offset;    /* Field_nr +1 to rowid field */
00496 private:
00497   uint32_t primary_key;
00498 public:
00499 
00500   uint32_t getPrimaryKey() const
00501   {
00502     return primary_key;
00503   }
00504 
00505   bool hasPrimaryKey() const
00506   {
00507     return primary_key != MAX_KEY;
00508   }
00509 
00510   /* Index of auto-updated TIMESTAMP field in field array */
00511   uint32_t next_number_index;               /* autoincrement key number */
00512   uint32_t next_number_key_offset;          /* autoinc keypart offset in a key */
00513   uint32_t next_number_keypart;             /* autoinc keypart number in a key */
00514   uint32_t error, open_errno, errarg;       /* error from open_table_def() */
00515 
00516 private:
00517   uint8_t blob_ptr_size;      /* 4 or 8 */
00518 
00519 public:
00520   uint8_t sizeBlobPtr() const
00521   {
00522     return blob_ptr_size;
00523   }
00524 
00525   bool db_low_byte_first;   /* Portable row format */
00526 
00527   /*
00528     Set of keys in use, implemented as a Bitmap.
00529     Excludes keys disabled by ALTER Table ... DISABLE KEYS.
00530   */
00531   key_map keys_in_use;
00532   key_map keys_for_keyread;
00533 
00534   /* 
00535     event_observers is a class containing all the event plugins that have 
00536     registered an interest in this table.
00537   */
00538   virtual plugin::EventObserverList *getTableObservers() 
00539   { 
00540     return NULL;
00541   }
00542   
00543   virtual void setTableObservers(plugin::EventObserverList *) 
00544   { }
00545   
00546   /*
00547     Set share's identifier information.
00548 
00549     SYNOPSIS
00550     setIdentifier()
00551 
00552     NOTES
00553   */
00554 
00555   void setIdentifier(const identifier::Table &identifier_arg);
00556 
00557   /*
00558     Initialize share for temporary tables
00559 
00560     SYNOPSIS
00561     init()
00562     share Share to fill
00563     key   Table_cache_key, as generated from create_table_def_key.
00564     must start with db name.
00565     key_length  Length of key
00566     table_name  Table name
00567     path  Path to table (possible in lower case)
00568 
00569     NOTES
00570     
00571   */
00572 
00573 private:
00574   void init(const char *new_table_name,
00575             const char *new_path);
00576 
00577 protected:
00578   void open_table_error(int pass_error, int db_errno, int pass_errarg);
00579 
00580 public:
00581 
00582   static TableShare::shared_ptr getShareCreate(Session*, const identifier::Table&, int &error);
00583 
00584   friend std::ostream& operator<<(std::ostream& output, const TableShare &share)
00585   {
00586     return output << "TableShare:(" <<  share.getSchemaNameRef() << ", " << share.getTableName() << ", " << share.getTableTypeAsString() << ", " << share.getPath() << ")";
00587   }
00588 
00589 protected:
00590   friend class drizzled::table::Singular;
00591 
00592   Field *make_field(const message::Table::Field &pfield,
00593                     unsigned char *ptr,
00594                     uint32_t field_length,
00595                     bool is_nullable,
00596                     unsigned char *null_pos,
00597                     unsigned char null_bit,
00598                     uint8_t decimals,
00599                     enum_field_types field_type,
00600                     const charset_info_st * field_charset,
00601                     Field::utype unireg_check,
00602                     TYPELIB *interval,
00603                     const char *field_name);
00604 
00605   Field *make_field(const message::Table::Field &pfield,
00606                     unsigned char *ptr,
00607                     uint32_t field_length,
00608                     bool is_nullable,
00609                     unsigned char *null_pos,
00610                     unsigned char null_bit,
00611                     uint8_t decimals,
00612                     enum_field_types field_type,
00613                     const charset_info_st * field_charset,
00614                     Field::utype unireg_check,
00615                     TYPELIB *interval,
00616                     const char *field_name, 
00617                     bool is_unsigned);
00618 
00619 public:
00620   int open_table_def(Session& session, const identifier::Table &identifier);
00621 
00622   int open_table_from_share(Session *session,
00623                             const identifier::Table &identifier,
00624                             const char *alias,
00625                             uint32_t db_stat, uint32_t ha_open_flags,
00626                             Table &outparam);
00627 private:
00628   int open_table_from_share_inner(Session *session,
00629                                   const char *alias,
00630                                   uint32_t db_stat,
00631                                   Table &outparam);
00632   int open_table_cursor_inner(const identifier::Table &identifier,
00633                               uint32_t db_stat, uint32_t ha_open_flags,
00634                               Table &outparam,
00635                               bool &error_reported);
00636 public:
00637   bool parse_table_proto(Session& session, const message::Table &table);
00638 
00639   virtual bool is_replicated() const
00640   {
00641     return false;
00642   }
00643 };
00644 
00645 } /* namespace drizzled */
00646