~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Stewart Smith
  • Date: 2010-11-03 03:27:09 UTC
  • mto: (1902.1.1 build) (1910.1.2 build)
  • mto: This revision was merged to the branch mainline in revision 1903.
  • Revision ID: stewart@flamingspork.com-20101103032709-oyvfrc6eb8fzj0mr
fix docs warning: docs/unlock.rst:2: (WARNING/2) Title underline too short.

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::TableIdentifiers &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