~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/information_engine/information_engine.cc

  • Committer: Brian Aker
  • Date: 2010-02-19 23:07:45 UTC
  • mto: (1273.13.97 build)
  • mto: This revision was merged to the branch mainline in revision 1309.
  • Revision ID: brian@gaz-20100219230745-cmurfbxj845it9z7
This remove the original info_schema system for the server. More still to
cut, but we are on our way.

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
 
#include "config.h"
22
 
 
23
 
#include <plugin/information_engine/information_engine.h>
24
 
#include <drizzled/session.h>
25
 
 
26
 
#include <plugin/information_engine/information_cursor.h>
27
 
 
28
 
#include <string>
29
 
 
30
 
using namespace std;
31
 
using namespace drizzled;
32
 
 
33
 
static const string engine_name("INFORMATION_ENGINE");
34
 
 
35
 
 
36
 
Cursor *InformationEngine::create(TableShare &table, memory::Root *mem_root)
37
 
{
38
 
  return new (mem_root) InformationCursor(*this, table);
39
 
}
40
 
 
41
 
 
42
 
int InformationEngine::doGetTableDefinition(Session &,
43
 
                                            const char *path,
44
 
                                            const char *,
45
 
                                            const char *,
46
 
                                            const bool,
47
 
                                            message::Table *table_proto)
48
 
{
49
 
  string tab_name(path);
50
 
  string i_s_prefix("./information_schema/");
51
 
  if (tab_name.compare(0, i_s_prefix.length(), i_s_prefix) != 0)
52
 
  {
53
 
    return ENOENT;
54
 
  }
55
 
 
56
 
  if (! table_proto)
57
 
  {
58
 
    return EEXIST;
59
 
  }
60
 
 
61
 
  tab_name.erase(0, i_s_prefix.length());
62
 
  plugin::InfoSchemaTable *schema_table= plugin::InfoSchemaTable::getTable(tab_name.c_str());
63
 
 
64
 
  if (! schema_table)
65
 
  {
66
 
    return ENOENT;
67
 
  }
68
 
 
69
 
  table_proto->set_name(tab_name);
70
 
  table_proto->set_type(message::Table::STANDARD);
71
 
 
72
 
  message::Table::StorageEngine *protoengine= table_proto->mutable_engine();
73
 
  protoengine->set_name(engine_name);
74
 
 
75
 
  message::Table::TableOptions *table_options= table_proto->mutable_options();
76
 
  table_options->set_collation_id(default_charset_info->number);
77
 
  table_options->set_collation(default_charset_info->name);
78
 
 
79
 
  const plugin::InfoSchemaTable::Columns &columns= schema_table->getColumns();
80
 
  plugin::InfoSchemaTable::Columns::const_iterator iter= columns.begin();
81
 
 
82
 
  while (iter != columns.end())
83
 
  {
84
 
    const plugin::ColumnInfo *column= *iter;
85
 
    /* get the various proto variables we need */
86
 
    message::Table::Field *proto_field= table_proto->add_field();
87
 
    message::Table::Field::FieldOptions *field_options=
88
 
      proto_field->mutable_options();
89
 
    message::Table::Field::FieldConstraints *field_constraints=
90
 
      proto_field->mutable_constraints();
91
 
 
92
 
    proto_field->set_name(column->getName());
93
 
    field_options->set_default_value("0");
94
 
 
95
 
    if (column->getFlags() & MY_I_S_MAYBE_NULL)
96
 
    {
97
 
      field_options->set_default_null(true);
98
 
      field_constraints->set_is_nullable(true);
99
 
    }
100
 
    else
101
 
    {
102
 
      field_options->set_default_null(false);
103
 
      field_constraints->set_is_nullable(false);
104
 
    }
105
 
 
106
 
    if (column->getFlags() & MY_I_S_UNSIGNED)
107
 
    {
108
 
      field_constraints->set_is_unsigned(true);
109
 
    }
110
 
 
111
 
    switch(column->getType())
112
 
    {
113
 
    case DRIZZLE_TYPE_LONG:
114
 
      proto_field->set_type(message::Table::Field::INTEGER);
115
 
      break;
116
 
    case DRIZZLE_TYPE_DOUBLE:
117
 
      proto_field->set_type(message::Table::Field::DOUBLE);
118
 
      break;
119
 
    case DRIZZLE_TYPE_NULL:
120
 
      assert(true);
121
 
      break;
122
 
    case DRIZZLE_TYPE_TIMESTAMP:
123
 
      proto_field->set_type(message::Table::Field::TIMESTAMP);
124
 
      field_options->set_default_value("NOW()");
125
 
      break;
126
 
    case DRIZZLE_TYPE_LONGLONG:
127
 
      proto_field->set_type(message::Table::Field::BIGINT);
128
 
      break;
129
 
    case DRIZZLE_TYPE_DATETIME:
130
 
      proto_field->set_type(message::Table::Field::DATETIME);
131
 
      field_options->set_default_value("NOW()");
132
 
      break;
133
 
    case DRIZZLE_TYPE_DATE:
134
 
      proto_field->set_type(message::Table::Field::DATE);
135
 
      field_options->set_default_value("NOW()");
136
 
      break;
137
 
    case DRIZZLE_TYPE_VARCHAR:
138
 
    {
139
 
      message::Table::Field::StringFieldOptions *str_field_options=
140
 
        proto_field->mutable_string_options();
141
 
      proto_field->set_type(message::Table::Field::VARCHAR);
142
 
      str_field_options->set_length(column->getLength());
143
 
      field_options->set_default_value("");
144
 
      str_field_options->set_collation_id(default_charset_info->number);
145
 
      str_field_options->set_collation(default_charset_info->name);
146
 
      break;
147
 
    }
148
 
    case DRIZZLE_TYPE_DECIMAL:
149
 
    {
150
 
      message::Table::Field::NumericFieldOptions *num_field_options=
151
 
        proto_field->mutable_numeric_options();
152
 
      proto_field->set_type(message::Table::Field::DECIMAL);
153
 
      num_field_options->set_precision(column->getLength());
154
 
      num_field_options->set_scale(column->getLength() % 10);
155
 
      break;
156
 
    }
157
 
    default:
158
 
      assert(true);
159
 
      break;
160
 
    }
161
 
 
162
 
    ++iter;
163
 
  }
164
 
 
165
 
  return EEXIST;
166
 
}
167
 
 
168
 
 
169
 
void InformationEngine::doGetTableNames(drizzled::CachedDirectory&, 
170
 
                                        string &db, 
171
 
                                        set<string> &set_of_names)
172
 
{
173
 
  if (db.compare("information_schema"))
174
 
    return;
175
 
 
176
 
  plugin::InfoSchemaTable::getTableNames(set_of_names);
177
 
}
178
 
 
179
 
InformationEngine::Share *InformationEngine::getShare(const string &name_arg)
180
 
{
181
 
  InformationEngine::Share *share= NULL;
182
 
  pthread_mutex_lock(&mutex);
183
 
 
184
 
  OpenTables::iterator it= open_tables.find(name_arg);
185
 
 
186
 
  if (it != open_tables.end())
187
 
  {
188
 
    share= &((*it).second);
189
 
    share->incUseCount();
190
 
  }
191
 
  else
192
 
  {
193
 
    pair<OpenTables::iterator, bool> returned;
194
 
 
195
 
    returned=
196
 
      open_tables.insert(Record(name_arg, InformationEngine::Share(name_arg)));
197
 
 
198
 
    if (returned.second == false)
199
 
    {
200
 
      pthread_mutex_unlock(&mutex);
201
 
      return NULL;
202
 
    }
203
 
 
204
 
    Record &value= *(returned.first);
205
 
    share= &(value.second);
206
 
    share->setInfoSchemaTable(name_arg);
207
 
    share->initThreadLock();
208
 
  }
209
 
 
210
 
 
211
 
  pthread_mutex_unlock(&mutex);
212
 
 
213
 
  return share;
214
 
}
215
 
 
216
 
 
217
 
void InformationEngine::freeShare(InformationEngine::Share *share)
218
 
{
219
 
  pthread_mutex_lock(&mutex);
220
 
 
221
 
  share->decUseCount();
222
 
 
223
 
  if (share->getUseCount() == 0)
224
 
  {
225
 
    open_tables.erase(share->getName());
226
 
    share->deinitThreadLock();
227
 
  }
228
 
 
229
 
  pthread_mutex_unlock(&mutex);
230
 
}
231
 
 
232
 
 
233
 
static plugin::StorageEngine *information_engine= NULL;
234
 
 
235
 
static int init(plugin::Registry &registry)
236
 
{
237
 
  information_engine= new(std::nothrow) InformationEngine(engine_name);
238
 
  if (! information_engine)
239
 
  {
240
 
    return 1;
241
 
  }
242
 
 
243
 
  registry.add(information_engine);
244
 
  
245
 
  return 0;
246
 
}
247
 
 
248
 
static int finalize(plugin::Registry &registry)
249
 
{
250
 
  registry.remove(information_engine);
251
 
  delete information_engine;
252
 
 
253
 
  return 0;
254
 
}
255
 
 
256
 
DRIZZLE_DECLARE_PLUGIN
257
 
{
258
 
  DRIZZLE_VERSION_ID,
259
 
  "INFORMATION_ENGINE",
260
 
  "1.0",
261
 
  "Padraig O'Sullivan, Brian Aker",
262
 
  "Engine which provides information schema tables",
263
 
  PLUGIN_LICENSE_GPL,
264
 
  init,     /* Plugin Init */
265
 
  finalize,     /* Plugin Deinit */
266
 
  NULL,               /* system variables */
267
 
  NULL                /* config options   */
268
 
}
269
 
DRIZZLE_DECLARE_PLUGIN_END;