~drizzle-trunk/drizzle/development

1273.20.1 by Brian Aker
Basic engine with test.
1
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 *
4
 *  Copyright (C) 2010 Brian Aker
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
1273.20.2 by Brian Aker
Adding on more bits for schema engine.
23
#include "plugin/schema_engine/schema.h"
24
#include "drizzled/db.h"
1273.19.20 by Brian Aker
Remove meta data call from db.cc
25
#include "drizzled/sql_table.h"
1309.1.2 by Brian Aker
Move IO for default DFE out of SE (more of).
26
#include "drizzled/global_charset_info.h"
27
#include "drizzled/charset.h"
28
#include "drizzled/charset_info.h"
29
#include "drizzled/cursor.h"
1786.3.1 by Monty Taylor
Initial working local catalog.
30
#include "drizzled/data_home.h"
1273.20.1 by Brian Aker
Basic engine with test.
31
1309.1.30 by Brian Aker
Simplify dropTable() (will add exceptions right now)
32
#include "drizzled/internal/my_sys.h"
33
1309.1.1 by Brian Aker
This removes the special case read of proto from SE interface, down to
34
#include <fcntl.h>
1273.19.25 by Brian Aker
createSchema() now works via SE interface.
35
#include <sys/stat.h>
36
#include <sys/types.h>
37
1309.1.1 by Brian Aker
This removes the special case read of proto from SE interface, down to
38
#include <google/protobuf/io/zero_copy_stream.h>
39
#include <google/protobuf/io/zero_copy_stream_impl.h>
40
1273.19.20 by Brian Aker
Remove meta data call from db.cc
41
#include <iostream>
42
#include <fstream>
1273.20.1 by Brian Aker
Basic engine with test.
43
#include <string>
44
45
using namespace std;
46
using namespace drizzled;
47
1415 by Brian Aker
Mass overhaul to use schema_identifier.
48
1273.19.31 by Brian Aker
Fix dropSchema().
49
#define MY_DB_OPT_FILE "db.opt"
1309.1.2 by Brian Aker
Move IO for default DFE out of SE (more of).
50
#define DEFAULT_FILE_EXTENSION ".dfe" // Deep Fried Elephant
1273.19.31 by Brian Aker
Fix dropSchema().
51
1273.20.1 by Brian Aker
Basic engine with test.
52
Schema::Schema():
53
  drizzled::plugin::StorageEngine("schema",
54
                                  HTON_ALTER_NOT_SUPPORTED |
1273.19.30 by Brian Aker
Performance patch... we now only cycle through engines that actually have
55
                                  HTON_HAS_SCHEMA_DICTIONARY |
1273.20.1 by Brian Aker
Basic engine with test.
56
                                  HTON_SKIP_STORE_LOCK |
1309.1.3 by Brian Aker
Cache for Schema.
57
                                  HTON_TEMPORARY_NOT_SUPPORTED),
58
  schema_cache_filled(false)
59
{
60
  table_definition_ext= DEFAULT_FILE_EXTENSION;
61
}
62
63
Schema::~Schema()
64
{
1273.20.1 by Brian Aker
Basic engine with test.
65
}
66
1309.1.3 by Brian Aker
Cache for Schema.
67
void Schema::prime()
68
{
1813.2.9 by Monty Taylor
Made data_home be fs::path natively.
69
  CachedDirectory directory(getDataHomeCatalog().file_string(), CachedDirectory::DIRECTORY);
1309.1.3 by Brian Aker
Cache for Schema.
70
  CachedDirectory::Entries files= directory.getEntries();
71
1755.2.6 by Brian Aker
Remove usage of non-boost lock type.
72
  mutex.lock();
1309.1.3 by Brian Aker
Cache for Schema.
73
74
  for (CachedDirectory::Entries::iterator fileIter= files.begin();
75
       fileIter != files.end(); fileIter++)
76
  {
77
    CachedDirectory::Entry *entry= *fileIter;
78
    message::Schema schema_message;
79
1556.1.2 by Brian Aker
Creates a "cleanup" of Innodb's temp files in case of a crash of the DB.
80
    if (not entry->filename.compare(GLOBAL_TEMPORARY_EXT))
81
      continue;
82
1749.3.14 by Brian Aker
Update to use the identifier (and not the straight filename).
83
    SchemaIdentifier filename(entry->filename);
84
    if (readSchemaFile(filename, schema_message))
1309.1.3 by Brian Aker
Cache for Schema.
85
    {
1415 by Brian Aker
Mass overhaul to use schema_identifier.
86
      SchemaIdentifier schema_identifier(schema_message.name());
87
1309.1.3 by Brian Aker
Cache for Schema.
88
      pair<SchemaCache::iterator, bool> ret=
1812.3.8 by Brian Aker
This switches our schema system over to using a shared ptr. Lets see how
89
        schema_cache.insert(make_pair(schema_identifier.getPath(), new message::Schema(schema_message)));
1309.1.3 by Brian Aker
Cache for Schema.
90
91
      if (ret.second == false)
1415 by Brian Aker
Mass overhaul to use schema_identifier.
92
     {
1309.1.3 by Brian Aker
Cache for Schema.
93
        abort(); // If this has happened, something really bad is going down.
94
      }
95
    }
96
  }
1755.2.6 by Brian Aker
Remove usage of non-boost lock type.
97
  mutex.unlock();
1309.1.3 by Brian Aker
Cache for Schema.
98
}
99
1966.2.3 by Brian Aker
Fix another style issue.
100
void Schema::doGetSchemaIdentifiers(SchemaIdentifier::vector &set_of_names)
1273.20.1 by Brian Aker
Basic engine with test.
101
{
1755.2.6 by Brian Aker
Remove usage of non-boost lock type.
102
  mutex.lock_shared();
1309.1.3 by Brian Aker
Cache for Schema.
103
  {
104
    for (SchemaCache::iterator iter= schema_cache.begin();
105
         iter != schema_cache.end();
106
         iter++)
107
    {
1812.3.8 by Brian Aker
This switches our schema system over to using a shared ptr. Lets see how
108
      set_of_names.push_back(SchemaIdentifier((*iter).second->name()));
1309.1.3 by Brian Aker
Cache for Schema.
109
    }
1755.2.6 by Brian Aker
Remove usage of non-boost lock type.
110
  }
111
  mutex.unlock_shared();
1273.20.1 by Brian Aker
Basic engine with test.
112
}
1273.20.2 by Brian Aker
Adding on more bits for schema engine.
113
1966.2.1 by Brian Aker
Clean up style for shared_ptr for messages around table/schema.
114
bool Schema::doGetSchemaDefinition(const SchemaIdentifier &schema_identifier, message::schema::shared_ptr &schema_message)
1273.20.2 by Brian Aker
Adding on more bits for schema engine.
115
{
1755.2.6 by Brian Aker
Remove usage of non-boost lock type.
116
  mutex.lock_shared();
117
  SchemaCache::iterator iter= schema_cache.find(schema_identifier.getPath());
118
119
  if (iter != schema_cache.end())
1273.19.20 by Brian Aker
Remove meta data call from db.cc
120
  {
1812.3.8 by Brian Aker
This switches our schema system over to using a shared ptr. Lets see how
121
    schema_message= (*iter).second;
1755.2.6 by Brian Aker
Remove usage of non-boost lock type.
122
    mutex.unlock_shared();
123
    return true;
1309.1.3 by Brian Aker
Cache for Schema.
124
  }
1755.2.6 by Brian Aker
Remove usage of non-boost lock type.
125
  mutex.unlock_shared();
1309.1.3 by Brian Aker
Cache for Schema.
126
1755.2.6 by Brian Aker
Remove usage of non-boost lock type.
127
  return false;
1273.20.2 by Brian Aker
Adding on more bits for schema engine.
128
}
1273.19.25 by Brian Aker
createSchema() now works via SE interface.
129
1755.2.6 by Brian Aker
Remove usage of non-boost lock type.
130
1856.2.8 by Joseph Daly
working alter, drop, create schema
131
bool Schema::doCreateSchema(const drizzled::message::Schema &schema_message)
1273.19.25 by Brian Aker
createSchema() now works via SE interface.
132
{
1415 by Brian Aker
Mass overhaul to use schema_identifier.
133
  SchemaIdentifier schema_identifier(schema_message.name());
134
135
  if (mkdir(schema_identifier.getPath().c_str(), 0777) == -1)
1273.19.25 by Brian Aker
createSchema() now works via SE interface.
136
    return false;
137
1415 by Brian Aker
Mass overhaul to use schema_identifier.
138
  if (not writeSchemaFile(schema_identifier, schema_message))
1273.19.25 by Brian Aker
createSchema() now works via SE interface.
139
  {
1415 by Brian Aker
Mass overhaul to use schema_identifier.
140
    rmdir(schema_identifier.getPath().c_str());
1273.19.25 by Brian Aker
createSchema() now works via SE interface.
141
142
    return false;
143
  }
144
1755.2.6 by Brian Aker
Remove usage of non-boost lock type.
145
  mutex.lock();
1309.1.3 by Brian Aker
Cache for Schema.
146
  {
1755.2.6 by Brian Aker
Remove usage of non-boost lock type.
147
    pair<SchemaCache::iterator, bool> ret=
1812.3.8 by Brian Aker
This switches our schema system over to using a shared ptr. Lets see how
148
      schema_cache.insert(make_pair(schema_identifier.getPath(), new message::Schema(schema_message)));
1755.2.6 by Brian Aker
Remove usage of non-boost lock type.
149
150
151
    if (ret.second == false)
152
    {
153
      abort(); // If this has happened, something really bad is going down.
154
    }
1309.1.3 by Brian Aker
Cache for Schema.
155
  }
1755.2.6 by Brian Aker
Remove usage of non-boost lock type.
156
  mutex.unlock();
1309.1.3 by Brian Aker
Cache for Schema.
157
1273.19.25 by Brian Aker
createSchema() now works via SE interface.
158
  return true;
159
}
1273.19.26 by Brian Aker
Move Alter schema to SE interface.
160
1642 by Brian Aker
This adds const to SchemaIdentifier.
161
bool Schema::doDropSchema(const SchemaIdentifier &schema_identifier)
1273.19.31 by Brian Aker
Fix dropSchema().
162
{
1966.2.1 by Brian Aker
Clean up style for shared_ptr for messages around table/schema.
163
  message::schema::shared_ptr schema_message;
1273.19.31 by Brian Aker
Fix dropSchema().
164
1415 by Brian Aker
Mass overhaul to use schema_identifier.
165
  string schema_file(schema_identifier.getPath());
1273.19.31 by Brian Aker
Fix dropSchema().
166
  schema_file.append(1, FN_LIBCHAR);
167
  schema_file.append(MY_DB_OPT_FILE);
168
1415 by Brian Aker
Mass overhaul to use schema_identifier.
169
  if (not doGetSchemaDefinition(schema_identifier, schema_message))
1273.19.31 by Brian Aker
Fix dropSchema().
170
    return false;
171
172
  // No db.opt file, no love from us.
173
  if (access(schema_file.c_str(), F_OK))
174
  {
175
    perror(schema_file.c_str());
176
    return false;
177
  }
178
179
  if (unlink(schema_file.c_str()))
1387 by Brian Aker
Fix for cases where not all files are removed during a deletion of a schema.
180
  {
1273.19.31 by Brian Aker
Fix dropSchema().
181
    perror(schema_file.c_str());
1387 by Brian Aker
Fix for cases where not all files are removed during a deletion of a schema.
182
    return false;
183
  }
1273.19.31 by Brian Aker
Fix dropSchema().
184
1415 by Brian Aker
Mass overhaul to use schema_identifier.
185
  if (rmdir(schema_identifier.getPath().c_str()))
1387 by Brian Aker
Fix for cases where not all files are removed during a deletion of a schema.
186
  {
1415 by Brian Aker
Mass overhaul to use schema_identifier.
187
    perror(schema_identifier.getPath().c_str());
188
    //@todo If this happens, we want a report of it. For the moment I dump
189
    //to stderr so I can catch it in Hudson.
190
    CachedDirectory dir(schema_identifier.getPath());
1387 by Brian Aker
Fix for cases where not all files are removed during a deletion of a schema.
191
    cerr << dir;
192
  }
1273.19.31 by Brian Aker
Fix dropSchema().
193
1755.2.6 by Brian Aker
Remove usage of non-boost lock type.
194
  mutex.lock();
195
  schema_cache.erase(schema_identifier.getPath());
196
  mutex.unlock();
1309.1.3 by Brian Aker
Cache for Schema.
197
1273.19.31 by Brian Aker
Fix dropSchema().
198
  return true;
199
}
200
1273.19.26 by Brian Aker
Move Alter schema to SE interface.
201
bool Schema::doAlterSchema(const drizzled::message::Schema &schema_message)
202
{
1415 by Brian Aker
Mass overhaul to use schema_identifier.
203
  SchemaIdentifier schema_identifier(schema_message.name());
1273.19.26 by Brian Aker
Move Alter schema to SE interface.
204
1415 by Brian Aker
Mass overhaul to use schema_identifier.
205
  if (access(schema_identifier.getPath().c_str(), F_OK))
1273.19.28 by Brian Aker
More cleanup on ALTER SCHEMA. Hey! MySQL never had errors on half of it...
206
    return false;
207
1415 by Brian Aker
Mass overhaul to use schema_identifier.
208
  if (writeSchemaFile(schema_identifier, schema_message))
1273.19.26 by Brian Aker
Move Alter schema to SE interface.
209
  {
1755.2.6 by Brian Aker
Remove usage of non-boost lock type.
210
    mutex.lock();
1309.1.3 by Brian Aker
Cache for Schema.
211
    {
1415 by Brian Aker
Mass overhaul to use schema_identifier.
212
      schema_cache.erase(schema_identifier.getPath());
1309.1.3 by Brian Aker
Cache for Schema.
213
214
      pair<SchemaCache::iterator, bool> ret=
1812.3.8 by Brian Aker
This switches our schema system over to using a shared ptr. Lets see how
215
        schema_cache.insert(make_pair(schema_identifier.getPath(), new message::Schema(schema_message)));
1309.1.3 by Brian Aker
Cache for Schema.
216
217
      if (ret.second == false)
218
      {
219
        abort(); // If this has happened, something really bad is going down.
220
      }
1755.2.6 by Brian Aker
Remove usage of non-boost lock type.
221
    }
222
    mutex.unlock();
1273.19.26 by Brian Aker
Move Alter schema to SE interface.
223
  }
224
225
  return true;
226
}
1273.19.27 by Brian Aker
Move schema writing code to schema engine plugin.
227
228
/**
229
  path is path to database, not schema file 
230
231
  @note we do the rename to make it crash safe.
232
*/
1642 by Brian Aker
This adds const to SchemaIdentifier.
233
bool Schema::writeSchemaFile(const SchemaIdentifier &schema_identifier, const message::Schema &db)
1273.19.27 by Brian Aker
Move schema writing code to schema engine plugin.
234
{
235
  char schema_file_tmp[FN_REFLEN];
1415 by Brian Aker
Mass overhaul to use schema_identifier.
236
  string schema_file(schema_identifier.getPath());
1273.19.27 by Brian Aker
Move schema writing code to schema engine plugin.
237
238
239
  schema_file.append(1, FN_LIBCHAR);
240
  schema_file.append(MY_DB_OPT_FILE);
241
1395.1.18 by Brian Aker
Small update.
242
  snprintf(schema_file_tmp, FN_REFLEN, "%sXXXXXX", schema_file.c_str());
243
1273.19.27 by Brian Aker
Move schema writing code to schema engine plugin.
244
  int fd= mkstemp(schema_file_tmp);
245
246
  if (fd == -1)
1387 by Brian Aker
Fix for cases where not all files are removed during a deletion of a schema.
247
  {
248
    perror(schema_file_tmp);
1395.1.18 by Brian Aker
Small update.
249
1309.1.3 by Brian Aker
Cache for Schema.
250
    return false;
1387 by Brian Aker
Fix for cases where not all files are removed during a deletion of a schema.
251
  }
1273.19.27 by Brian Aker
Move schema writing code to schema engine plugin.
252
1608.1.2 by Brian Aker
Merge enum test
253
  bool success;
254
255
  try {
256
    success= db.SerializeToFileDescriptor(fd);
257
  }
258
  catch (...)
259
  {
260
    success= false;
261
  }
262
263
  if (not success)
1273.19.27 by Brian Aker
Move schema writing code to schema engine plugin.
264
  {
1567.1.1 by Brian Aker
This fixes bug 586009, increases the size of the log files so that the UNION
265
    my_error(ER_CORRUPT_SCHEMA_DEFINITION, MYF(0), schema_file.c_str(),
266
             db.InitializationErrorString().empty() ? "unknown" :  db.InitializationErrorString().c_str());
1395.1.18 by Brian Aker
Small update.
267
268
    if (close(fd) == -1)
269
      perror(schema_file_tmp);
270
271
    if (unlink(schema_file_tmp))
272
      perror(schema_file_tmp);
273
274
    return false;
275
  }
276
277
  if (close(fd) == -1)
278
  {
279
    perror(schema_file_tmp);
280
281
    if (unlink(schema_file_tmp))
282
      perror(schema_file_tmp);
1309.1.3 by Brian Aker
Cache for Schema.
283
284
    return false;
1273.19.27 by Brian Aker
Move schema writing code to schema engine plugin.
285
  }
286
287
  if (rename(schema_file_tmp, schema_file.c_str()) == -1)
288
  {
1395.1.18 by Brian Aker
Small update.
289
    if (unlink(schema_file_tmp))
290
      perror(schema_file_tmp);
1309.1.3 by Brian Aker
Cache for Schema.
291
292
    return false;
293
  }
294
295
  return true;
296
}
297
298
1749.3.14 by Brian Aker
Update to use the identifier (and not the straight filename).
299
bool Schema::readSchemaFile(const drizzled::SchemaIdentifier &schema_identifier, drizzled::message::Schema &schema)
1309.1.3 by Brian Aker
Cache for Schema.
300
{
1749.3.14 by Brian Aker
Update to use the identifier (and not the straight filename).
301
  string db_opt_path(schema_identifier.getPath());
1309.1.3 by Brian Aker
Cache for Schema.
302
303
  /*
304
    Pass an empty file name, and the database options file name as extension
305
    to avoid table name to file name encoding.
306
  */
1415 by Brian Aker
Mass overhaul to use schema_identifier.
307
  db_opt_path.append(1, FN_LIBCHAR);
1358.1.5 by Brian Aker
Cleans up use of static buffer in TableIdentifier.
308
  db_opt_path.append(MY_DB_OPT_FILE);
1309.1.3 by Brian Aker
Cache for Schema.
309
1358.1.5 by Brian Aker
Cleans up use of static buffer in TableIdentifier.
310
  fstream input(db_opt_path.c_str(), ios::in | ios::binary);
1309.1.3 by Brian Aker
Cache for Schema.
311
312
  /**
313
    @note If parsing fails, either someone has done a "mkdir" or has deleted their opt file.
314
    So what do we do? We muddle through the adventure by generating 
315
    one with a name in it, and the charset set to the default.
316
  */
317
  if (input.good())
318
  {
1749.3.14 by Brian Aker
Update to use the identifier (and not the straight filename).
319
    if (schema.ParseFromIstream(&input))
1309.1.3 by Brian Aker
Cache for Schema.
320
    {
321
      return true;
322
    }
1415 by Brian Aker
Mass overhaul to use schema_identifier.
323
1567.1.1 by Brian Aker
This fixes bug 586009, increases the size of the log files so that the UNION
324
    my_error(ER_CORRUPT_SCHEMA_DEFINITION, MYF(0), db_opt_path.c_str(),
1749.3.14 by Brian Aker
Update to use the identifier (and not the straight filename).
325
             schema.InitializationErrorString().empty() ? "unknown" :  schema.InitializationErrorString().c_str());
1309.1.3 by Brian Aker
Cache for Schema.
326
  }
327
  else
328
  {
1358.1.5 by Brian Aker
Cleans up use of static buffer in TableIdentifier.
329
    perror(db_opt_path.c_str());
1309.1.3 by Brian Aker
Cache for Schema.
330
  }
331
332
  return false;
333
}
1320.1.8 by Brian Aker
Temporary fix for allowing engines to say "don't do this".
334
1429.1.3 by Brian Aker
Merge in work for fetching a list of table identifiers.
335
void Schema::doGetTableIdentifiers(drizzled::CachedDirectory&,
1642 by Brian Aker
This adds const to SchemaIdentifier.
336
                                   const drizzled::SchemaIdentifier&,
1966.2.4 by Brian Aker
Style cleanup.
337
                                   drizzled::TableIdentifier::vector&)
1429.1.3 by Brian Aker
Merge in work for fetching a list of table identifiers.
338
{
339
}