~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/info_schema/schemata.cc

  • Committer: Brian Aker
  • Date: 2009-12-29 01:38:38 UTC
  • mfrom: (1251.1.1 drizzle)
  • Revision ID: brian@gaz-20091229013838-03kb2z5xbqw03ddt
Merge of Diego fix.

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
 * @file 
 
23
 *   schemata I_S table methods.
 
24
 */
 
25
 
 
26
#include "config.h"
 
27
#include "drizzled/session.h"
 
28
#include "drizzled/show.h"
 
29
#include "drizzled/join_table.h"
 
30
#include "drizzled/sql_table.h"
 
31
#include "drizzled/db.h"
 
32
#include "helper_methods.h"
 
33
#include "schemata.h"
 
34
 
 
35
#ifdef HAVE_SYS_STAT_H
 
36
# include <sys/stat.h>
 
37
#endif
 
38
 
 
39
#include <vector>
 
40
 
 
41
using namespace drizzled;
 
42
using namespace std;
 
43
 
 
44
/*
 
45
 * Vectors of columns for the schemata I_S table.
 
46
 */
 
47
static vector<const plugin::ColumnInfo *> *columns= NULL;
 
48
 
 
49
/*
 
50
 * Methods for the schemata I_S table.
 
51
 */
 
52
static plugin::InfoSchemaMethods *methods= NULL;
 
53
 
 
54
/*
 
55
 * schemata I_S table.
 
56
 */
 
57
static plugin::InfoSchemaTable *sch_table= NULL;
 
58
 
 
59
/**
 
60
 * Populate the vectors of columns for the I_S table.
 
61
 *
 
62
 * @return a pointer to a std::vector of Columns.
 
63
 */
 
64
vector<const plugin::ColumnInfo *> *SchemataIS::createColumns()
 
65
{
 
66
  if (columns == NULL)
 
67
  {
 
68
    columns= new vector<const plugin::ColumnInfo *>;
 
69
  }
 
70
  else
 
71
  {
 
72
    clearColumns(*columns);
 
73
  }
 
74
 
 
75
  columns->push_back(new plugin::ColumnInfo("CATALOG_NAME",
 
76
                                            FN_REFLEN,
 
77
                                            DRIZZLE_TYPE_VARCHAR,
 
78
                                            0, 
 
79
                                            1, 
 
80
                                            ""));
 
81
 
 
82
  columns->push_back(new plugin::ColumnInfo("SCHEMA_NAME",
 
83
                                            NAME_CHAR_LEN,
 
84
                                            DRIZZLE_TYPE_VARCHAR,
 
85
                                            0, 
 
86
                                            0, 
 
87
                                            "Database"));
 
88
 
 
89
  columns->push_back(new plugin::ColumnInfo("DEFAULT_CHARACTER_SET_NAME",
 
90
                                            64, 
 
91
                                            DRIZZLE_TYPE_VARCHAR, 
 
92
                                            0, 
 
93
                                            0, 
 
94
                                            ""));
 
95
 
 
96
  columns->push_back(new plugin::ColumnInfo("DEFAULT_COLLATION_NAME",
 
97
                                            64, 
 
98
                                            DRIZZLE_TYPE_VARCHAR, 
 
99
                                            0, 
 
100
                                            0, 
 
101
                                            ""));
 
102
 
 
103
  columns->push_back(new plugin::ColumnInfo("SQL_PATH",
 
104
                                            FN_REFLEN,
 
105
                                            DRIZZLE_TYPE_VARCHAR,
 
106
                                            0, 
 
107
                                            1, 
 
108
                                            ""));
 
109
 
 
110
  return columns;
 
111
}
 
112
 
 
113
/**
 
114
 * Initialize the I_S table.
 
115
 *
 
116
 * @return a pointer to an I_S table
 
117
 */
 
118
plugin::InfoSchemaTable *SchemataIS::getTable()
 
119
{
 
120
  columns= createColumns();
 
121
 
 
122
  if (methods == NULL)
 
123
  {
 
124
    methods= new SchemataISMethods();
 
125
  }
 
126
 
 
127
  if (sch_table == NULL)
 
128
  {
 
129
    sch_table= new plugin::InfoSchemaTable("SCHEMATA",
 
130
                                           *columns,
 
131
                                           1, -1, false, false, 0,
 
132
                                           methods);
 
133
  }
 
134
 
 
135
  return sch_table;
 
136
}
 
137
 
 
138
/**
 
139
 * Delete memory allocated for the table, columns and methods.
 
140
 */
 
141
void SchemataIS::cleanup()
 
142
{
 
143
  clearColumns(*columns);
 
144
  delete sch_table;
 
145
  delete methods;
 
146
  delete columns;
 
147
}
 
148
 
 
149
static bool store_schema_schemata(Session *, 
 
150
                                  Table *table, 
 
151
                                  LEX_STRING *db_name,
 
152
                                  const CHARSET_INFO * const cs,
 
153
                                  plugin::InfoSchemaTable *schema_table)
 
154
{
 
155
  table->restoreRecordAsDefault();
 
156
  table->setWriteSet(1);
 
157
  table->setWriteSet(2);
 
158
  table->setWriteSet(3);
 
159
  table->field[1]->store(db_name->str, db_name->length, system_charset_info);
 
160
  table->field[2]->store(cs->csname, strlen(cs->csname), system_charset_info);
 
161
  table->field[3]->store(cs->name, strlen(cs->name), system_charset_info);
 
162
  schema_table->addRow(table->record[0], table->s->reclength);
 
163
  return false;
 
164
}
 
165
 
 
166
int SchemataISMethods::fillTable(Session *session, 
 
167
                                 Table *table,
 
168
                                 plugin::InfoSchemaTable *schema_table)
 
169
{
 
170
  /*
 
171
    TODO: fill_schema_shemata() is called when new client is connected.
 
172
    Returning error status in this case leads to client hangup.
 
173
  */
 
174
 
 
175
  LOOKUP_FIELD_VALUES lookup_field_vals;
 
176
  vector<LEX_STRING*> db_names;
 
177
  bool with_i_schema;
 
178
  /* the WHERE condition */
 
179
  COND *cond= table->reginfo.join_tab->select_cond;
 
180
 
 
181
  if (get_lookup_field_values(session, 
 
182
                              cond, 
 
183
                              table->pos_in_table_list, 
 
184
                              &lookup_field_vals,
 
185
                              schema_table))
 
186
  {
 
187
    return 0;
 
188
  }
 
189
 
 
190
  if (make_db_list(session, 
 
191
                   db_names, 
 
192
                   &lookup_field_vals,
 
193
                   &with_i_schema))
 
194
  {
 
195
    return 1;
 
196
  }
 
197
 
 
198
  /*
 
199
    If we have lookup db value we should check that the database exists
 
200
  */
 
201
  if (lookup_field_vals.db_value.str && 
 
202
      ! lookup_field_vals.wild_db_value &&
 
203
      ! with_i_schema)
 
204
  {
 
205
    char path[FN_REFLEN+16];
 
206
    uint32_t path_len;
 
207
    struct stat stat_info;
 
208
    if (! lookup_field_vals.db_value.str[0])
 
209
    {
 
210
      return 0;
 
211
    }
 
212
 
 
213
    path_len= build_table_filename(path, 
 
214
                                   sizeof(path),
 
215
                                   lookup_field_vals.db_value.str, 
 
216
                                   "", 
 
217
                                   false);
 
218
    path[path_len-1]= 0;
 
219
    if (stat(path,&stat_info))
 
220
    {
 
221
      return 0;
 
222
    }
 
223
  }
 
224
 
 
225
  vector<LEX_STRING*>::iterator db_name= db_names.begin();
 
226
  while (db_name != db_names.end())
 
227
  {
 
228
    if (with_i_schema)       // information schema name is always first in list
 
229
    {
 
230
      if (store_schema_schemata(session, table, *db_name, system_charset_info, schema_table))
 
231
      {
 
232
        return 1;
 
233
      }
 
234
      with_i_schema= 0;
 
235
    }
 
236
    else
 
237
    {
 
238
      const CHARSET_INFO *cs= get_default_db_collation((*db_name)->str);
 
239
 
 
240
      if (store_schema_schemata(session, table, *db_name, cs, schema_table))
 
241
      {
 
242
        return 1;
 
243
      }
 
244
    }
 
245
    ++db_name;
 
246
  }
 
247
  return 0;
 
248
}
 
249
 
 
250
int SchemataISMethods::oldFormat(Session *session, drizzled::plugin::InfoSchemaTable *schema_table)
 
251
  const
 
252
{
 
253
  char tmp[128];
 
254
  LEX *lex= session->lex;
 
255
  Select_Lex *sel= lex->current_select;
 
256
  Name_resolution_context *context= &sel->context;
 
257
  const drizzled::plugin::InfoSchemaTable::Columns sch_columns= schema_table->getColumns();
 
258
 
 
259
  if (! sel->item_list.elements)
 
260
  {
 
261
    const drizzled::plugin::ColumnInfo *column= sch_columns[1];
 
262
    String buffer(tmp,sizeof(tmp), system_charset_info);
 
263
    Item_field *field= new Item_field(context,
 
264
                                      NULL, 
 
265
                                      NULL, 
 
266
                                      column->getName().c_str());
 
267
    if (! field || session->add_item_to_list(field))
 
268
    {
 
269
      return 1;
 
270
    }
 
271
    buffer.length(0);
 
272
    buffer.append(column->getOldName().c_str());
 
273
    if (lex->wild && lex->wild->ptr())
 
274
    {
 
275
      buffer.append(STRING_WITH_LEN(" ("));
 
276
      buffer.append(lex->wild->ptr());
 
277
      buffer.append(')');
 
278
    }
 
279
    field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
 
280
  }
 
281
  return 0;
 
282
}
 
283