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