~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table_share.h

  • Committer: Monty Taylor
  • Date: 2008-11-16 06:29:53 UTC
  • mto: (584.1.9 devel)
  • mto: This revision was merged to the branch mainline in revision 589.
  • Revision ID: monty@inaugust.com-20081116062953-ivdltjmfe009b5fr
Moved stuff into item/

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
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
 
#ifndef DRIZZLED_TABLE_SHARE_H
27
 
#define DRIZZLED_TABLE_SHARE_H
28
 
 
29
 
#include <string>
30
 
 
31
 
#include <boost/unordered_map.hpp>
32
 
#include <boost/thread/condition_variable.hpp>
33
 
 
34
 
#include "drizzled/typelib.h"
35
 
#include "drizzled/memory/root.h"
36
 
#include "drizzled/message/table.pb.h"
37
 
#include "drizzled/util/string.h"
38
 
 
39
 
namespace drizzled
40
 
{
41
 
 
42
 
typedef boost::unordered_map< TableIdentifier::Key, TableShare *> TableDefinitionCache;
43
 
 
44
 
const static std::string STANDARD_STRING("STANDARD");
45
 
const static std::string TEMPORARY_STRING("TEMPORARY");
46
 
const static std::string INTERNAL_STRING("INTERNAL");
47
 
const static std::string FUNCTION_STRING("FUNCTION");
48
 
 
49
 
namespace plugin
50
 
{
51
 
class EventObserverList;
52
 
}
53
 
 
54
 
class Field_blob;
55
 
 
56
 
class TableShare
57
 
{
58
 
  typedef std::vector<std::string> StringVector;
59
 
public:
60
 
  TableShare(TableIdentifier::Type type_arg);
61
 
 
62
 
  TableShare(TableIdentifier &identifier, const TableIdentifier::Key &key); // Used by placeholder
63
 
 
64
 
  TableShare(const TableIdentifier &identifier); // Just used during createTable()
65
 
 
66
 
  TableShare(TableIdentifier::Type type_arg,
67
 
             TableIdentifier &identifier,
68
 
             char *path_arg= NULL, uint32_t path_length_arg= 0); // Shares for cache
69
 
 
70
 
  ~TableShare();
71
 
 
72
 
private:
73
 
  /** Category of this table. */
74
 
  enum_table_category table_category;
75
 
 
76
 
  uint32_t open_count;                  /* Number of tables in open list */
77
 
public:
78
 
 
79
 
  bool isTemporaryCategory() const
80
 
  {
81
 
    return (table_category == TABLE_CATEGORY_TEMPORARY);
82
 
  }
83
 
 
84
 
  void setTableCategory(enum_table_category arg)
85
 
  {
86
 
    table_category= arg;
87
 
  }
88
 
 
89
 
  /* The following is copied to each Table on OPEN */
90
 
  typedef std::vector<Field *> Fields;
91
 
private:
92
 
  Fields field;
93
 
public:
94
 
  const Fields getFields() const
95
 
  {
96
 
    return field;
97
 
  }
98
 
 
99
 
  Field ** getFields(bool)
100
 
  {
101
 
    return &field[0];
102
 
  }
103
 
 
104
 
  void setFields(uint32_t arg)
105
 
  {
106
 
    field.resize(arg);
107
 
  }
108
 
 
109
 
  uint32_t positionFields(Field **arg) const
110
 
  {
111
 
    return (arg - (Field **)&field[0]);
112
 
  }
113
 
 
114
 
  void pushField(Field *arg)
115
 
  {
116
 
    fields++;
117
 
    field.push_back(arg);
118
 
  }
119
 
 
120
 
 
121
 
  Field **found_next_number_field;
122
 
private:
123
 
  Field *timestamp_field;               /* Used only during open */
124
 
public:
125
 
 
126
 
  Field *getTimestampField() const               /* Used only during open */
127
 
  {
128
 
    return timestamp_field;
129
 
  }
130
 
 
131
 
  void setTimestampField(Field *arg) /* Used only during open */
132
 
  {
133
 
    timestamp_field= arg;
134
 
  }
135
 
 
136
 
 
137
 
private:
138
 
  KeyInfo  *key_info;                   /* data of keys in database */
139
 
public:
140
 
  KeyInfo &getKeyInfo(uint32_t arg) const
141
 
  {
142
 
    return key_info[arg];
143
 
  }
144
 
  std::vector<uint>     blob_field;                     /* Index to blobs in Field arrray*/
145
 
 
146
 
  /* hash of field names (contains pointers to elements of field array) */
147
 
private:
148
 
  typedef boost::unordered_map < std::string, Field **, util::insensitive_hash, util::insensitive_equal_to> FieldMap;
149
 
  typedef std::pair< std::string, Field ** > FieldMapPair;
150
 
  FieldMap name_hash; /* hash of field names */
151
 
public:
152
 
  size_t getNamedFieldSize() const
153
 
  {
154
 
    return name_hash.size();
155
 
  }
156
 
 
157
 
  Field **getNamedField(const std::string &arg)
158
 
  {
159
 
    FieldMap::iterator iter= name_hash.find(arg);
160
 
 
161
 
    if (iter == name_hash.end())
162
 
        return 0;
163
 
 
164
 
    return (*iter).second;
165
 
  }
166
 
 
167
 
private:
168
 
  memory::Root mem_root;
169
 
public:
170
 
  void *alloc_root(size_t arg)
171
 
  {
172
 
    return mem_root.alloc_root(arg);
173
 
  }
174
 
 
175
 
  char *strmake_root(const char *str_arg, size_t len_arg)
176
 
  {
177
 
    return mem_root.strmake_root(str_arg, len_arg);
178
 
  }
179
 
 
180
 
  memory::Root *getMemRoot()
181
 
  {
182
 
    return &mem_root;
183
 
  }
184
 
 
185
 
private:
186
 
  std::vector<std::string> _keynames;
187
 
 
188
 
  void addKeyName(std::string arg)
189
 
  {
190
 
    std::transform(arg.begin(), arg.end(),
191
 
                   arg.begin(), ::toupper);
192
 
    _keynames.push_back(arg);
193
 
  }
194
 
public:
195
 
  bool doesKeyNameExist(const char *name_arg, uint32_t name_length, uint32_t &position) const
196
 
  {
197
 
    std::string arg(name_arg, name_length);
198
 
    std::transform(arg.begin(), arg.end(),
199
 
                   arg.begin(), ::toupper);
200
 
 
201
 
    std::vector<std::string>::const_iterator iter= std::find(_keynames.begin(), _keynames.end(), arg);
202
 
 
203
 
    if (iter == _keynames.end())
204
 
      return false;
205
 
 
206
 
    position= iter -  _keynames.begin();
207
 
 
208
 
    return true;
209
 
  }
210
 
 
211
 
  bool doesKeyNameExist(std::string arg, uint32_t &position) const
212
 
  {
213
 
    std::transform(arg.begin(), arg.end(),
214
 
                   arg.begin(), ::toupper);
215
 
 
216
 
    std::vector<std::string>::const_iterator iter= std::find(_keynames.begin(), _keynames.end(), arg);
217
 
 
218
 
    if (iter == _keynames.end())
219
 
    {
220
 
      position= -1; //historical, required for finding primary key from unique
221
 
      return false;
222
 
    }
223
 
 
224
 
    position= iter -  _keynames.begin();
225
 
 
226
 
    return true;
227
 
  }
228
 
 
229
 
private:
230
 
  std::vector<TYPELIB> intervals;                       /* pointer to interval info */
231
 
 
232
 
  boost::mutex mutex;                /* For locking the share  */
233
 
  boost::condition_variable cond;                       /* To signal that share is ready */
234
 
 
235
 
 
236
 
  void lock()
237
 
  {
238
 
    mutex.lock();
239
 
  }
240
 
 
241
 
  void unlock()
242
 
  {
243
 
    mutex.unlock();
244
 
  }
245
 
public:
246
 
 
247
 
private:
248
 
  std::vector<unsigned char> default_values;            /* row with default values */
249
 
public:
250
 
  unsigned char * getDefaultValues()
251
 
  {
252
 
    return &default_values[0];
253
 
  }
254
 
  void resizeDefaultValues(size_t arg)
255
 
  {
256
 
    default_values.resize(arg);
257
 
  }
258
 
 
259
 
  const CHARSET_INFO *table_charset; /* Default charset of string fields */
260
 
 
261
 
  MyBitmap all_set;
262
 
private:
263
 
  std::vector<my_bitmap_map> all_bitmap;
264
 
 
265
 
public:
266
 
  /*
267
 
    Key which is used for looking-up table in table cache and in the list
268
 
    of thread's temporary tables. Has the form of:
269
 
    "database_name\0table_name\0" + optional part for temporary tables.
270
 
 
271
 
    Note that all three 'table_cache_key', 'db' and 'table_name' members
272
 
    must be set (and be non-zero) for tables in table cache. They also
273
 
    should correspond to each other.
274
 
    To ensure this one can use set_table_cache() methods.
275
 
  */
276
 
private:
277
 
  TableIdentifier::Key private_key_for_cache; // This will not exist in the final design.
278
 
  std::vector<char> private_normalized_path; // This will not exist in the final design.
279
 
  LEX_STRING db;                        /* Pointer to db */
280
 
  LEX_STRING table_name;                /* Table name (for open) */
281
 
  LEX_STRING path;      /* Path to table (from datadir) */
282
 
  LEX_STRING normalized_path;           /* unpack_filename(path) */
283
 
public:
284
 
 
285
 
  const char *getNormalizedPath() const
286
 
  {
287
 
    return normalized_path.str;
288
 
  }
289
 
 
290
 
  const char *getPath() const
291
 
  {
292
 
    return path.str;
293
 
  }
294
 
 
295
 
  const TableIdentifier::Key& getCacheKey() const // This should never be called when we aren't looking at a cache.
296
 
  {
297
 
    assert(private_key_for_cache.size());
298
 
    return private_key_for_cache;
299
 
  }
300
 
 
301
 
  size_t getCacheKeySize() const
302
 
  {
303
 
    return private_key_for_cache.size();
304
 
  }
305
 
 
306
 
  void setPath(char *str_arg, uint32_t size_arg)
307
 
  {
308
 
    path.str= str_arg;
309
 
    path.length= size_arg;
310
 
  }
311
 
 
312
 
  void setNormalizedPath(char *str_arg, uint32_t size_arg)
313
 
  {
314
 
    normalized_path.str= str_arg;
315
 
    normalized_path.length= size_arg;
316
 
  }
317
 
 
318
 
  const char *getTableName() const
319
 
  {
320
 
    return table_name.str;
321
 
  }
322
 
 
323
 
  uint32_t getTableNameSize() const
324
 
  {
325
 
    return table_name.length;
326
 
  }
327
 
 
328
 
  const std::string &getTableName(std::string &name_arg) const
329
 
  {
330
 
    name_arg.clear();
331
 
    name_arg.append(table_name.str, table_name.length);
332
 
 
333
 
    return name_arg;
334
 
  }
335
 
 
336
 
  const char *getSchemaName() const
337
 
  {
338
 
    return db.str;
339
 
  }
340
 
 
341
 
  const std::string &getSchemaName(std::string &schema_name_arg) const
342
 
  {
343
 
    schema_name_arg.clear();
344
 
    schema_name_arg.append(db.str, db.length);
345
 
 
346
 
    return schema_name_arg;
347
 
  }
348
 
 
349
 
  uint32_t   block_size;                   /* create information */
350
 
 
351
 
private:
352
 
  uint64_t   version;
353
 
public:
354
 
  uint64_t getVersion() const
355
 
  {
356
 
    return version;
357
 
  }
358
 
 
359
 
  void refreshVersion()
360
 
  {
361
 
   version= refresh_version;
362
 
  }
363
 
 
364
 
  void resetVersion()
365
 
  {
366
 
    version= 0;
367
 
  }
368
 
 
369
 
  uint32_t   timestamp_offset;          /* Set to offset+1 of record */
370
 
private:
371
 
  uint32_t   reclength;                 /* Recordlength */
372
 
public:
373
 
  uint32_t   stored_rec_length;         /* Stored record length*/
374
 
 
375
 
  uint32_t getRecordLength() const
376
 
  {
377
 
    return reclength;
378
 
  }
379
 
 
380
 
  void setRecordLength(uint32_t arg)
381
 
  {
382
 
    reclength= arg;
383
 
  }
384
 
 
385
 
  const Field_blob *getBlobFieldAt(uint32_t arg) const
386
 
  {
387
 
    if (arg < blob_fields)
388
 
      return (Field_blob*) field[blob_field[arg]];
389
 
 
390
 
    return NULL;
391
 
  }
392
 
 
393
 
private:
394
 
  /* Max rows is a hint to HEAP during a create tmp table */
395
 
  uint64_t max_rows;
396
 
 
397
 
  message::Table *table_proto;
398
 
public:
399
 
 
400
 
  /*
401
 
    @note Without a table_proto, we assume we are building a STANDARD table.
402
 
    This will be modified once we use Identifiers in the Share itself.
403
 
  */
404
 
  message::Table::TableType getTableType() const
405
 
  {
406
 
    return table_proto ? table_proto->type() : message::Table::STANDARD;
407
 
  }
408
 
 
409
 
  const std::string &getTableTypeAsString() const
410
 
  {
411
 
    switch (table_proto->type())
412
 
    {
413
 
    default:
414
 
    case message::Table::STANDARD:
415
 
      return STANDARD_STRING;
416
 
    case message::Table::TEMPORARY:
417
 
      return TEMPORARY_STRING;
418
 
    case message::Table::INTERNAL:
419
 
      return INTERNAL_STRING;
420
 
    case message::Table::FUNCTION:
421
 
      return FUNCTION_STRING;
422
 
    }
423
 
  }
424
 
 
425
 
  /* This is only used in one location currently */
426
 
  inline message::Table *getTableProto() const
427
 
  {
428
 
    return table_proto;
429
 
  }
430
 
 
431
 
  inline void setTableProto(message::Table *arg)
432
 
  {
433
 
    assert(table_proto == NULL);
434
 
    table_proto= arg;
435
 
  }
436
 
 
437
 
  inline bool hasComment() const
438
 
  {
439
 
    return (table_proto) ?  table_proto->options().has_comment() : false; 
440
 
  }
441
 
 
442
 
  inline const char *getComment()
443
 
  {
444
 
    return (table_proto && table_proto->has_options()) ?  table_proto->options().comment().c_str() : NULL; 
445
 
  }
446
 
 
447
 
  inline uint32_t getCommentLength() const
448
 
  {
449
 
    return (table_proto) ? table_proto->options().comment().length() : 0; 
450
 
  }
451
 
 
452
 
  inline uint64_t getMaxRows() const
453
 
  {
454
 
    return max_rows;
455
 
  }
456
 
 
457
 
  inline void setMaxRows(uint64_t arg)
458
 
  {
459
 
    max_rows= arg;
460
 
  }
461
 
 
462
 
  /**
463
 
   * Returns true if the supplied Field object
464
 
   * is part of the table's primary key.
465
 
 */
466
 
  bool fieldInPrimaryKey(Field *field) const;
467
 
 
468
 
  plugin::StorageEngine *storage_engine;                        /* storage engine plugin */
469
 
  inline plugin::StorageEngine *db_type() const /* table_type for handler */
470
 
  {
471
 
    return storage_engine;
472
 
  }
473
 
  inline plugin::StorageEngine *getEngine() const       /* table_type for handler */
474
 
  {
475
 
    return storage_engine;
476
 
  }
477
 
 
478
 
private:
479
 
  TableIdentifier::Type tmp_table;
480
 
public:
481
 
 
482
 
  TableIdentifier::Type getType() const
483
 
  {
484
 
    return tmp_table;
485
 
  }
486
 
 
487
 
private:
488
 
  uint32_t ref_count;       /* How many Table objects uses this */
489
 
public:
490
 
  uint32_t getTableCount() const
491
 
  {
492
 
    return ref_count;
493
 
  }
494
 
 
495
 
  void incrementTableCount()
496
 
  {
497
 
    lock();
498
 
    ref_count++;
499
 
    unlock();
500
 
  }
501
 
 
502
 
  uint32_t null_bytes;
503
 
  uint32_t last_null_bit_pos;
504
 
  uint32_t fields;                              /* Number of fields */
505
 
 
506
 
  uint32_t sizeFields() const
507
 
  {
508
 
    return fields;
509
 
  }
510
 
 
511
 
  uint32_t rec_buff_length;                 /* Size of table->record[] buffer */
512
 
  uint32_t keys;
513
 
 
514
 
  uint32_t sizeKeys() const
515
 
  {
516
 
    return keys;
517
 
  }
518
 
  uint32_t key_parts;
519
 
  uint32_t max_key_length, max_unique_length, total_key_length;
520
 
  uint32_t uniques;                         /* Number of UNIQUE index */
521
 
  uint32_t null_fields;                 /* number of null fields */
522
 
  uint32_t blob_fields;                 /* number of blob fields */
523
 
  uint32_t timestamp_field_offset;              /* Field number for timestamp field */
524
 
  uint32_t varchar_fields;                  /* number of varchar fields */
525
 
  uint32_t db_create_options;           /* Create options from database */
526
 
  uint32_t db_options_in_use;           /* Options in use */
527
 
  uint32_t db_record_offset;            /* if HA_REC_IN_SEQ */
528
 
  uint32_t rowid_field_offset;          /* Field_nr +1 to rowid field */
529
 
  /**
530
 
   * @TODO 
531
 
   *
532
 
   * Currently the replication services component uses
533
 
   * the primary_key member to determine which field is the table's
534
 
   * primary key.  However, as it exists, because this member is scalar, it
535
 
   * only supports a single-column primary key. Is there a better way
536
 
   * to ask for the fields which are in a primary key?
537
 
 */
538
 
private:
539
 
  uint32_t primary_key;
540
 
public:
541
 
 
542
 
  uint32_t getPrimaryKey() const
543
 
  {
544
 
    return primary_key;
545
 
  }
546
 
 
547
 
  bool hasPrimaryKey() const
548
 
  {
549
 
    return primary_key != MAX_KEY;
550
 
  }
551
 
 
552
 
  /* Index of auto-updated TIMESTAMP field in field array */
553
 
  uint32_t next_number_index;               /* autoincrement key number */
554
 
  uint32_t next_number_key_offset;          /* autoinc keypart offset in a key */
555
 
  uint32_t next_number_keypart;             /* autoinc keypart number in a key */
556
 
  uint32_t error, open_errno, errarg;       /* error from open_table_def() */
557
 
  uint32_t column_bitmap_size;
558
 
 
559
 
  uint8_t blob_ptr_size;                        /* 4 or 8 */
560
 
  bool db_low_byte_first;               /* Portable row format */
561
 
 
562
 
private:
563
 
  bool name_lock;
564
 
public:
565
 
  bool isNameLock() const
566
 
  {
567
 
    return name_lock;
568
 
  }
569
 
 
570
 
  bool replace_with_name_lock;
571
 
 
572
 
private:
573
 
  bool waiting_on_cond;                 /* Protection against free */
574
 
public:
575
 
  bool isWaitingOnCondition()
576
 
  {
577
 
    return waiting_on_cond;
578
 
  }
579
 
 
580
 
  /*
581
 
    Set of keys in use, implemented as a Bitmap.
582
 
    Excludes keys disabled by ALTER Table ... DISABLE KEYS.
583
 
  */
584
 
  key_map keys_in_use;
585
 
  key_map keys_for_keyread;
586
 
 
587
 
  /* 
588
 
    event_observers is a class containing all the event plugins that have 
589
 
    registered an interest in this table.
590
 
  */
591
 
  private:
592
 
  plugin::EventObserverList *event_observers;
593
 
  public:
594
 
  plugin::EventObserverList *getTableObservers() 
595
 
  { 
596
 
    return event_observers;
597
 
  }
598
 
  
599
 
  void setTableObservers(plugin::EventObserverList *observers) 
600
 
  { 
601
 
    event_observers= observers;
602
 
  }
603
 
  
604
 
  /*
605
 
    Set share's identifier information.
606
 
 
607
 
    SYNOPSIS
608
 
    setIdentifier()
609
 
 
610
 
    NOTES
611
 
  */
612
 
 
613
 
  void setIdentifier(TableIdentifier &identifier_arg);
614
 
 
615
 
  inline bool honor_global_locks()
616
 
  {
617
 
    return (table_category == TABLE_CATEGORY_USER);
618
 
  }
619
 
 
620
 
 
621
 
  /*
622
 
    Initialize share for temporary tables
623
 
 
624
 
    SYNOPSIS
625
 
    init()
626
 
    share       Share to fill
627
 
    key         Table_cache_key, as generated from create_table_def_key.
628
 
    must start with db name.
629
 
    key_length  Length of key
630
 
    table_name  Table name
631
 
    path        Path to table (possible in lower case)
632
 
 
633
 
    NOTES
634
 
    
635
 
  */
636
 
 
637
 
private:
638
 
  void init(const char *new_table_name,
639
 
            const char *new_path);
640
 
public:
641
 
 
642
 
  void open_table_error(int pass_error, int db_errno, int pass_errarg);
643
 
 
644
 
  static void cacheStart(void);
645
 
  static void release(TableShare *share);
646
 
  static void release(TableIdentifier &identifier);
647
 
  static const TableDefinitionCache &getCache();
648
 
  static TableShare *getShare(TableIdentifier &identifier);
649
 
  static TableShare *getShareCreate(Session *session, 
650
 
                                    TableIdentifier &identifier,
651
 
                                    int *error);
652
 
 
653
 
  friend std::ostream& operator<<(std::ostream& output, const TableShare &share)
654
 
  {
655
 
    output << "TableShare:(";
656
 
    output <<  share.getSchemaName();
657
 
    output << ", ";
658
 
    output << share.getTableName();
659
 
    output << ", ";
660
 
    output << share.getTableTypeAsString();
661
 
    output << ", ";
662
 
    output << share.getPath();
663
 
    output << ")";
664
 
 
665
 
    return output;  // for multiple << operators.
666
 
  }
667
 
 
668
 
  Field *make_field(unsigned char *ptr,
669
 
                    uint32_t field_length,
670
 
                    bool is_nullable,
671
 
                    unsigned char *null_pos,
672
 
                    unsigned char null_bit,
673
 
                    uint8_t decimals,
674
 
                    enum_field_types field_type,
675
 
                    const CHARSET_INFO * field_charset,
676
 
                    Field::utype unireg_check,
677
 
                    TYPELIB *interval,
678
 
                    const char *field_name);
679
 
 
680
 
  int open_table_def(Session& session, TableIdentifier &identifier);
681
 
 
682
 
  int open_table_from_share(Session *session,
683
 
                            const TableIdentifier &identifier,
684
 
                            const char *alias,
685
 
                            uint32_t db_stat, uint32_t ha_open_flags,
686
 
                            Table &outparam);
687
 
  int parse_table_proto(Session& session, message::Table &table);
688
 
private:
689
 
  int inner_parse_table_proto(Session& session, message::Table &table);
690
 
};
691
 
 
692
 
} /* namespace drizzled */
693
 
 
694
 
#endif /* DRIZZLED_TABLE_SHARE_H */