~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/plugin/catalog.cc

Merge catalog with current trunk.

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) 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
 
 
23
#include "drizzled/plugin/catalog.h"
 
24
#include "drizzled/catalog/cache.h"
 
25
#include "drizzled/error.h"
 
26
 
 
27
#include <boost/foreach.hpp>
 
28
 
 
29
namespace drizzled
 
30
{
 
31
namespace plugin
 
32
{
 
33
 
 
34
// Private container we use for holding the instances of engines passed to
 
35
// use from the catalog plugins.
 
36
class Engines {
 
37
  catalog::Engine::vector _catalogs;
 
38
 
 
39
public:
 
40
  static Engines& singleton()
 
41
  {
 
42
    static Engines ptr;
 
43
    return ptr;
 
44
  }
 
45
 
 
46
  catalog::Engine::vector &catalogs()
 
47
  {
 
48
    return _catalogs;
 
49
  }
 
50
};
 
51
 
 
52
class LockErase
 
53
{
 
54
  bool _locked;
 
55
  const identifier::Catalog &identifier;
 
56
  catalog::error_t error;
 
57
 
 
58
public:
 
59
  LockErase(const identifier::Catalog &identifier_arg) :
 
60
    _locked(false),
 
61
    identifier(identifier_arg)
 
62
  {
 
63
    init();
 
64
  }
 
65
 
 
66
  bool locked () const
 
67
  {
 
68
    return _locked;
 
69
  }
 
70
 
 
71
  ~LockErase()
 
72
  {
 
73
    if (_locked)
 
74
    {
 
75
      if (not catalog::Cache::singleton().unlock(identifier, error))
 
76
      {
 
77
        catalog::error(error, identifier);
 
78
        assert(0);
 
79
      }
 
80
    }
 
81
  }
 
82
 
 
83
private:
 
84
  void init()
 
85
  {
 
86
    // We insert a lock into the cache, if this fails we bail.
 
87
    if (not catalog::Cache::singleton().lock(identifier, error))
 
88
    {
 
89
      assert(0);
 
90
      return;
 
91
    }
 
92
 
 
93
    _locked= true;
 
94
  }
 
95
};
 
96
 
 
97
class CreateLock
 
98
{
 
99
  bool _locked;
 
100
  const identifier::Catalog &identifier;
 
101
  catalog::error_t error;
 
102
 
 
103
public:
 
104
  CreateLock(const identifier::Catalog &identifier_arg) :
 
105
    _locked(false),
 
106
    identifier(identifier_arg)
 
107
  {
 
108
    init();
 
109
  }
 
110
 
 
111
  bool locked () const
 
112
  {
 
113
    return _locked;
 
114
  }
 
115
 
 
116
  ~CreateLock()
 
117
  {
 
118
    if (_locked)
 
119
    {
 
120
      if (not catalog::Cache::singleton().unlock(identifier, error))
 
121
      {
 
122
        catalog::error(error, identifier);
 
123
        assert(0);
 
124
      }
 
125
    }
 
126
  }
 
127
 
 
128
 
 
129
private:
 
130
  void init()
 
131
  {
 
132
    // We insert a lock into the cache, if this fails we bail.
 
133
    if (not catalog::Cache::singleton().lock(identifier, error))
 
134
    {
 
135
      assert(0);
 
136
      return;
 
137
    }
 
138
 
 
139
    _locked= true;
 
140
  }
 
141
};
 
142
 
 
143
Catalog::~Catalog()
 
144
{
 
145
}
 
146
 
 
147
bool Catalog::create(const identifier::Catalog &identifier)
 
148
{
 
149
  message::catalog::shared_ptr message= message::catalog::make_shared(identifier);
 
150
  return create(identifier, message);
 
151
}
 
152
 
 
153
bool Catalog::create(const identifier::Catalog &identifier, message::catalog::shared_ptr &message)
 
154
{
 
155
  assert(message);
 
156
 
 
157
  CreateLock lock(identifier);
 
158
 
 
159
  if (not lock.locked())
 
160
  {
 
161
    my_error(ER_CATALOG_NO_LOCK, MYF(0), identifier.getName().c_str());
 
162
    return false;
 
163
  }
 
164
 
 
165
  BOOST_FOREACH(catalog::Engine::vector::const_reference ref, Engines::singleton().catalogs())
 
166
  {
 
167
    if (ref->create(identifier, message))
 
168
    {
 
169
      return false;
 
170
    }
 
171
  }
 
172
 
 
173
  return true;
 
174
}
 
175
 
 
176
bool Catalog::drop(const identifier::Catalog &identifier)
 
177
{
 
178
  static drizzled::identifier::Catalog LOCAL_IDENTIFIER("local");
 
179
  if (identifier == LOCAL_IDENTIFIER)
 
180
  {
 
181
    my_error(drizzled::ER_CATALOG_NO_DROP_LOCAL, MYF(0));
 
182
    return false;
 
183
  }
 
184
 
 
185
  LockErase lock(identifier);
 
186
  if (not lock.locked())
 
187
  {
 
188
    my_error(ER_CATALOG_NO_LOCK, MYF(0), identifier.getName().c_str());
 
189
    return false; 
 
190
  }
 
191
 
 
192
  
 
193
  BOOST_FOREACH(catalog::Engine::vector::const_reference ref, Engines::singleton().catalogs())
 
194
  {
 
195
    if (not ref->drop(identifier))
 
196
    {
 
197
      return false;
 
198
    }
 
199
  }
 
200
 
 
201
  return true;
 
202
}
 
203
 
 
204
bool Catalog::lock(const identifier::Catalog &identifier)
 
205
{
 
206
  catalog::error_t error;
 
207
  
 
208
  // We insert a lock into the cache, if this fails we bail.
 
209
  if (not catalog::Cache::singleton().lock(identifier, error))
 
210
  {
 
211
    catalog::error(error, identifier);
 
212
 
 
213
    return false;
 
214
  }
 
215
 
 
216
  return true;
 
217
}
 
218
 
 
219
 
 
220
bool Catalog::unlock(const identifier::Catalog &identifier)
 
221
{
 
222
  catalog::error_t error;
 
223
  if (not catalog::Cache::singleton().unlock(identifier, error))
 
224
  {
 
225
    catalog::error(error, identifier);
 
226
  }
 
227
 
 
228
  return false;
 
229
}
 
230
 
 
231
bool plugin::Catalog::addPlugin(plugin::Catalog *arg)
 
232
{
 
233
  Engines::singleton().catalogs().push_back(arg->engine());
 
234
 
 
235
  return false;
 
236
}
 
237
 
 
238
bool plugin::Catalog::exist(const identifier::Catalog &identifier)
 
239
{
 
240
  if (catalog::Cache::singleton().exist(identifier))
 
241
    return true;
 
242
 
 
243
  BOOST_FOREACH(catalog::Engine::vector::const_reference ref, Engines::singleton().catalogs())
 
244
  {
 
245
    if (ref->exist(identifier))
 
246
      return true;
 
247
  }
 
248
 
 
249
  return false;
 
250
}
 
251
 
 
252
void plugin::Catalog::getIdentifiers(identifier::Catalog::vector &identifiers)
 
253
{
 
254
  BOOST_FOREACH(catalog::Engine::vector::const_reference ref, Engines::singleton().catalogs())
 
255
  {
 
256
    ref->getIdentifiers(identifiers);
 
257
  }
 
258
}
 
259
 
 
260
void plugin::Catalog::getMessages(message::catalog::vector &messages)
 
261
{
 
262
  BOOST_FOREACH(catalog::Engine::vector::const_reference ref, Engines::singleton().catalogs())
 
263
  {
 
264
    ref->getMessages(messages);
 
265
  }
 
266
}
 
267
 
 
268
bool plugin::Catalog::getMessage(const identifier::Catalog &identifier, message::catalog::shared_ptr &message)
 
269
{
 
270
  catalog::error_t error;
 
271
  catalog::Instance::shared_ptr instance= catalog::Cache::singleton().find(identifier, error);
 
272
 
 
273
  if (instance and instance->message())
 
274
  {
 
275
    message= instance->message();
 
276
 
 
277
    if (message)
 
278
      return message;
 
279
  }
 
280
 
 
281
  BOOST_FOREACH(catalog::Engine::vector::const_reference ref, Engines::singleton().catalogs())
 
282
  {
 
283
    if (ref->getMessage(identifier, message))
 
284
      return true;
 
285
  }
 
286
 
 
287
  return false;
 
288
}
 
289
 
 
290
bool plugin::Catalog::getInstance(const identifier::Catalog &identifier, catalog::Instance::shared_ptr &instance)
 
291
{
 
292
  catalog::error_t error;
 
293
  instance= catalog::Cache::singleton().find(identifier, error);
 
294
 
 
295
  if (instance)
 
296
    return true;
 
297
 
 
298
  BOOST_FOREACH(catalog::Engine::vector::const_reference ref, Engines::singleton().catalogs())
 
299
  {
 
300
    if (ref->getInstance(identifier, instance))
 
301
      return true;
 
302
  }
 
303
 
 
304
  // If this should fail, we are in a world of pain.
 
305
  catalog::Cache::singleton().insert(identifier, instance, error);
 
306
 
 
307
  return true;
 
308
}
 
309
 
 
310
 
 
311
void plugin::Catalog::removePlugin(plugin::Catalog *arg)
 
312
{
 
313
  Engines::singleton().catalogs().erase(find(Engines::singleton().catalogs().begin(),
 
314
                                             Engines::singleton().catalogs().end(),
 
315
                                             arg->engine()));
 
316
}
 
317
 
 
318
} /* namespace plugin */
 
319
} /* namespace drizzled */