~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/plugin/info_schema_table.h

Blackhole, CSV, Pool of Threads,Single Thread, Multi Thread.

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
#ifndef DRIZZLED_PLUGIN_INFO_SCHEMA_TABLE_H
 
22
#define DRIZZLED_PLUGIN_INFO_SCHEMA_TABLE_H
 
23
 
 
24
#include "drizzled/hash/crc32.h"
 
25
 
 
26
#include <string>
 
27
#include <set>
 
28
#include <algorithm>
 
29
 
 
30
namespace drizzled
 
31
{
 
32
namespace plugin
 
33
{
 
34
 
 
35
/**
 
36
 * @file
 
37
 *   info_schema.h
 
38
 * @brief 
 
39
 *   Header file which contains all classes related to I_S
 
40
 */
 
41
 
 
42
typedef class Item COND;
 
43
 
 
44
 
 
45
/**
 
46
 * @class ColumnInfo
 
47
 * @brief
 
48
 *   Represents a field (column) in an I_S table.
 
49
 */
 
50
class ColumnInfo 
 
51
 
52
public: 
 
53
  ColumnInfo(const std::string& in_name, 
 
54
             uint32_t in_length, 
 
55
             enum enum_field_types in_type,
 
56
             int32_t in_value,
 
57
             uint32_t in_flags,
 
58
             const std::string& in_old_name)
 
59
    :
 
60
      name(in_name),
 
61
      length(in_length),
 
62
      type(in_type),
 
63
      value(in_value),
 
64
      flags(in_flags),
 
65
      old_name(in_old_name)
 
66
  {}
 
67
 
 
68
  ColumnInfo()
 
69
    :
 
70
      name(),
 
71
      length(0),
 
72
      type(DRIZZLE_TYPE_VARCHAR),
 
73
      flags(0),
 
74
      old_name()
 
75
  {}
 
76
 
 
77
  /**
 
78
   * @return the name of this column.
 
79
   */
 
80
  const std::string &getName() const
 
81
  {
 
82
    return name;
 
83
  }
 
84
 
 
85
  /**
 
86
   * This method is only ever called from the
 
87
   * InfoSchemaMethods::oldFormat() methods. It is mostly
 
88
   * for old SHOW compatability. It is used when a list
 
89
   * of fields need to be generated for SHOW. The names
 
90
   * for those fields (or columns) are found by calling
 
91
   * this method on each column in the I_S table.
 
92
   *
 
93
   * @return the old name of this column.
 
94
   */
 
95
  const std::string &getOldName() const
 
96
  {
 
97
    return old_name;
 
98
  }
 
99
 
 
100
  /**
 
101
   * @return the flags for this column.
 
102
   */
 
103
  uint32_t getFlags() const
 
104
  {
 
105
    return flags;
 
106
  }
 
107
 
 
108
  /**
 
109
   * @return the length of this column.
 
110
   */
 
111
  uint32_t getLength() const
 
112
  {
 
113
    return length;
 
114
  }
 
115
 
 
116
  /**
 
117
   * @return the value of this column.
 
118
   */
 
119
  int32_t getValue() const
 
120
  {
 
121
    return value;
 
122
  }
 
123
 
 
124
  /**
 
125
   * @return this column's type.
 
126
   */
 
127
  enum enum_field_types getType() const
 
128
  {
 
129
    return type;
 
130
  }
 
131
 
 
132
private:
 
133
 
 
134
  /**
 
135
   * This is used as column name.
 
136
   */
 
137
  const std::string name;
 
138
 
 
139
  /**
 
140
   * For string-type columns, this is the maximum number of
 
141
   * characters. Otherwise, it is the 'display-length' for the column.
 
142
   */
 
143
  uint32_t length;
 
144
 
 
145
  /**
 
146
   * This denotes data type for the column. For the most part, there seems to
 
147
   * be one entry in the enum for each SQL data type, although there seem to
 
148
   * be a number of additional entries in the enum.
 
149
   */
 
150
  enum enum_field_types type;
 
151
 
 
152
  int32_t value;
 
153
 
 
154
  /**
 
155
   * This is used to set column attributes. By default, columns are @c NOT
 
156
   * @c NULL and @c SIGNED, and you can deviate from the default
 
157
   * by setting the appopriate flags. You can use either one of the flags
 
158
   * @c MY_I_S_MAYBE_NULL and @cMY_I_S_UNSIGNED or
 
159
   * combine them using the bitwise or operator @c |. Both flags are
 
160
   * defined in table.h.
 
161
   */
 
162
  uint32_t flags;
 
163
 
 
164
  /**
 
165
   * The name of this column which is used for old SHOW
 
166
   * compatability.
 
167
   */
 
168
  const std::string old_name;
 
169
 
 
170
};
 
171
 
 
172
/**
 
173
 * @class InfoSchemaMethods
 
174
 * @brief
 
175
 *   The methods that an I_S table can support
 
176
 */
 
177
class InfoSchemaMethods
 
178
{
 
179
public:
 
180
  virtual ~InfoSchemaMethods() {}
 
181
 
 
182
  virtual int fillTable(Session *session, 
 
183
                        Table *table,
 
184
                        InfoSchemaTable *schema_table);
 
185
  virtual int processTable(InfoSchemaTable *store_table, 
 
186
                           Session *session, TableList *tables,
 
187
                           Table *table, bool res, LEX_STRING *db_name,
 
188
                           LEX_STRING *table_name);
 
189
  virtual int oldFormat(Session *session, 
 
190
                        InfoSchemaTable *schema_table) const;
 
191
};
 
192
 
 
193
/**
 
194
 * @class InfoSchemaRecord
 
195
 * @brief represents a row in an I_S table
 
196
 */
 
197
class InfoSchemaRecord
 
198
{
 
199
public:
 
200
  InfoSchemaRecord()
 
201
    :
 
202
      record(NULL),
 
203
      rec_len(0),
 
204
      checksum(0)
 
205
  {}
 
206
 
 
207
  InfoSchemaRecord(unsigned char *buf,
 
208
                   size_t in_len)
 
209
    :
 
210
      record(NULL),
 
211
      rec_len(in_len),
 
212
      checksum(0)
 
213
  {
 
214
    record= new unsigned char[rec_len];
 
215
    memcpy(record, buf, rec_len);
 
216
    checksum= drizzled::hash::crc32((const char *) record, rec_len);
 
217
  }
 
218
 
 
219
  InfoSchemaRecord(const InfoSchemaRecord &rhs)
 
220
    :
 
221
      record(NULL),
 
222
      rec_len(rhs.rec_len)
 
223
  {
 
224
    record= new(std::nothrow) unsigned char[rec_len];
 
225
    memcpy(record, rhs.record, rec_len);
 
226
    checksum= drizzled::hash::crc32((const char *) record, rec_len);
 
227
  }
 
228
 
 
229
  ~InfoSchemaRecord()
 
230
  {
 
231
    if (record)
 
232
    {
 
233
      delete [] record;
 
234
    }
 
235
  }
 
236
 
 
237
  /**
 
238
   * Copy this record into the memory passed to this function.
 
239
   *
 
240
   * @param[out] buf copy the record into this memory
 
241
   */
 
242
  void copyRecordInto(unsigned char *buf)
 
243
  {
 
244
    memcpy(buf, record, rec_len);
 
245
  }
 
246
 
 
247
  /**
 
248
   * @return the length of this record
 
249
   */
 
250
  size_t getRecordLength() const
 
251
  {
 
252
    return rec_len;
 
253
  }
 
254
 
 
255
  /**
 
256
   * @return the checksum of the data in this record
 
257
   */
 
258
  uint32_t getChecksum() const
 
259
  {
 
260
    return checksum;
 
261
  }
 
262
 
 
263
  /**
 
264
   * @param[in] crc a checksum to compare
 
265
   * @return true if the input checksum matches the checksum for this record; false otherwise
 
266
   */
 
267
  bool checksumMatches(uint32_t crc) const
 
268
  {
 
269
    return (checksum == crc);
 
270
  }
 
271
 
 
272
private:
 
273
 
 
274
  unsigned char *record;
 
275
 
 
276
  size_t rec_len;
 
277
 
 
278
  uint32_t checksum;
 
279
 
 
280
};
 
281
 
 
282
class DeleteRows
 
283
{
 
284
public:
 
285
  template<typename T>
 
286
  inline void operator()(const T *ptr) const
 
287
  {
 
288
    delete ptr;
 
289
  }
 
290
};
 
291
 
 
292
class FindRowByChecksum
 
293
{
 
294
  uint32_t cs;
 
295
public:
 
296
  FindRowByChecksum(uint32_t in_cs)
 
297
    :
 
298
      cs(in_cs)
 
299
  {}
 
300
 
 
301
  inline bool operator()(const InfoSchemaRecord *rec) const
 
302
  {
 
303
    return (cs == rec->getChecksum());
 
304
  }
 
305
};
 
306
 
 
307
/**
 
308
 * @class InfoSchemaTable
 
309
 * @brief 
 
310
 *   Represents an I_S table.
 
311
 */
 
312
class InfoSchemaTable : public Plugin
 
313
{
 
314
  InfoSchemaTable();
 
315
  InfoSchemaTable(const InfoSchemaTable &);
 
316
  InfoSchemaTable& operator=(const InfoSchemaTable &);
 
317
public:
 
318
 
 
319
  typedef std::vector<const ColumnInfo *> Columns;
 
320
  typedef std::vector<InfoSchemaRecord *> Rows;
 
321
  
 
322
  InfoSchemaTable(const std::string& tab_name,
 
323
                  Columns& in_column_info,
 
324
                  int idx_col1,
 
325
                  int idx_col2,
 
326
                  bool in_hidden,
 
327
                  bool in_opt_possible,
 
328
                  uint32_t req_object,
 
329
                  InfoSchemaMethods *in_methods)
 
330
    :
 
331
      Plugin(tab_name, "InfoSchemaTable"),
 
332
      hidden(in_hidden),
 
333
      is_opt_possible(in_opt_possible),
 
334
      first_column_index(idx_col1),
 
335
      second_column_index(idx_col2),
 
336
      requested_object(req_object),
 
337
      column_info(in_column_info),
 
338
      rows(),
 
339
      i_s_methods(in_methods)
 
340
  {}
 
341
 
 
342
  explicit InfoSchemaTable(const std::string& tab_name)
 
343
    :
 
344
      Plugin(tab_name, "InfoSchemaTable"),
 
345
      hidden(false),
 
346
      is_opt_possible(false),
 
347
      first_column_index(0),
 
348
      second_column_index(0),
 
349
      requested_object(0),
 
350
      column_info(),
 
351
      rows(),
 
352
      i_s_methods(NULL)
 
353
  {}
 
354
 
 
355
  virtual ~InfoSchemaTable()
 
356
  {
 
357
    std::for_each(rows.begin(),
 
358
                  rows.end(),
 
359
                  DeleteRows());
 
360
    rows.clear();
 
361
  }
 
362
 
 
363
  /**
 
364
   * Set the methods available on this I_S table.
 
365
   * @param[in] new_methods the methods to use
 
366
   */
 
367
  void setInfoSchemaMethods(InfoSchemaMethods *new_methods)
 
368
  {
 
369
    i_s_methods= new_methods;
 
370
  }
 
371
 
 
372
  /**
 
373
   * Fill I_S table.
 
374
   *
 
375
   * @param[in] session a session handler
 
376
   * @return 0 on success; 1 on error
 
377
   */
 
378
  int fillTable(Session *session, Table *table)
 
379
  {
 
380
    int retval= i_s_methods->fillTable(session, table, this);
 
381
    return retval;
 
382
  }
 
383
 
 
384
  /**
 
385
   * Fill and store records into an I_S table.
 
386
   *
 
387
   * @param[in] session a session handler
 
388
   * @param[in] tables table list (processed table)
 
389
   * @param[in] table I_S table
 
390
   * @param[in] res 1 means error during opening of the processed table
 
391
   *                0 means processed table opened without error
 
392
   * @param[in] db_name database name
 
393
   * @param[in] tab_name table name
 
394
   * @return 0 on success; 1 on error
 
395
   */
 
396
  int processTable(Session *session, TableList *tables, Table *table,
 
397
                   bool res, LEX_STRING *db_name, LEX_STRING *tab_name)
 
398
  {
 
399
    int retval= i_s_methods->processTable(this, session, tables, table,
 
400
                                          res, db_name, tab_name);
 
401
    return retval;
 
402
  }
 
403
 
 
404
  /**
 
405
   * For old SHOW compatibility. It is used when old SHOW doesn't
 
406
   * have generated column names. Generates the list of fields
 
407
   * for SHOW.
 
408
   *
 
409
   * @param[in] session a session handler
 
410
   * @param[in] schema_table pointer to element of the I_S tables list
 
411
   */
 
412
  int oldFormat(Session *session, InfoSchemaTable *schema_table) const
 
413
  {
 
414
    int retval= i_s_methods->oldFormat(session, schema_table);
 
415
    return retval;
 
416
  }
 
417
 
 
418
  /**
 
419
   * @param[in] new_first_index value to set first column index to
 
420
   */
 
421
  void setFirstColumnIndex(int32_t new_first_index)
 
422
  {
 
423
    first_column_index= new_first_index;
 
424
  }
 
425
 
 
426
  /**
 
427
   * @param[in] new_second_index value to set second column index to
 
428
   */
 
429
  void setSecondColumnIndex(int32_t new_second_index)
 
430
  {
 
431
    second_column_index= new_second_index;
 
432
  }
 
433
 
 
434
  /**
 
435
   * @param[in] in_column_info the columns info to use for this I_S table
 
436
   */
 
437
  void setColumnInfo(ColumnInfo *in_column_info)
 
438
  {
 
439
    ColumnInfo *tmp= in_column_info;
 
440
    for (; tmp->getName().length() != 0; tmp++)
 
441
    {
 
442
      column_info.push_back(tmp);
 
443
    }
 
444
  }
 
445
 
 
446
  /**
 
447
   * @return the name of the I_S table.
 
448
   */
 
449
  const std::string &getTableName() const
 
450
  {
 
451
    return getName();
 
452
  }
 
453
 
 
454
  /**
 
455
   * @return the names of the I_S tables.
 
456
   */
 
457
  static void getTableNames(std::set<std::string>& tables_names);
 
458
 
 
459
  /**
 
460
   * @return true if this I_S table is hidden; false otherwise.
 
461
   */
 
462
  bool isHidden() const
 
463
  {
 
464
    return hidden;
 
465
  }
 
466
 
 
467
  /**
 
468
   * @return true if I_S optimizations can be performed on this
 
469
   *         I_S table when running the fillTable method; false
 
470
   *         otherwise.
 
471
   */
 
472
  bool isOptimizationPossible() const
 
473
  {
 
474
    return is_opt_possible;
 
475
  }
 
476
 
 
477
  /**
 
478
   * @return the index for the first field.
 
479
   */
 
480
  int32_t getFirstColumnIndex() const
 
481
  {
 
482
    return first_column_index;
 
483
  }
 
484
 
 
485
  /**
 
486
   * @return the index the second field.
 
487
   */
 
488
  int32_t getSecondColumnIndex() const
 
489
  {
 
490
    return second_column_index;
 
491
  }
 
492
 
 
493
  /**
 
494
   * @return the requested object.
 
495
   */
 
496
  uint32_t getRequestedObject() const
 
497
  {
 
498
    return requested_object;
 
499
  }
 
500
 
 
501
  /**
 
502
   * @return the columns for this I_S table
 
503
   */
 
504
  const Columns &getColumns() const
 
505
  {
 
506
    return column_info;
 
507
  }
 
508
 
 
509
  /**
 
510
   * @return the rows for this I_S table.
 
511
   */
 
512
  Rows &getRows()
 
513
  {
 
514
    return rows;
 
515
  }
 
516
 
 
517
  /**
 
518
   * Clear the rows for this table and de-allocate all memory for this rows.
 
519
   */
 
520
  void clearRows()
 
521
  {
 
522
    std::for_each(rows.begin(),
 
523
                  rows.end(),
 
524
                  DeleteRows());
 
525
    rows.clear();
 
526
  }
 
527
 
 
528
  /**
 
529
   * Add a row to the std::vector of rows for this I_S table. For the moment, we check to make sure
 
530
   * that we do not add any duplicate rows. This is done in a niave manner for the moment by
 
531
   * checking the crc of the raw data for each row. We will not add this row to the std::vector of
 
532
   * rows for this I_S table is a duplicate row already exists in the std::vector.
 
533
   *
 
534
   * @param[in] buf raw data for the record to add
 
535
   * @param[in] len size of the raw data for the record to add
 
536
   */
 
537
  void addRow(unsigned char *buf, size_t len)
 
538
  {
 
539
    uint32_t cs= drizzled::hash::crc32((const char *) buf, len);
 
540
    Rows::iterator it= std::find_if(rows.begin(),
 
541
                                    rows.end(),
 
542
                                    FindRowByChecksum(cs));
 
543
    if (it == rows.end())
 
544
    {
 
545
      InfoSchemaRecord *record= new InfoSchemaRecord(buf, len);
 
546
      rows.push_back(record);
 
547
    }
 
548
  }
 
549
 
 
550
  /**
 
551
   * @param[in] index the index of this column
 
552
   * @return the name for the column at the given index
 
553
   */
 
554
  const std::string &getColumnName(int index) const
 
555
  {
 
556
    return column_info[index]->getName();
 
557
  }
 
558
 
 
559
private:
 
560
 
 
561
  /**
 
562
   * Boolean which indicates whether this I_S table
 
563
   * is hidden or not. If it is hidden, it will not show
 
564
   * up in the list of I_S tables.
 
565
   */
 
566
  bool hidden;
 
567
 
 
568
  /**
 
569
   * Boolean which indicates whether optimizations are
 
570
   * possible on this I_S table when performing the
 
571
   * fillTable method.
 
572
   */
 
573
  bool is_opt_possible;
 
574
 
 
575
  /**
 
576
   * The index of the first column.
 
577
   */
 
578
  int32_t first_column_index;
 
579
 
 
580
  /**
 
581
   * The index of the second column.
 
582
   */
 
583
  int32_t second_column_index;
 
584
 
 
585
  /**
 
586
   * The object to open (TABLE | VIEW).
 
587
   */
 
588
  uint32_t requested_object;
 
589
 
 
590
  /**
 
591
   * The columns for this I_S table.
 
592
   */
 
593
  Columns column_info;
 
594
 
 
595
  /**
 
596
   * The rows for this I_S table.
 
597
   */
 
598
  Rows rows;
 
599
 
 
600
  /**
 
601
   * Contains the methods available on this I_S table.
 
602
   */
 
603
  InfoSchemaMethods *i_s_methods;
 
604
 
 
605
public:
 
606
  static bool addPlugin(plugin::InfoSchemaTable *schema_table);
 
607
  static void removePlugin(plugin::InfoSchemaTable *table);
 
608
 
 
609
  static plugin::InfoSchemaTable *getTable(const char *table_name);
 
610
  static int addTableToList(Session *session, std::vector<LEX_STRING*> &files,
 
611
                            const char *wild);
 
612
};
 
613
 
 
614
} /* namespace plugin */
 
615
} /* namespace drizzled */
 
616
 
 
617
#endif /* DRIZZLED_PLUGIN_INFO_SCHEMA_TABLE_H */