1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2009 Sun Microsystems, Inc.
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.
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.
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
22
This class is shared between different table objects. There is one
23
instance of table share per one table in the database.
26
#ifndef DRIZZLED_TABLE_INSTANCE_BASE_H
27
#define DRIZZLED_TABLE_INSTANCE_BASE_H
31
#include <boost/unordered_map.hpp>
32
#include <boost/thread/condition_variable.hpp>
33
#include <boost/dynamic_bitset.hpp>
34
#include <boost/shared_ptr.hpp>
35
#include <boost/scoped_ptr.hpp>
37
#include <drizzled/memory/root.h>
38
#include <drizzled/message.h>
39
#include <drizzled/util/string.h>
41
#include <drizzled/lex_string.h>
42
#include <drizzled/key_map.h>
44
#include <drizzled/table/cache.h>
46
#include <drizzled/field.h>
52
const static std::string NO_PROTOBUFFER_AVAILABLE("NO PROTOBUFFER AVAILABLE");
56
class EventObserverList;
68
typedef std::vector<std::string> StringVector;
71
typedef boost::shared_ptr<TableShare> shared_ptr;
72
typedef std::vector <shared_ptr> vector;
74
TableShare(const identifier::Table::Type type_arg);
76
TableShare(const identifier::Table &identifier, const identifier::Table::Key &key); // Used by placeholder
78
TableShare(const identifier::Table &identifier); // Just used during createTable()
80
TableShare(const identifier::Table::Type type_arg,
81
const identifier::Table &identifier,
82
char *path_arg= NULL, uint32_t path_length_arg= 0); // Shares for cache
84
virtual ~TableShare();
87
/** Category of this table. */
88
enum_table_category table_category;
91
bool isTemporaryCategory() const
93
return (table_category == TABLE_CATEGORY_TEMPORARY);
96
void setTableCategory(enum_table_category arg)
101
/* The following is copied to each Table on OPEN */
102
typedef std::vector<Field *> Fields;
108
const Fields getFields() const
118
Field ** getFields(bool)
123
void setFields(uint32_t arg)
128
uint32_t positionFields(Field **arg) const
130
return (arg - (Field **)&_fields[0]);
133
void pushField(Field *arg)
136
_fields.push_back(arg);
139
Field **found_next_number_field;
142
Field *timestamp_field; /* Used only during open */
146
Field *getTimestampField() const /* Used only during open */
148
return timestamp_field;
151
void setTimestampField(Field *arg) /* Used only during open */
153
timestamp_field= arg;
158
KeyInfo *key_info; /* data of keys in database */
161
KeyInfo &getKeyInfo(uint32_t arg) const
163
return key_info[arg];
165
std::vector<uint> blob_field; /* Index to blobs in Field arrray*/
168
/* hash of field names (contains pointers to elements of field array) */
169
typedef boost::unordered_map < std::string, Field **, util::insensitive_hash, util::insensitive_equal_to> FieldMap;
170
typedef std::pair< std::string, Field ** > FieldMapPair;
171
FieldMap name_hash; /* hash of field names */
174
size_t getNamedFieldSize() const
176
return name_hash.size();
179
Field **getNamedField(const std::string &arg)
181
FieldMap::iterator iter= name_hash.find(arg);
183
if (iter == name_hash.end())
186
return (*iter).second;
190
memory::Root mem_root;
192
void *alloc_root(size_t arg)
194
return mem_root.alloc_root(arg);
197
char *strmake_root(const char *str_arg, size_t len_arg)
199
return mem_root.strmake_root(str_arg, len_arg);
202
memory::Root *getMemRoot()
207
std::vector<std::string> _keynames;
209
void addKeyName(std::string arg)
211
std::transform(arg.begin(), arg.end(),
212
arg.begin(), ::toupper);
213
_keynames.push_back(arg);
217
bool doesKeyNameExist(const char *name_arg, uint32_t name_length, uint32_t &position) const
219
return doesKeyNameExist(std::string(name_arg, name_length), position);
222
bool doesKeyNameExist(std::string arg, uint32_t &position) const
224
std::transform(arg.begin(), arg.end(),
225
arg.begin(), ::toupper);
227
std::vector<std::string>::const_iterator iter= std::find(_keynames.begin(), _keynames.end(), arg);
229
if (iter == _keynames.end())
231
position= UINT32_MAX; //historical, required for finding primary key from unique
235
position= iter - _keynames.begin();
241
std::vector<TYPELIB> intervals; /* pointer to interval info */
247
virtual void unlock()
251
std::vector<unsigned char> default_values; /* row with default values */
254
// @note This needs to be made to be const in the future
255
unsigned char *getDefaultValues()
257
return &default_values[0];
259
void resizeDefaultValues(size_t arg)
261
default_values.resize(arg);
264
const charset_info_st *table_charset; /* Default charset of string fields */
266
boost::dynamic_bitset<> all_set;
269
Key which is used for looking-up table in table cache and in the list
270
of thread's temporary tables. Has the form of:
271
"database_name\0table_name\0" + optional part for temporary tables.
273
Note that all three 'table_cache_key', 'db' and 'table_name' members
274
must be set (and be non-zero) for tables in table cache. They also
275
should correspond to each other.
276
To ensure this one can use set_table_cache() methods.
279
identifier::Table::Key private_key_for_cache; // This will not exist in the final design.
280
std::vector<char> private_normalized_path; // This will not exist in the final design.
281
LEX_STRING db; /* Pointer to db */
282
LEX_STRING table_name; /* Table name (for open) */
283
LEX_STRING path; /* Path to table (from datadir) */
284
LEX_STRING normalized_path; /* unpack_filename(path) */
288
const char *getNormalizedPath() const
290
return normalized_path.str;
293
const char *getPath() const
298
const identifier::Table::Key& getCacheKey() const // This should never be called when we aren't looking at a cache.
300
assert(private_key_for_cache.size());
301
return private_key_for_cache;
304
size_t getCacheKeySize() const
306
return private_key_for_cache.size();
310
void setPath(char *str_arg, uint32_t size_arg)
313
path.length= size_arg;
316
void setNormalizedPath(char *str_arg, uint32_t size_arg)
318
normalized_path.str= str_arg;
319
normalized_path.length= size_arg;
324
const char *getTableName() const
326
return table_name.str;
329
uint32_t getTableNameSize() const
331
return table_name.length;
334
const std::string &getTableName(std::string &name_arg) const
337
name_arg.append(table_name.str, table_name.length);
342
const char *getSchemaName() const
347
const std::string &getSchemaName(std::string &schema_name_arg) const
349
schema_name_arg.clear();
350
schema_name_arg.append(db.str, db.length);
352
return schema_name_arg;
355
uint32_t block_size; /* create information */
361
uint64_t getVersion() const
366
void refreshVersion();
374
uint32_t timestamp_offset; /* Set to offset+1 of record */
376
uint32_t reclength; /* Recordlength */
377
uint32_t stored_rec_length; /* Stored record length*/
380
uint32_t sizeStoredRecord() const
382
return stored_rec_length;
385
uint32_t getRecordLength() const
390
void setRecordLength(uint32_t arg)
395
const Field_blob *getBlobFieldAt(uint32_t arg) const
397
if (arg < blob_fields)
398
return (Field_blob*) _fields[blob_field[arg]];
404
/* Max rows is a hint to HEAP during a create tmp table */
407
boost::scoped_ptr<message::Table> _table_message;
411
@note Without a _table_message, we assume we are building a STANDARD table.
412
This will be modified once we use Identifiers in the Share itself.
414
message::Table::TableType getTableType() const
416
return getTableMessage() ? getTableMessage()->type() : message::Table::STANDARD;
419
const std::string &getTableTypeAsString() const
421
if (getTableMessage())
422
return message::type(getTableMessage()->type());
424
return NO_PROTOBUFFER_AVAILABLE;
427
/* This is only used in one location currently */
428
inline message::Table *getTableMessage() const
430
return _table_message.get();
433
void setTableMessage(const message::Table &arg)
435
assert(not getTableMessage());
436
_table_message.reset(new(std::nothrow) message::Table(arg));
439
const message::Table::Field &field(int32_t field_position) const
441
assert(getTableMessage());
442
return getTableMessage()->field(field_position);
445
inline bool hasComment() const
447
return (getTableMessage()) ? getTableMessage()->options().has_comment() : false;
450
inline const char *getComment()
452
return (getTableMessage() && getTableMessage()->has_options()) ? getTableMessage()->options().comment().c_str() : NULL;
455
inline uint32_t getCommentLength() const
457
return (getTableMessage()) ? getTableMessage()->options().comment().length() : 0;
460
inline uint64_t getMaxRows() const
465
inline void setMaxRows(uint64_t arg)
471
* Returns true if the supplied Field object
472
* is part of the table's primary key.
474
bool fieldInPrimaryKey(Field *field) const;
476
plugin::StorageEngine *storage_engine; /* storage engine plugin */
477
inline plugin::StorageEngine *db_type() const /* table_type for handler */
479
return storage_engine;
481
inline plugin::StorageEngine *getEngine() const /* table_type for handler */
483
return storage_engine;
487
identifier::Table::Type tmp_table;
490
identifier::Table::Type getType() const
496
uint32_t _ref_count; /* How many Table objects uses this */
499
uint32_t getTableCount() const
504
void incrementTableCount()
511
uint32_t decrementTableCount()
517
uint32_t last_null_bit_pos;
519
uint32_t _field_size; /* Number of fields */
522
void setFieldSize(uint32_t arg)
527
uint32_t sizeFields() const
532
uint32_t rec_buff_length; /* Size of table->record[] buffer */
535
uint32_t sizeKeys() const
540
uint32_t max_key_length, max_unique_length, total_key_length;
541
uint32_t uniques; /* Number of UNIQUE index */
542
uint32_t null_fields; /* number of null fields */
543
uint32_t blob_fields; /* number of blob fields */
545
bool has_variable_width; /* number of varchar fields */
548
bool hasVariableWidth() const
550
return has_variable_width; // We should calculate this.
552
void setVariableWidth()
554
has_variable_width= true;
556
uint32_t db_create_options; /* Create options from database */
557
uint32_t db_options_in_use; /* Options in use */
558
uint32_t db_record_offset; /* if HA_REC_IN_SEQ */
559
uint32_t rowid_field_offset; /* Field_nr +1 to rowid field */
563
* Currently the replication services component uses
564
* the primary_key member to determine which field is the table's
565
* primary key. However, as it exists, because this member is scalar, it
566
* only supports a single-column primary key. Is there a better way
567
* to ask for the fields which are in a primary key?
570
uint32_t primary_key;
573
uint32_t getPrimaryKey() const
578
bool hasPrimaryKey() const
580
return primary_key != MAX_KEY;
583
/* Index of auto-updated TIMESTAMP field in field array */
584
uint32_t next_number_index; /* autoincrement key number */
585
uint32_t next_number_key_offset; /* autoinc keypart offset in a key */
586
uint32_t next_number_keypart; /* autoinc keypart number in a key */
587
uint32_t error, open_errno, errarg; /* error from open_table_def() */
590
uint8_t blob_ptr_size; /* 4 or 8 */
593
uint8_t sizeBlobPtr() const
595
return blob_ptr_size;
598
bool db_low_byte_first; /* Portable row format */
601
Set of keys in use, implemented as a Bitmap.
602
Excludes keys disabled by ALTER Table ... DISABLE KEYS.
605
key_map keys_for_keyread;
608
event_observers is a class containing all the event plugins that have
609
registered an interest in this table.
611
virtual plugin::EventObserverList *getTableObservers()
616
virtual void setTableObservers(plugin::EventObserverList *)
620
Set share's identifier information.
628
void setIdentifier(const identifier::Table &identifier_arg);
631
Initialize share for temporary tables
636
key Table_cache_key, as generated from create_table_def_key.
637
must start with db name.
638
key_length Length of key
639
table_name Table name
640
path Path to table (possible in lower case)
647
void init(const char *new_table_name,
648
const char *new_path);
651
void open_table_error(int pass_error, int db_errno, int pass_errarg);
655
static TableShare::shared_ptr getShareCreate(Session *session,
656
const identifier::Table &identifier,
659
friend std::ostream& operator<<(std::ostream& output, const TableShare &share)
661
output << "TableShare:(";
662
output << share.getSchemaName();
664
output << share.getTableName();
666
output << share.getTableTypeAsString();
668
output << share.getPath();
671
return output; // for multiple << operators.
675
friend class drizzled::table::Singular;
677
Field *make_field(const message::Table::Field &pfield,
679
uint32_t field_length,
681
unsigned char *null_pos,
682
unsigned char null_bit,
684
enum_field_types field_type,
685
const charset_info_st * field_charset,
686
Field::utype unireg_check,
688
const char *field_name);
690
Field *make_field(const message::Table::Field &pfield,
692
uint32_t field_length,
694
unsigned char *null_pos,
695
unsigned char null_bit,
697
enum_field_types field_type,
698
const charset_info_st * field_charset,
699
Field::utype unireg_check,
701
const char *field_name,
705
int open_table_def(Session& session, const identifier::Table &identifier);
707
int open_table_from_share(Session *session,
708
const identifier::Table &identifier,
710
uint32_t db_stat, uint32_t ha_open_flags,
713
int open_table_from_share_inner(Session *session,
717
int open_table_cursor_inner(const identifier::Table &identifier,
718
uint32_t db_stat, uint32_t ha_open_flags,
720
bool &error_reported);
722
bool parse_table_proto(Session& session, message::Table &table);
724
virtual bool replicate() const
730
} /* namespace drizzled */
732
#endif /* DRIZZLED_TABLE_INSTANCE_BASE_H */