Drizzled Public API Documentation

base.h
1 /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3  *
4  * Copyright (C) 2009 Sun Microsystems, Inc.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 /*
22  This class is shared between different table objects. There is one
23  instance of table share per one table in the database.
24 */
25 
26 #pragma once
27 
28 #include <string>
29 
30 #include <boost/unordered_map.hpp>
31 #include <boost/thread/condition_variable.hpp>
32 #include <boost/dynamic_bitset.hpp>
33 #include <boost/shared_ptr.hpp>
34 #include <boost/scoped_ptr.hpp>
35 
36 #include <drizzled/memory/root.h>
37 #include <drizzled/message.h>
38 #include <drizzled/util/string.h>
39 #include <drizzled/key_map.h>
40 #include <drizzled/field.h>
41 #include <drizzled/util/find_ptr.h>
42 
43 namespace drizzled {
44 
45 const static std::string NO_PROTOBUFFER_AVAILABLE("NO PROTOBUFFER AVAILABLE");
46 
48 {
49  typedef std::vector<std::string> StringVector;
50 
51 public:
52  typedef boost::shared_ptr<TableShare> shared_ptr;
53  typedef std::vector <shared_ptr> vector;
54 
55  TableShare(const identifier::Table::Type type_arg);
56 
57  TableShare(const identifier::Table &identifier, const identifier::Table::Key &key); // Used by placeholder
58 
59  TableShare(const identifier::Table &identifier); // Just used during createTable()
60 
61  TableShare(const identifier::Table::Type type_arg,
62  const identifier::Table &identifier,
63  const char *path_arg= NULL, uint32_t path_length_arg= 0); // Shares for cache
64 
65  virtual ~TableShare();
66 
67 private:
70 
71 public:
72  bool isTemporaryCategory() const
73  {
75  }
76 
77  void setTableCategory(enum_table_category arg)
78  {
79  table_category= arg;
80  }
81 
82  /* The following is copied to each Table on OPEN */
83  typedef std::vector<Field *> Fields;
84 
85 private:
86  Fields _fields;
87 
88 public:
89  const Fields getFields() const
90  {
91  return _fields;
92  }
93 
94  Fields getFields()
95  {
96  return _fields;
97  }
98 
99  Field ** getFields(bool)
100  {
101  return &_fields[0];
102  }
103 
104  void setFields(uint32_t arg)
105  {
106  _fields.resize(arg);
107  }
108 
109  uint32_t positionFields(Field **arg) const
110  {
111  return (arg - (Field **)&_fields[0]);
112  }
113 
114  void pushField(Field *arg)
115  {
116  _field_size++;
117  _fields.push_back(arg);
118  }
119 
120  Field **found_next_number_field;
121 
122 private:
123  Field *timestamp_field; /* Used only during open */
124 
125 public:
126 
127  Field *getTimestampField() const /* Used only during open */
128  {
129  return timestamp_field;
130  }
131 
132  void setTimestampField(Field *arg) /* Used only during open */
133  {
134  timestamp_field= arg;
135  }
136 
137 
138 private:
139  KeyInfo *key_info; /* data of keys in database */
140 
141 public:
142  KeyInfo &getKeyInfo(uint32_t arg) const
143  {
144  return key_info[arg];
145  }
146  std::vector<uint> blob_field; /* Index to blobs in Field arrray*/
147 
148 private:
149  /* hash of field names (contains pointers to elements of field array) */
150  typedef boost::unordered_map<std::string, Field**, util::insensitive_hash, util::insensitive_equal_to> FieldMap;
151  FieldMap name_hash; /* hash of field names */
152 
153 public:
154  size_t getNamedFieldSize() const
155  {
156  return name_hash.size();
157  }
158 
159  Field **getNamedField(const std::string &arg)
160  {
161  return find_ptr2(name_hash, arg);
162  }
163 
164 private:
165  memory::Root mem_root;
166 
167  unsigned char* alloc(size_t arg)
168  {
169  return mem_root.alloc(arg);
170  }
171 
172  memory::Root& mem()
173  {
174  return mem_root;
175  }
176 
177  typedef std::vector<std::string> keynames_t;
178 
179  keynames_t _keynames;
180 
181  void addKeyName(const std::string& arg)
182  {
183  _keynames.push_back(boost::to_upper_copy(arg));
184  }
185 
186 public:
187  uint32_t doesKeyNameExist(const std::string& arg) const
188  {
189  keynames_t::const_iterator it= find(_keynames.begin(), _keynames.end(), boost::to_upper_copy(arg));
190  return it == _keynames.end() ? UINT32_MAX : it - _keynames.begin(); // historical, required for finding primary key from unique
191  }
192 
193 private:
194  std::vector<TYPELIB> intervals; /* pointer to interval info */
195 
196 public:
197  virtual void lock()
198  { }
199 
200  virtual void unlock()
201  { }
202 
203 private:
204  std::vector<unsigned char> default_values; /* row with default values */
205 
206 public:
207  // @note This needs to be made to be const in the future
208  unsigned char *getDefaultValues()
209  {
210  return &default_values[0];
211  }
212  void resizeDefaultValues(size_t arg)
213  {
214  default_values.resize(arg);
215  }
216 
217  const charset_info_st *table_charset; /* Default charset of string fields */
218 
219  boost::dynamic_bitset<> all_set;
220 
221  /*
222  Key which is used for looking-up table in table cache and in the list
223  of thread's temporary tables. Has the form of:
224  "database_name\0table_name\0" + optional part for temporary tables.
225 
226  Note that all three 'table_cache_key', 'db' and 'table_name' members
227  must be set (and be non-zero) for tables in table cache. They also
228  should correspond to each other.
229  To ensure this one can use set_table_cache() methods.
230  */
231 private:
232  identifier::Table::Key private_key_for_cache; // This will not exist in the final design.
233  std::vector<char> private_normalized_path; // This will not exist in the final design.
234  str_ref db; /* Pointer to db */
235  str_ref table_name; /* Table name (for open) */
236  str_ref path; /* Path to table (from datadir) */
237  str_ref normalized_path; /* unpack_filename(path) */
238 
239 public:
240 
241  const char *getNormalizedPath() const
242  {
243  return normalized_path.data();
244  }
245 
246  const char *getPath() const
247  {
248  return path.data();
249  }
250 
251  const identifier::Table::Key& getCacheKey() const // This should never be called when we aren't looking at a cache.
252  {
253  assert(private_key_for_cache.size());
254  return private_key_for_cache;
255  }
256 
257  size_t getCacheKeySize() const
258  {
259  return private_key_for_cache.size();
260  }
261 
262  str_ref getTableNameRef() const
263  {
264  return table_name;
265  }
266 
267  const char *getTableName() const
268  {
269  return table_name.data();
270  }
271 
272  str_ref getSchemaNameRef() const
273  {
274  return db;
275  }
276 
277  const char *getSchemaName() const
278  {
279  return db.data();
280  }
281 
282  uint32_t block_size; /* create information */
283 
284 private:
285  uint64_t version;
286 
287 public:
288  uint64_t getVersion() const
289  {
290  return version;
291  }
292 
293  void refreshVersion();
294 
295  void resetVersion()
296  {
297  version= 0;
298  }
299 
300 private:
301  uint32_t timestamp_offset; /* Set to offset+1 of record */
302 
303  uint32_t reclength; /* Recordlength */
304  uint32_t stored_rec_length; /* Stored record length*/
305 
306 public:
307  uint32_t sizeStoredRecord() const
308  {
309  return stored_rec_length;
310  }
311 
312  uint32_t getRecordLength() const
313  {
314  return reclength;
315  }
316 
317  void setRecordLength(uint32_t arg)
318  {
319  reclength= arg;
320  }
321 
322  const Field_blob *getBlobFieldAt(uint32_t arg) const
323  {
324  if (arg < blob_fields)
325  return (Field_blob*) _fields[blob_field[arg]];
326 
327  return NULL;
328  }
329 
330 private:
331  /* Max rows is a hint to HEAP during a create tmp table */
332  uint64_t max_rows;
333 
334  boost::scoped_ptr<message::Table> _table_message;
335 
336 public:
337  /*
338  @note Without a _table_message, we assume we are building a STANDARD table.
339  This will be modified once we use Identifiers in the Share itself.
340  */
341  message::Table::TableType getTableType() const
342  {
343  return getTableMessage() ? getTableMessage()->type() : message::Table::STANDARD;
344  }
345 
346  const std::string &getTableTypeAsString() const
347  {
348  if (getTableMessage())
349  return message::type(getTableMessage()->type());
350 
351  return NO_PROTOBUFFER_AVAILABLE;
352  }
353 
354  /* This is only used in one location currently */
355  inline message::Table *getTableMessage() const
356  {
357  return _table_message.get();
358  }
359 
360  void setTableMessage(const message::Table &arg)
361  {
362  assert(not getTableMessage());
363  _table_message.reset(new message::Table(arg));
364  }
365 
366  const message::Table::Field &field(int32_t field_position) const
367  {
368  assert(getTableMessage());
369  return getTableMessage()->field(field_position);
370  }
371 
372  inline bool hasComment() const
373  {
374  return getTableMessage() ? getTableMessage()->options().has_comment() : false;
375  }
376 
377  inline const char *getComment()
378  {
379  return (getTableMessage() && getTableMessage()->has_options()) ? getTableMessage()->options().comment().c_str() : NULL;
380  }
381 
382  inline uint32_t getCommentLength() const
383  {
384  return (getTableMessage()) ? getTableMessage()->options().comment().length() : 0;
385  }
386 
387  inline uint64_t getMaxRows() const
388  {
389  return max_rows;
390  }
391 
392  inline void setMaxRows(uint64_t arg)
393  {
394  max_rows= arg;
395  }
396 
401  bool fieldInPrimaryKey(Field *field) const;
402 
403  plugin::StorageEngine *storage_engine; /* storage engine plugin */
404  inline plugin::StorageEngine *db_type() const /* table_type for handler */
405  {
406  return storage_engine;
407  }
408  inline plugin::StorageEngine *getEngine() const /* table_type for handler */
409  {
410  return storage_engine;
411  }
412 
413 private:
414  identifier::Table::Type tmp_table;
415 public:
416 
417  identifier::Table::Type getType() const
418  {
419  return tmp_table;
420  }
421 
422 private:
423  uint32_t _ref_count; /* How many Table objects uses this */
424 
425 public:
426  uint32_t getTableCount() const
427  {
428  return _ref_count;
429  }
430 
431  void incrementTableCount()
432  {
433  lock();
434  _ref_count++;
435  unlock();
436  }
437 
438  uint32_t decrementTableCount()
439  {
440  return --_ref_count;
441  }
442 
443  uint32_t null_bytes;
444  uint32_t last_null_bit_pos;
445 private:
446  uint32_t _field_size; /* Number of fields */
447 
448 public:
449  void setFieldSize(uint32_t arg)
450  {
451  _field_size= arg;
452  }
453 
454  uint32_t sizeFields() const
455  {
456  return _field_size;
457  }
458 
459  uint32_t rec_buff_length; /* Size of table->record[] buffer */
460  uint32_t keys;
461 
462  uint32_t sizeKeys() const
463  {
464  return keys;
465  }
466  uint32_t key_parts;
467  uint32_t max_key_length, max_unique_length, total_key_length;
468  uint32_t uniques; /* Number of UNIQUE index */
469  uint32_t null_fields; /* number of null fields */
470  uint32_t blob_fields; /* number of blob fields */
471 private:
472  bool has_variable_width; /* number of varchar fields */
473 
474 public:
475  bool hasVariableWidth() const
476  {
477  return has_variable_width; // We should calculate this.
478  }
479  void setVariableWidth()
480  {
481  has_variable_width= true;
482  }
483  uint32_t db_create_options; /* Create options from database */
484  uint32_t db_options_in_use; /* Options in use */
485  uint32_t db_record_offset; /* if HA_REC_IN_SEQ */
486  uint32_t rowid_field_offset; /* Field_nr +1 to rowid field */
496 private:
497  uint32_t primary_key;
498 public:
499 
500  uint32_t getPrimaryKey() const
501  {
502  return primary_key;
503  }
504 
505  bool hasPrimaryKey() const
506  {
507  return primary_key != MAX_KEY;
508  }
509 
510  /* Index of auto-updated TIMESTAMP field in field array */
511  uint32_t next_number_index; /* autoincrement key number */
512  uint32_t next_number_key_offset; /* autoinc keypart offset in a key */
513  uint32_t next_number_keypart; /* autoinc keypart number in a key */
514  uint32_t error, open_errno, errarg; /* error from open_table_def() */
515 
516 private:
517  uint8_t blob_ptr_size; /* 4 or 8 */
518 
519 public:
520  uint8_t sizeBlobPtr() const
521  {
522  return blob_ptr_size;
523  }
524 
525  bool db_low_byte_first; /* Portable row format */
526 
527  /*
528  Set of keys in use, implemented as a Bitmap.
529  Excludes keys disabled by ALTER Table ... DISABLE KEYS.
530  */
531  key_map keys_in_use;
532  key_map keys_for_keyread;
533 
534  /*
535  event_observers is a class containing all the event plugins that have
536  registered an interest in this table.
537  */
538  virtual plugin::EventObserverList *getTableObservers()
539  {
540  return NULL;
541  }
542 
543  virtual void setTableObservers(plugin::EventObserverList *)
544  { }
545 
546  /*
547  Set share's identifier information.
548 
549  SYNOPSIS
550  setIdentifier()
551 
552  NOTES
553  */
554 
555  void setIdentifier(const identifier::Table &identifier_arg);
556 
557  /*
558  Initialize share for temporary tables
559 
560  SYNOPSIS
561  init()
562  share Share to fill
563  key Table_cache_key, as generated from create_table_def_key.
564  must start with db name.
565  key_length Length of key
566  table_name Table name
567  path Path to table (possible in lower case)
568 
569  NOTES
570 
571  */
572 
573 private:
574  void init(const char *new_table_name,
575  const char *new_path);
576 
577 protected:
578  void open_table_error(int pass_error, int db_errno, int pass_errarg);
579 
580 public:
581 
582  static TableShare::shared_ptr getShareCreate(Session*, const identifier::Table&, int &error);
583 
584  friend std::ostream& operator<<(std::ostream& output, const TableShare &share)
585  {
586  return output << "TableShare:(" << share.getSchemaNameRef() << ", " << share.getTableName() << ", " << share.getTableTypeAsString() << ", " << share.getPath() << ")";
587  }
588 
589 protected:
590  friend class drizzled::table::Singular;
591 
592  Field *make_field(const message::Table::Field &pfield,
593  unsigned char *ptr,
594  uint32_t field_length,
595  bool is_nullable,
596  unsigned char *null_pos,
597  unsigned char null_bit,
598  uint8_t decimals,
599  enum_field_types field_type,
600  const charset_info_st * field_charset,
601  Field::utype unireg_check,
602  TYPELIB *interval,
603  const char *field_name);
604 
605  Field *make_field(const message::Table::Field &pfield,
606  unsigned char *ptr,
607  uint32_t field_length,
608  bool is_nullable,
609  unsigned char *null_pos,
610  unsigned char null_bit,
611  uint8_t decimals,
612  enum_field_types field_type,
613  const charset_info_st * field_charset,
614  Field::utype unireg_check,
615  TYPELIB *interval,
616  const char *field_name,
617  bool is_unsigned);
618 
619 public:
620  int open_table_def(Session& session, const identifier::Table &identifier);
621 
622  int open_table_from_share(Session *session,
623  const identifier::Table &identifier,
624  const char *alias,
625  uint32_t db_stat, uint32_t ha_open_flags,
626  Table &outparam);
627 private:
628  int open_table_from_share_inner(Session *session,
629  const char *alias,
630  uint32_t db_stat,
631  Table &outparam);
632  int open_table_cursor_inner(const identifier::Table &identifier,
633  uint32_t db_stat, uint32_t ha_open_flags,
634  Table &outparam,
635  bool &error_reported);
636 public:
637  bool parse_table_proto(Session& session, const message::Table &table);
638 
639  virtual bool is_replicated() const
640  {
641  return false;
642  }
643 };
644 
645 } /* namespace drizzled */
646