00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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);
00058
00059 TableShare(const identifier::Table &identifier);
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);
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
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;
00124
00125 public:
00126
00127 Field *getTimestampField() const
00128 {
00129 return timestamp_field;
00130 }
00131
00132 void setTimestampField(Field *arg)
00133 {
00134 timestamp_field= arg;
00135 }
00136
00137
00138 private:
00139 KeyInfo *key_info;
00140
00141 public:
00142 KeyInfo &getKeyInfo(uint32_t arg) const
00143 {
00144 return key_info[arg];
00145 }
00146 std::vector<uint> blob_field;
00147
00148 private:
00149
00150 typedef boost::unordered_map<std::string, Field**, util::insensitive_hash, util::insensitive_equal_to> FieldMap;
00151 FieldMap name_hash;
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();
00191 }
00192
00193 private:
00194 std::vector<TYPELIB> intervals;
00195
00196 public:
00197 virtual void lock()
00198 { }
00199
00200 virtual void unlock()
00201 { }
00202
00203 private:
00204 std::vector<unsigned char> default_values;
00205
00206 public:
00207
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;
00218
00219 boost::dynamic_bitset<> all_set;
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 private:
00232 identifier::Table::Key private_key_for_cache;
00233 std::vector<char> private_normalized_path;
00234 str_ref db;
00235 str_ref table_name;
00236 str_ref path;
00237 str_ref normalized_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
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;
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;
00302
00303 uint32_t reclength;
00304 uint32_t stored_rec_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
00332 uint64_t max_rows;
00333
00334 boost::scoped_ptr<message::Table> _table_message;
00335
00336 public:
00337
00338
00339
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
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;
00404 inline plugin::StorageEngine *db_type() const
00405 {
00406 return storage_engine;
00407 }
00408 inline plugin::StorageEngine *getEngine() const
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;
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;
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;
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;
00469 uint32_t null_fields;
00470 uint32_t blob_fields;
00471 private:
00472 bool has_variable_width;
00473
00474 public:
00475 bool hasVariableWidth() const
00476 {
00477 return has_variable_width;
00478 }
00479 void setVariableWidth()
00480 {
00481 has_variable_width= true;
00482 }
00483 uint32_t db_create_options;
00484 uint32_t db_options_in_use;
00485 uint32_t db_record_offset;
00486 uint32_t rowid_field_offset;
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
00511 uint32_t next_number_index;
00512 uint32_t next_number_key_offset;
00513 uint32_t next_number_keypart;
00514 uint32_t error, open_errno, errarg;
00515
00516 private:
00517 uint8_t blob_ptr_size;
00518
00519 public:
00520 uint8_t sizeBlobPtr() const
00521 {
00522 return blob_ptr_size;
00523 }
00524
00525 bool db_low_byte_first;
00526
00527
00528
00529
00530
00531 key_map keys_in_use;
00532 key_map keys_for_keyread;
00533
00534
00535
00536
00537
00538 virtual plugin::EventObserverList *getTableObservers()
00539 {
00540 return NULL;
00541 }
00542
00543 virtual void setTableObservers(plugin::EventObserverList *)
00544 { }
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555 void setIdentifier(const identifier::Table &identifier_arg);
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
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 }
00646