~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Brian Aker
  • Date: 2008-10-11 17:31:45 UTC
  • Revision ID: brian@tangent.org-20081011173145-qzws50bp0npuihzp
Removed dead bootstrap variable.

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