~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/pbms/src/ha_pbms.cc

  • Committer: Mark Atwood
  • Date: 2011-12-20 02:32:53 UTC
  • mfrom: (2469.1.1 drizzle-build)
  • Revision ID: me@mark.atwood.name-20111220023253-bvu0kr14kwsdvz7g
mergeĀ lp:~brianaker/drizzle/deprecate-pbms

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2008 PrimeBase Technologies GmbH, Germany
2
 
 *
3
 
 * PrimeBase Media Stream for MySQL
4
 
 *
5
 
 * This program is free software; you can redistribute it and/or modify
6
 
 * it under the terms of the GNU General Public License as published by
7
 
 * the Free Software Foundation; either version 2 of the License, or
8
 
 * (at your option) any later version.
9
 
 *
10
 
 * This program is distributed in the hope that it will be useful,
11
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 * GNU General Public License for more details.
14
 
 *
15
 
 * You should have received a copy of the GNU General Public License
16
 
 * along with this program; if not, write to the Free Software
17
 
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
 
 *
19
 
 * Original author: Paul McCullagh
20
 
 * Continued development: Barry Leslie
21
 
 *
22
 
 * 2007-05-20
23
 
 *
24
 
 * H&G2JCtL
25
 
 *
26
 
 * Table handler.
27
 
 *
28
 
 */
29
 
 
30
 
#ifdef USE_PRAGMA_IMPLEMENTATION
31
 
#pragma implementation                          // gcc: Class implementation
32
 
#endif
33
 
 
34
 
#ifdef DRIZZLED
35
 
#include <config.h>
36
 
 
37
 
#include <drizzled/current_session.h>
38
 
#include <drizzled/common.h>
39
 
#include <drizzled/plugin.h>
40
 
#include <drizzled/field.h>
41
 
#include <drizzled/session.h>
42
 
#include <drizzled/data_home.h>
43
 
#include <drizzled/error.h>
44
 
#include <drizzled/table.h>
45
 
#include <drizzled/plugin/transactional_storage_engine.h>
46
 
#include <drizzled/named_savepoint.h>
47
 
 
48
 
#define my_strdup(a,b) strdup(a)
49
 
using namespace drizzled;
50
 
using namespace drizzled::plugin;
51
 
 
52
 
 
53
 
 
54
 
#include "cslib/CSConfig.h"
55
 
#else
56
 
#include "cslib/CSConfig.h"
57
 
#include "mysql_priv.h"
58
 
#include <mysql/plugin.h>
59
 
#include <my_dir.h>
60
 
#endif 
61
 
 
62
 
#include <stdlib.h>
63
 
#include <time.h>
64
 
#include <inttypes.h>
65
 
 
66
 
 
67
 
#include "defs_ms.h"
68
 
 
69
 
#include "cslib/CSDefs.h"
70
 
#include "cslib/CSObject.h"
71
 
#include "cslib/CSGlobal.h"
72
 
#include "cslib/CSThread.h"
73
 
#include "cslib/CSStrUtil.h"
74
 
#include "cslib/CSLog.h"
75
 
 
76
 
#include "engine_ms.h"  
77
 
#include "ha_pbms.h"
78
 
#include "network_ms.h"
79
 
#include "connection_handler_ms.h"
80
 
#include "open_table_ms.h"
81
 
#include "database_ms.h"
82
 
#include "temp_log_ms.h"
83
 
#include "system_table_ms.h"
84
 
#include "mysql_ms.h"
85
 
#include "discover_ms.h"
86
 
#include "metadata_ms.h"
87
 
#include "transaction_ms.h"
88
 
#include "systab_httpheader_ms.h"
89
 
#include "system_table_ms.h"
90
 
#include "parameters_ms.h"
91
 
#include "pbmsdaemon_ms.h"
92
 
#include "version_ms.h"
93
 
 
94
 
/* Note: 'new' used here is NOT CSObject::new which is a DEBUG define*/
95
 
#ifdef new
96
 
#undef new
97
 
#endif
98
 
 
99
 
 
100
 
#ifdef DRIZZLED
101
 
 
102
 
static int pbms_done_func(void *);
103
 
 
104
 
class PBMSStorageEngine : public drizzled::plugin::TransactionalStorageEngine {
105
 
public:
106
 
        PBMSStorageEngine()
107
 
        : TransactionalStorageEngine(std::string("PBMS"), HTON_NO_FLAGS | HTON_HIDDEN) {}
108
 
 
109
 
        ~PBMSStorageEngine()
110
 
        {
111
 
                pbms_done_func(NULL);
112
 
        }
113
 
        
114
 
        int close_connection(Session *);
115
 
        
116
 
        int doStartTransaction(Session *session, start_transaction_option_t options);
117
 
        int doCommit(Session *, bool);
118
 
        int doRollback(Session *, bool);
119
 
        Cursor *create(Table& table);
120
 
        bool doDropSchema(const drizzled::identifier::Schema&);
121
 
        
122
 
        /*
123
 
        * Indicates to a storage engine the start of a
124
 
        * new SQL statement.
125
 
        */
126
 
        void doStartStatement(Session *session)
127
 
        {
128
 
                (void) session;
129
 
        }
130
 
 
131
 
        /*
132
 
        * Indicates to a storage engine the end of
133
 
        * the current SQL statement in the supplied
134
 
        * Session.
135
 
        */
136
 
        void doEndStatement(Session *session)
137
 
        {
138
 
                (void) session;
139
 
        }
140
 
        
141
 
        int doCreateTable(Session&, Table&, const identifier::Table& ident, const drizzled::message::Table& );  
142
 
        int doDropTable(Session &, const identifier::Table& );
143
 
        
144
 
        int doRenameTable(Session&, const identifier::Table &from, const identifier::Table &to);
145
 
        
146
 
        void doGetTableIdentifiers(drizzled::CachedDirectory &dir,
147
 
                                   const drizzled::identifier::Schema &schema,
148
 
                                   drizzled::identifier::table::vector &set_of_identifiers) 
149
 
        {
150
 
                std::set<std::string> set_of_names;
151
 
                
152
 
                doGetTableNames(dir, schema, set_of_names);
153
 
                for (std::set<std::string>::iterator set_iter = set_of_names.begin(); set_iter != set_of_names.end(); ++set_iter)
154
 
                {
155
 
                        set_of_identifiers.push_back(identifier::Table(schema, *set_iter));
156
 
                }
157
 
        }
158
 
        
159
 
        void doGetTableNames(CachedDirectory&, 
160
 
                                        const identifier::Schema &schema, 
161
 
                                        std::set<std::string> &set_of_names) 
162
 
        {
163
 
                bool isPBMS = schema.compare("PBMS");
164
 
                
165
 
                if (isPBMS || PBMSParameters::isBLOBDatabase(schema.getSchemaName().c_str()))
166
 
                        PBMSSystemTables::getSystemTableNames(isPBMS, set_of_names);
167
 
        }
168
 
 
169
 
        int doSetSavepoint(Session *thd, NamedSavepoint &savepoint);
170
 
        int doRollbackToSavepoint(Session *session, NamedSavepoint &savepoint);
171
 
        int doReleaseSavepoint(Session *session, NamedSavepoint &savepoint);
172
 
        const char **bas_ext() const;
173
 
 
174
 
  int doGetTableDefinition(Session&, const identifier::Table &identifier,
175
 
                                          drizzled::message::Table &table_proto)
176
 
  {
177
 
                int err;
178
 
                const char *tab_name = identifier.getTableName().c_str();
179
 
 
180
 
                // Set some required table proto info:
181
 
                table_proto.set_schema(identifier.getSchemaName().c_str());
182
 
                table_proto.set_creation_timestamp(0);
183
 
                table_proto.set_update_timestamp(0);
184
 
                
185
 
                err = PBMSSystemTables::getSystemTableInfo(tab_name, table_proto);
186
 
                if (err)
187
 
                        return err;
188
 
                        
189
 
                return EEXIST;
190
 
  }
191
 
 
192
 
        bool doDoesTableExist(Session&, const identifier::Table &identifier)
193
 
        {
194
 
                const char *tab_name = identifier.getTableName().c_str();
195
 
                const char *db_name = identifier.getSchemaName().c_str();
196
 
                bool isPBMS = identifier.getSchemaName().compare("PBMS");
197
 
                
198
 
                if (isPBMS || PBMSParameters::isBLOBDatabase(db_name)) {
199
 
                        return PBMSSystemTables::isSystemTable(isPBMS, tab_name);                                                                        
200
 
                }
201
 
                
202
 
                return false;           
203
 
        }
204
 
 
205
 
 
206
 
};
207
 
 
208
 
PBMSStorageEngine       *pbms_hton;
209
 
#else
210
 
handlerton              *pbms_hton;
211
 
#endif
212
 
 
213
 
static const char *ha_pbms_exts[] = {
214
 
        NullS
215
 
};
216
 
 
217
 
/*
218
 
 * ---------------------------------------------------------------
219
 
 * UTILITIES
220
 
 */
221
 
 
222
 
#ifndef DRIZZLED
223
 
void pbms_take_part_in_transaction(void *thread)
224
 
{
225
 
        THD                     *thd;
226
 
        if ((thd = (THD *) thread)) {
227
 
                trans_register_ha(thd, true, pbms_hton); 
228
 
        }
229
 
}
230
 
#endif
231
 
 
232
 
#ifdef DRIZZLED
233
 
const char **PBMSStorageEngine::bas_ext() const
234
 
#else
235
 
const char **ha_pbms::bas_ext() const
236
 
#endif
237
 
{
238
 
        return ha_pbms_exts;
239
 
}
240
 
 
241
 
#ifdef DRIZZLED
242
 
int PBMSStorageEngine::close_connection(Session *thd)
243
 
{
244
 
#else
245
 
static int pbms_close_connection(handlerton *hton, THD* thd)
246
 
{
247
 
        (void)hton;
248
 
#endif
249
 
        MSEngine::closeConnection(thd);
250
 
        return 0;
251
 
}
252
 
 
253
 
 
254
 
 
255
 
/*
256
 
 * ---------------------------------------------------------------
257
 
 * HANDLER INTERFACE
258
 
 */
259
 
 
260
 
 
261
 
#ifdef DRIZZLED
262
 
Cursor *PBMSStorageEngine::create(Table& table)
263
 
{
264
 
        PBMSStorageEngine * const hton = this;
265
 
        return new ha_pbms(hton, table);
266
 
}
267
 
#else
268
 
static handler *pbms_create_handler(handlerton *hton, TABLE_SHARE *table, MEM_ROOT *mem_root)
269
 
{
270
 
        return new (mem_root) ha_pbms(hton, table);
271
 
}
272
 
#endif
273
 
 
274
 
#ifdef DRIZZLED
275
 
int PBMSStorageEngine::doStartTransaction(Session *thd, start_transaction_option_t options)
276
 
{
277
 
        (void)thd;
278
 
        (void)options;
279
 
        return 0;
280
 
}
281
 
 
282
 
int PBMSStorageEngine::doCommit(Session *thd, bool all)
283
 
{
284
 
#else
285
 
static int pbms_commit(handlerton *, THD *thd, bool all)
286
 
{
287
 
#endif
288
 
        int                     err = 0;
289
 
        CSThread        *self;
290
 
        PBMSResultRec result;
291
 
 
292
 
        // I am not interesed in single statement transactions.
293
 
        if (all == false)
294
 
                return 0;
295
 
 
296
 
        if (MSEngine::enterConnection(thd, &self, &result, false))
297
 
                return 0;
298
 
        inner_();
299
 
        try_(a) {
300
 
                MSTransactionManager::commit();
301
 
        }
302
 
        catch_(a) {
303
 
                err = MSEngine::exceptionToResult(&self->myException, &result);
304
 
        }
305
 
        cont_(a);
306
 
        self->myIsAutoCommit = true;
307
 
        return_(err);
308
 
}
309
 
 
310
 
#ifdef DRIZZLED
311
 
int PBMSStorageEngine::doRollback(THD *thd, bool all)
312
 
{
313
 
#else
314
 
static int pbms_rollback(handlerton *, THD *thd, bool all)
315
 
{
316
 
#endif
317
 
        int                     err = 0;
318
 
        CSThread        *self;
319
 
        PBMSResultRec result;
320
 
        
321
 
        UNUSED(all);
322
 
        
323
 
        if (MSEngine::enterConnection(thd, &self, &result, false))
324
 
                return 0;
325
 
        inner_();
326
 
        try_(a) {
327
 
                MSTransactionManager::rollback();
328
 
        }
329
 
        catch_(a) {
330
 
                err = MSEngine::exceptionToResult(&self->myException, &result);
331
 
        }
332
 
        cont_(a);
333
 
        self->myIsAutoCommit = true;
334
 
        return_(err);
335
 
}
336
 
 
337
 
#ifdef DRIZZLED
338
 
int PBMSStorageEngine::doSetSavepoint(Session *thd, NamedSavepoint &savepoint)
339
 
{
340
 
        int                     err = 0;
341
 
        CSThread        *self;
342
 
        PBMSResultRec result;
343
 
 
344
 
        if (MSEngine::enterConnection(thd, &self, &result, false))
345
 
                return 0;
346
 
        
347
 
        inner_();
348
 
        try_(a) {
349
 
                MSTransactionManager::setSavepoint(savepoint.getName().c_str());
350
 
        }
351
 
        catch_(a) {
352
 
                err = MSEngine::exceptionToResult(&self->myException, &result);
353
 
        }
354
 
        cont_(a);
355
 
        return_(err);
356
 
        
357
 
}
358
 
 
359
 
int PBMSStorageEngine::doRollbackToSavepoint(Session *session, NamedSavepoint &savepoint)
360
 
{
361
 
        int                     err = 0;
362
 
        CSThread        *self;
363
 
        PBMSResultRec result;
364
 
 
365
 
        if (MSEngine::enterConnection(session, &self, &result, false))
366
 
                return 0;
367
 
        inner_();
368
 
        try_(a) {
369
 
                MSTransactionManager::rollbackTo(savepoint.getName().c_str());
370
 
        }
371
 
        catch_(a) {
372
 
                err = MSEngine::exceptionToResult(&self->myException, &result);
373
 
        }
374
 
        cont_(a);
375
 
        return_(err);
376
 
}
377
 
 
378
 
 
379
 
int PBMSStorageEngine::doReleaseSavepoint(Session *session, NamedSavepoint &savepoint)
380
 
{
381
 
        int                     err = 0;
382
 
        CSThread        *self;
383
 
        PBMSResultRec result;
384
 
 
385
 
        if (MSEngine::enterConnection(session, &self, &result, false))
386
 
                return 0;
387
 
                
388
 
        inner_();
389
 
        try_(a) {
390
 
                MSTransactionManager::releaseSavepoint(savepoint.getName().c_str());
391
 
        }
392
 
        catch_(a) {
393
 
                err = MSEngine::exceptionToResult(&self->myException, &result);
394
 
        }
395
 
        cont_(a);
396
 
        return_(err);
397
 
}
398
 
 
399
 
#else
400
 
static int pbms_savepoint_set(handlerton *hton, THD *thd, void *sv)
401
 
{
402
 
        int                     err = 0;
403
 
        CSThread        *self;
404
 
        PBMSResultRec result;
405
 
 
406
 
        if (MSEngine::enterConnection(thd, &self, &result, false))
407
 
                return 0;
408
 
                
409
 
        *((uint32_t*)sv) = self->myStmtCount;
410
 
        return 0;       
411
 
}
412
 
 
413
 
static int pbms_savepoint_rollback(handlerton *hton, THD *thd, void *sv)
414
 
{
415
 
        int                     err = 0;
416
 
        CSThread        *self;
417
 
        PBMSResultRec result;
418
 
 
419
 
        if (MSEngine::enterConnection(thd, &self, &result, false))
420
 
                return 0;
421
 
        inner_();
422
 
        try_(a) {
423
 
                MSTransactionManager::rollbackToPosition(*((uint32_t*)sv));
424
 
        }
425
 
        catch_(a) {
426
 
                err = MSEngine::exceptionToResult(&self->myException, &result);
427
 
        }
428
 
        cont_(a);
429
 
        return_(err);
430
 
}
431
 
 
432
 
static int pbms_savepoint_release(handlerton *hton, THD *thd, void *sv)
433
 
{
434
 
        return 0;
435
 
}
436
 
 
437
 
#endif
438
 
 
439
 
#ifdef DRIZZLED
440
 
bool  PBMSStorageEngine::doDropSchema(const drizzled::identifier::Schema &schema)
441
 
{
442
 
        CSThread *self;
443
 
        PBMSResultRec result;
444
 
        
445
 
        if (MSEngine::enterConnectionNoThd(&self, &result))
446
 
                return false;
447
 
        inner_();
448
 
        
449
 
        try_(a) {
450
 
                MSDatabase::dropDatabase(schema.getSchemaName().c_str());
451
 
        }
452
 
        catch_(a);
453
 
        self->logException();
454
 
        cont_(a);
455
 
        return_(false);
456
 
}
457
 
#else
458
 
static void pbms_drop_database(handlerton *, char *path)
459
 
{
460
 
        CSThread *self;
461
 
        char db_name[PATH_MAX];
462
 
        PBMSResultRec result;
463
 
        
464
 
        if (MSEngine::enterConnectionNoThd(&self, &result))
465
 
                return;
466
 
        inner_();
467
 
        
468
 
        cs_strcpy(PATH_MAX, db_name, cs_last_directory_of_path(path));
469
 
        cs_remove_dir_char(db_name);
470
 
        try_(a) {
471
 
                MSDatabase::dropDatabase(db_name);
472
 
        }
473
 
        catch_(a);
474
 
        self->logException();
475
 
        cont_(a);
476
 
        exit_();
477
 
}
478
 
#endif
479
 
 
480
 
static bool pbms_started = false;
481
 
 
482
 
 
483
 
#ifdef DRIZZLED
484
 
int pbms_init_func(module::Context &registry);
485
 
int pbms_init_func(module::Context &registry)
486
 
#else
487
 
int pbms_init_func(void *p);
488
 
int pbms_discover_system_tables(handlerton *hton, THD* thd, const char *db, const char *name, uchar **frmblob, size_t *frmlen);
489
 
int pbms_init_func(void *p)
490
 
#endif
491
 
{
492
 
        PBMSResultRec           result;
493
 
        int                                     err;
494
 
        int                                     my_res = 0;
495
 
        CSThread                        *thread;
496
 
 
497
 
        ASSERT(!pbms_started);
498
 
        pbms_started = false;
499
 
        PBMSDaemon::setDaemonState(PBMSDaemon::DaemonStartUp);
500
 
        
501
 
        {
502
 
                char info[120];
503
 
                snprintf(info, 120, "PrimeBase Media Stream (PBMS) Daemon %s loaded...", PBMSVersion::getCString());
504
 
                CSL.logLine(NULL, CSLog::Protocol, info);
505
 
        }
506
 
        CSL.logLine(NULL, CSLog::Protocol, "Barry Leslie, PrimeBase Technologies GmbH, http://www.primebase.org");
507
 
        
508
 
        if ((err = MSEngine::startUp(&result))) {
509
 
                CSL.logLine(NULL, CSLog::Error, result.mr_message);
510
 
                PBMSDaemon::setDaemonState(PBMSDaemon::DaemonError);
511
 
                return(1);
512
 
        }
513
 
 
514
 
#ifdef DRIZZLED
515
 
                pbms_hton= new PBMSStorageEngine();
516
 
                registry.add(pbms_hton);
517
 
#else
518
 
        pbms_hton = (handlerton *) p;
519
 
        pbms_hton->state = SHOW_OPTION_YES;
520
 
        pbms_hton->close_connection = pbms_close_connection; /* close_connection, cleanup thread related data. */
521
 
        pbms_hton->create = pbms_create_handler;
522
 
        pbms_hton->flags = HTON_CAN_RECREATE | HTON_HIDDEN;
523
 
        pbms_hton->drop_database = pbms_drop_database; /* Drop a database */
524
 
        pbms_hton->discover = pbms_discover_system_tables;
525
 
 
526
 
        pbms_hton->commit = pbms_commit; /* commit */
527
 
        pbms_hton->rollback = pbms_rollback; /* rollback */
528
 
 
529
 
        pbms_hton->savepoint_offset = 4;
530
 
        pbms_hton->savepoint_set = pbms_savepoint_set;
531
 
        pbms_hton->savepoint_rollback = pbms_savepoint_rollback; 
532
 
        pbms_hton->savepoint_release = pbms_savepoint_release; 
533
 
#endif
534
 
        
535
 
        /* Startup the Media Stream network: */
536
 
        cs_init_memory();
537
 
        CSThread::startUp();
538
 
        if (!(thread = CSThread::newCSThread())) {
539
 
                CSException::logOSError(CS_CONTEXT, ENOMEM);
540
 
                PBMSDaemon::setDaemonState(PBMSDaemon::DaemonError);
541
 
                return(1);
542
 
        }
543
 
        if (!CSThread::attach(thread)) {
544
 
                PBMSDaemon::setDaemonState(PBMSDaemon::DaemonError);
545
 
                thread->myException.log(NULL);
546
 
                CSThread::shutDown();
547
 
                cs_exit_memory();
548
 
                MSEngine::shutDown();
549
 
                return(1);
550
 
        }
551
 
        enter_();
552
 
        try_(a) {
553
 
                thread->threadName = CSString::newString("startup");
554
 
                MSDatabase::startUp(PBMSParameters::getDefaultMetaDataHeaders());
555
 
                MSTableList::startUp();
556
 
                MSSystemTableShare::startUp();
557
 
                MSNetwork::startUp(PBMSParameters::getPortNumber());
558
 
                MSTransactionManager::startUp();
559
 
                MSNetwork::startNetwork();
560
 
        }
561
 
        catch_(a) {
562
 
                self->logException();
563
 
                my_res = 1;
564
 
        }
565
 
        cont_(a);
566
 
        if (my_res) {
567
 
                try_(b) {
568
 
                        MSNetwork::shutDown();
569
 
                        MSTransactionManager::shutDown();
570
 
                        MSSystemTableShare::shutDown();
571
 
                        MSDatabase::stopThreads();
572
 
                        MSTableList::shutDown();
573
 
                        MSDatabase::shutDown();
574
 
                        CSThread::shutDown();
575
 
                }
576
 
                catch_(b) {
577
 
                        self->logException();
578
 
                }
579
 
                cont_(b);
580
 
        }
581
 
        outer_();
582
 
        CSThread::detach(thread);
583
 
 
584
 
        if (my_res) {
585
 
                cs_exit_memory();
586
 
                MSEngine::shutDown();
587
 
        }
588
 
        else {
589
 
                srandom(time(NULL));
590
 
                pbms_started = true;
591
 
                
592
 
        }
593
 
 
594
 
        if (pbms_started)
595
 
                PBMSDaemon::setDaemonState(PBMSDaemon::DaemonRunning);
596
 
        else
597
 
                PBMSDaemon::setDaemonState(PBMSDaemon::DaemonError);
598
 
 
599
 
        return(my_res);
600
 
}
601
 
 
602
 
#ifdef DRIZZLED
603
 
static int pbms_done_func(void *)
604
 
#else
605
 
int pbms_done_func(void *)
606
 
#endif
607
 
{
608
 
        CSThread        *thread;
609
 
 
610
 
        if (!pbms_started)
611
 
                return 0;
612
 
 
613
 
        PBMSDaemon::setDaemonState(PBMSDaemon::DaemonShuttingDown);
614
 
        CSL.logLine(NULL, CSLog::Protocol, "PrimeBase Media Stream (PBMS) Daemon shutdown...");
615
 
        
616
 
        /* Shutdown the Media Stream network. */
617
 
        if (!(thread = CSThread::newCSThread()))
618
 
                CSException::logOSError(CS_CONTEXT, ENOMEM);
619
 
        else if (!CSThread::attach(thread))
620
 
                thread->myException.log(NULL);
621
 
        else {
622
 
                enter_();
623
 
                try_(a) {
624
 
                        thread->threadName = CSString::newString("shutdown");
625
 
                        MSNetwork::shutDown();
626
 
                        MSSystemTableShare::shutDown();
627
 
                        /* Ensure that the database threads are stopped before
628
 
                         * freeing the tables.
629
 
                         */
630
 
                        MSDatabase::stopThreads();
631
 
                        MSTableList::shutDown();
632
 
                        /* Databases must be shutdown after table because tables
633
 
                         * have references to repositories.
634
 
                         */
635
 
                        MSDatabase::shutDown();
636
 
                        
637
 
                        /* Shutdown the transaction manager after the databases
638
 
                         * incase they want to commit or rollback a transaction.
639
 
                         */
640
 
                        MSTransactionManager::shutDown();
641
 
                }
642
 
                catch_(a) {
643
 
                        self->logException();
644
 
                }
645
 
                cont_(a);
646
 
                outer_();
647
 
                CSThread::shutDown();
648
 
                CSThread::detach(thread);
649
 
        }
650
 
 
651
 
        MSEngine::shutDown();
652
 
        cs_exit_memory();
653
 
 
654
 
        CSL.logLine(NULL, CSLog::Protocol, "PrimeBase Media Stream (PBMS) Daemon shutdown completed");
655
 
        pbms_started = false;
656
 
        return(0);
657
 
}
658
 
 
659
 
#ifdef DRIZZLED
660
 
ha_pbms::ha_pbms(handlerton *hton, Table& table_arg) : handler(*hton, table_arg),
661
 
#else
662
 
ha_pbms::ha_pbms(handlerton *hton, TABLE_SHARE *table_arg) : handler(hton, table_arg),
663
 
#endif
664
 
ha_open_tab(NULL),
665
 
ha_error(0)
666
 
{
667
 
        memset(&ha_result, 0, sizeof(PBMSResultRec));
668
 
}
669
 
 
670
 
#ifndef DRIZZLED
671
 
MX_TABLE_TYPES_T ha_pbms::table_flags() const
672
 
{
673
 
        return (
674
 
                /* We need this flag because records are not packed
675
 
                 * into a table which means #ROWID != offset
676
 
                 */
677
 
                HA_REC_NOT_IN_SEQ |
678
 
                HA_CAN_SQL_HANDLER |
679
 
#if MYSQL_VERSION_ID > 50119
680
 
                /* We can do row logging, but not statement, because
681
 
                 * MVCC is not serializable!
682
 
                 */
683
 
                HA_BINLOG_ROW_CAPABLE |
684
 
#endif
685
 
                /*
686
 
                 * Auto-increment is allowed on a partial key.
687
 
                 */
688
 
                0);
689
 
}
690
 
#endif
691
 
 
692
 
int ha_pbms::open(const char *table_path, int , uint )
693
 
{
694
 
        CSThread *self;
695
 
 
696
 
        if ((ha_error = MSEngine::enterConnection(current_thd, &self, &ha_result, true)))
697
 
                return 1;
698
 
 
699
 
        inner_();
700
 
        try_(a) {
701
 
#ifdef DRIZZLED
702
 
                ha_open_tab = MSSystemTableShare::openSystemTable(table_path, getTable());
703
 
                ha_lock.init(&ha_open_tab->myShare->myThrLock);
704
 
#else
705
 
                ha_open_tab = MSSystemTableShare::openSystemTable(table_path, table);
706
 
                thr_lock_data_init(&ha_open_tab->myShare->myThrLock, &ha_lock, NULL);
707
 
#endif
708
 
                ref_length = ha_open_tab->getRefLen();
709
 
        }
710
 
        catch_(a) {
711
 
                ha_error = MSEngine::exceptionToResult(&self->myException, &ha_result);
712
 
        }
713
 
        cont_(a);
714
 
        return_(ha_error != MS_OK);
715
 
}
716
 
 
717
 
int ha_pbms::close(void)
718
 
{
719
 
        CSThread *self;
720
 
 
721
 
        if ((ha_error = MSEngine::enterConnection(current_thd, &self, &ha_result, true)))
722
 
                return 1;
723
 
 
724
 
        inner_();
725
 
        if (ha_open_tab) {
726
 
                ha_open_tab->release();
727
 
                ha_open_tab = NULL;
728
 
        }
729
 
        outer_();
730
 
        MSEngine::exitConnection();
731
 
        return 0;
732
 
}
733
 
 
734
 
#ifdef PBMS_HAS_KEYS
735
 
/* Index access functions: */
736
 
int ha_pbms::index_init(uint idx, bool sorted)
737
 
{
738
 
        int err = 0;
739
 
        UNUSED(sorted);
740
 
        
741
 
        enter_();
742
 
        try_(a) {
743
 
                ha_open_tab->index_init(idx);
744
 
        }
745
 
        catch_(a) {
746
 
                ha_error = MSEngine::exceptionToResult(&self->myException, &ha_result);
747
 
                err = 1;
748
 
        }
749
 
        cont_(a);
750
 
        return_(err);
751
 
}
752
 
 
753
 
//-------
754
 
int ha_pbms::index_end()
755
 
{
756
 
        int err = 0;
757
 
        enter_();
758
 
        try_(a) {
759
 
                ha_open_tab->index_end();
760
 
        }
761
 
        catch_(a) {
762
 
                ha_error = MSEngine::exceptionToResult(&self->myException, &ha_result);
763
 
                err = 1;
764
 
        }
765
 
        cont_(a);
766
 
        return_(err);
767
 
}
768
 
 
769
 
//-------
770
 
int ha_pbms::index_read(byte * buf, const byte * key,
771
 
                                                         uint key_len, enum ha_rkey_function find_flag)
772
 
{
773
 
        int err = 0;
774
 
        enter_();
775
 
        try_(a) {
776
 
                if (!ha_open_tab->index_read(buf, key, key_len, find_flag))
777
 
                        err = HA_ERR_KEY_NOT_FOUND;
778
 
 
779
 
        }
780
 
        catch_(a) {
781
 
                ha_error = MSEngine::exceptionToResult(&self->myException, &ha_result);
782
 
                err = 1;
783
 
        }
784
 
        cont_(a);
785
 
        return_(err);
786
 
}
787
 
 
788
 
//-------
789
 
int ha_pbms::index_read_idx(byte * buf, uint idx, const byte * key,
790
 
                                                                         uint key_len, enum ha_rkey_function find_flag)
791
 
{
792
 
        int err = 0;
793
 
        enter_();
794
 
        try_(a) {
795
 
                if (!ha_open_tab->index_read_idx(buf, idx, key, key_len, find_flag))
796
 
                        err = HA_ERR_KEY_NOT_FOUND;
797
 
        }
798
 
        catch_(a) {
799
 
                ha_error = MSEngine::exceptionToResult(&self->myException, &ha_result);
800
 
                err = 1;
801
 
        }
802
 
        cont_(a);
803
 
        return_(err);
804
 
}
805
 
 
806
 
//-------
807
 
int ha_pbms::index_next(byte * buf)
808
 
{
809
 
        int err = 0;
810
 
        enter_();
811
 
        try_(a) {
812
 
                if (!ha_open_tab->index_next(buf))
813
 
                        err = HA_ERR_END_OF_FILE;
814
 
        }
815
 
        catch_(a) {
816
 
                ha_error = MSEngine::exceptionToResult(&self->myException, &ha_result);
817
 
                err = 1;
818
 
        }
819
 
        cont_(a);
820
 
        return_(err);
821
 
}
822
 
 
823
 
//-------
824
 
int ha_pbms::index_prev(byte * buf)
825
 
{
826
 
        int err = 0;
827
 
        enter_();
828
 
        try_(a) {
829
 
                if (!ha_open_tab->index_prev(buf))
830
 
                        err = HA_ERR_END_OF_FILE;
831
 
        }
832
 
        catch_(a) {
833
 
                ha_error = MSEngine::exceptionToResult(&self->myException, &ha_result);
834
 
                err = 1;
835
 
        }
836
 
        cont_(a);
837
 
        return_(err);
838
 
}
839
 
 
840
 
//-------
841
 
int ha_pbms::index_first(byte * buf)
842
 
{
843
 
        int err = 0;
844
 
        enter_();
845
 
        try_(a) {
846
 
                if (!ha_open_tab->index_first(buf))
847
 
                        err = HA_ERR_END_OF_FILE;
848
 
        }
849
 
        catch_(a) {
850
 
                ha_error = MSEngine::exceptionToResult(&self->myException, &ha_result);
851
 
                err = 1;
852
 
        }
853
 
        cont_(a);
854
 
        return_(err);
855
 
}
856
 
 
857
 
//-------
858
 
int ha_pbms::index_last(byte * buf)
859
 
{
860
 
        int err = 0;
861
 
        enter_();
862
 
        try_(a) {
863
 
                if (!ha_open_tab->index_last(buf))
864
 
                        err = HA_ERR_END_OF_FILE;
865
 
        }
866
 
        catch_(a) {
867
 
                ha_error = MSEngine::exceptionToResult(&self->myException, &ha_result);
868
 
                err = 1;
869
 
        }
870
 
        cont_(a);
871
 
        return_(err);
872
 
}
873
 
 
874
 
//-------
875
 
int ha_pbms::index_read_last(byte * buf, const byte * key, uint key_len)
876
 
{
877
 
        int err = 0;
878
 
        enter_();
879
 
        try_(a) {
880
 
                if (!ha_open_tab->index_read_last(buf, key, key_len))
881
 
                        err = HA_ERR_KEY_NOT_FOUND;
882
 
        }
883
 
        catch_(a) {
884
 
                ha_error = MSEngine::exceptionToResult(&self->myException, &ha_result);
885
 
                err = 1;
886
 
        }
887
 
        cont_(a);
888
 
        return_(err);
889
 
}
890
 
 
891
 
//-------
892
 
 
893
 
#endif // PBMS_HAS_KEYS
894
 
 
895
 
/* Sequential scan functions: */
896
 
#ifdef DRIZZLED
897
 
int ha_pbms::doStartTableScan(bool )
898
 
#else
899
 
int ha_pbms::rnd_init(bool )
900
 
#endif
901
 
{
902
 
        int err = 0;
903
 
        enter_();
904
 
        try_(a) {
905
 
                ha_open_tab->seqScanInit();
906
 
        }
907
 
        catch_(a) {
908
 
                ha_error = MSEngine::exceptionToResult(&self->myException, &ha_result);
909
 
                err = 1;
910
 
        }
911
 
        cont_(a);
912
 
        return_(err);
913
 
}
914
 
 
915
 
//-------
916
 
int ha_pbms::rnd_next(unsigned char *buf)
917
 
{
918
 
        int err = 0;
919
 
        enter_();
920
 
        try_(a) {
921
 
                if (!ha_open_tab->seqScanNext((char *) buf))
922
 
                        err = HA_ERR_END_OF_FILE;
923
 
        }
924
 
        catch_(a) {
925
 
                ha_error = MSEngine::exceptionToResult(&self->myException, &ha_result);
926
 
                err = 1;
927
 
        }
928
 
        cont_(a);
929
 
        return_(err);
930
 
}
931
 
 
932
 
//-------
933
 
void ha_pbms::position(const unsigned char *)
934
 
{
935
 
        ha_open_tab->seqScanPos((unsigned char *) ref);
936
 
}
937
 
 
938
 
//-------
939
 
int ha_pbms::rnd_pos(unsigned char * buf, unsigned char *pos)
940
 
{
941
 
        int err = 0;
942
 
        enter_();
943
 
        try_(a) {
944
 
                ha_open_tab->seqScanRead(pos, (char *) buf);
945
 
        }
946
 
        catch_(a) {
947
 
                ha_error = MSEngine::exceptionToResult(&self->myException, &ha_result);
948
 
                err = 1;
949
 
        }
950
 
        cont_(a);
951
 
        return_(err);
952
 
}
953
 
 
954
 
//////////////////////////////
955
 
#ifdef DRIZZLED
956
 
int     ha_pbms::doInsertRecord(byte * buf)
957
 
#else
958
 
int ha_pbms::write_row(unsigned char * buf)
959
 
#endif
960
 
{
961
 
        int err = 0;
962
 
        enter_();
963
 
        try_(a) {
964
 
                ha_open_tab->insertRow((char *) buf);
965
 
        }
966
 
        catch_(a) {
967
 
                ha_error = MSEngine::exceptionToResult(&self->myException, &ha_result);
968
 
                err = 1;
969
 
        }
970
 
        cont_(a);
971
 
        return_(err);
972
 
}
973
 
 
974
 
#ifdef DRIZZLED
975
 
int     ha_pbms::doDeleteRecord(const byte * buf)
976
 
#else
977
 
int ha_pbms::delete_row(const  unsigned char * buf)
978
 
#endif
979
 
{
980
 
        int err = 0;
981
 
        enter_();
982
 
        try_(a) {
983
 
                ha_open_tab->deleteRow((char *) buf);
984
 
        }
985
 
        catch_(a) {
986
 
                ha_error = MSEngine::exceptionToResult(&self->myException, &ha_result);
987
 
                err = 1;
988
 
        }
989
 
        cont_(a);
990
 
        return_(err);
991
 
}
992
 
 
993
 
#ifdef DRIZZLED
994
 
int     ha_pbms::doUpdateRecord(const byte * old_data, byte * new_data)
995
 
#else
996
 
int ha_pbms::update_row(const unsigned char * old_data, unsigned char * new_data)
997
 
#endif
998
 
{
999
 
        int err = 0;
1000
 
        enter_();
1001
 
        try_(a) {
1002
 
                ha_open_tab->updateRow((char *) old_data, (char *) new_data);
1003
 
        }
1004
 
        catch_(a) {
1005
 
                ha_error = MSEngine::exceptionToResult(&self->myException, &ha_result);
1006
 
                err = 1;
1007
 
        }
1008
 
        cont_(a);
1009
 
        return_(err);
1010
 
}
1011
 
 
1012
 
int ha_pbms::info(uint )
1013
 
{
1014
 
        return 0;
1015
 
}
1016
 
 
1017
 
int ha_pbms::external_lock(THD *thd, int lock_type)
1018
 
{
1019
 
        CSThread        *self;
1020
 
        int                     err = 0;
1021
 
 
1022
 
        if ((ha_error = MSEngine::enterConnection(thd, &self, &ha_result, true)))
1023
 
                return 1;
1024
 
 
1025
 
        inner_();
1026
 
        try_(a) {
1027
 
                if (lock_type == F_UNLCK)
1028
 
                        ha_open_tab->unuse();
1029
 
                else
1030
 
                        ha_open_tab->use();
1031
 
        }
1032
 
        catch_(a) {
1033
 
                ha_error = MSEngine::exceptionToResult(&self->myException, &ha_result);
1034
 
                err = 1;
1035
 
        }
1036
 
        cont_(a);
1037
 
        return_(err);
1038
 
}
1039
 
 
1040
 
THR_LOCK_DATA **ha_pbms::store_lock(THD *, THR_LOCK_DATA **to, enum thr_lock_type lock_type)
1041
 
{
1042
 
        if (lock_type != TL_IGNORE && ha_lock.type == TL_UNLOCK)
1043
 
                ha_lock.type = lock_type;
1044
 
        *to++ = &ha_lock;
1045
 
        return to;
1046
 
}
1047
 
 
1048
 
 
1049
 
#ifdef DRIZZLED
1050
 
int PBMSStorageEngine::doCreateTable(Session&, Table&, const identifier::Table& , const drizzled::message::Table& )
1051
 
{
1052
 
        /* You cannot create PBMS tables. */
1053
 
        return( HA_ERR_WRONG_COMMAND );
1054
 
}
1055
 
 
1056
 
int PBMSStorageEngine::doDropTable(Session &, const identifier::Table& )
1057
 
{
1058
 
        /* You cannot delete PBMS tables. */
1059
 
        return( 0 );
1060
 
}
1061
 
 
1062
 
int PBMSStorageEngine::doRenameTable(Session&, const identifier::Table &, const identifier::Table &)
1063
 
{
1064
 
        /* You cannot rename PBMS tables. */
1065
 
        return( HA_ERR_WRONG_COMMAND );
1066
 
}
1067
 
 
1068
 
#else // DRIZZLED
1069
 
 
1070
 
int ha_pbms::create(const char *table_name, TABLE *table, HA_CREATE_INFO *)
1071
 
{
1072
 
        bool isPBMS = (strcasecmp(table->s->db.str, "PBMS") == 0);
1073
 
        
1074
 
        if (PBMSSystemTables::isSystemTable(isPBMS, cs_last_name_of_path(table_name)))
1075
 
                return(0);
1076
 
                
1077
 
        /* Create only works for system tables. */
1078
 
        return( HA_ERR_WRONG_COMMAND );
1079
 
}
1080
 
#endif // DRIZZLED
1081
 
 
1082
 
bool ha_pbms::get_error_message(int , String *buf)
1083
 
{
1084
 
        if (!ha_result.mr_code)
1085
 
                return false;
1086
 
 
1087
 
        buf->copy(ha_result.mr_message, strlen(ha_result.mr_message), system_charset_info);
1088
 
        return true;
1089
 
}
1090
 
 
1091
 
 
1092
 
CSThread *pbms_getMySelf(THD *thd);
1093
 
void pbms_setMySelf(THD *thd, CSThread *self);
1094
 
#ifdef DRIZZLED
1095
 
CSThread *pbms_getMySelf(THD *thd) { return ((CSThread *) *thd->getEngineData(pbms_hton));}
1096
 
void pbms_setMySelf(THD *thd, CSThread *self) { *thd->getEngineData(pbms_hton) = (void *)self;}
1097
 
#else
1098
 
CSThread *pbms_getMySelf(THD *thd) { return ((CSThread *) *thd_ha_data(thd, pbms_hton));}
1099
 
void pbms_setMySelf(THD *thd, CSThread *self) { *thd_ha_data(thd, pbms_hton) = (void *)self;}
1100
 
#endif
1101
 
 
1102