1
/* Copyright (c) 2009 PrimeBase Technologies GmbH, Germany
3
* PrimeBase Media Stream for MySQL
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
* PBMS interface used to enable engines for use with the PBMS engine.
27
* For an example on how to build this into an engine have a look at the PBXT engine
28
* in file ha_pbxt.cc. Search for 'PBMS_ENABLED'.
32
#include "xt_config.h"
38
#include <drizzled/common_includes.h>
39
#include <drizzled/plugin.h>
41
#include "mysql_priv.h"
42
#include <mysql/plugin.h>
43
#define session_alloc(sess, size) thd_alloc(sess, size);
44
#define current_session current_thd
47
#define GET_BLOB_FIELD(t, i) (Field_blob *)(t->field[t->s->blob_field[i]])
48
#define DB_NAME(f) (f->table->s->db.str)
49
#define TAB_NAME(f) (*(f->table_name))
51
#define PBMS_API pbms_enabled_api
53
#include "pbms_enabled.h"
55
static PBMS_API pbms_api;
57
PBMSEngineRec enabled_engine = {
61
//====================
62
bool pbms_initialize(const char *engine_name, bool isServer, PBMSResultPtr result)
66
strncpy(enabled_engine.ms_engine_name, engine_name, 32);
67
enabled_engine.ms_internal = isServer;
68
enabled_engine.ms_engine_name[31] = 0;
70
err = pbms_api.registerEngine(&enabled_engine, result);
76
//====================
79
pbms_api.deregisterEngine(&enabled_engine);
82
//====================
83
int pbms_write_row_blobs(TABLE *table, uchar *row_buffer, PBMSResultPtr result)
86
char *blob_rec, *blob;
87
size_t packlength, i, org_length, length;
88
char blob_url_buffer[PBMS_BLOB_URL_SIZE];
92
if (table->s->blob_fields == 0)
95
for (i= 0; i < table->s->blob_fields; i++) {
96
field = GET_BLOB_FIELD(table, i);
98
// Note: field->type() always returns MYSQL_TYPE_BLOB regardless of the type of BLOB
99
field->sql_type(type_name);
100
if (strcasecmp(type_name.c_ptr(), "LongBlob"))
103
// Get the blob record:
104
blob_rec = (char *)row_buffer + field->offset(field->table->record[0]);
105
packlength = field->pack_length() - field->table->s->blob_ptr_size;
107
memcpy(&blob, blob_rec +packlength, sizeof(char*));
108
org_length = field->get_length((uchar *)blob_rec);
111
// Signal PBMS to record a new reference to the BLOB.
112
// If 'blob' is not a BLOB URL then it will be stored in the repositor as a new BLOB
113
// and a reference to it will be created.
114
err = pbms_api.retainBlob(DB_NAME(field), TAB_NAME(field), blob_url_buffer, blob, org_length, field->field_index, result);
118
// If the BLOB length changed reset it.
119
// This will happen if the BLOB data was replaced with a BLOB reference.
120
length = strlen(blob_url_buffer) +1;
121
if ((length != org_length) || memcmp(blob_url_buffer, blob, length)) {
122
if (length != org_length) {
123
field->store_length((uchar *)blob_rec, packlength, length);
126
if (length > org_length) {
127
// This can only happen if the BLOB URL is actually larger than the BLOB itself.
128
blob = (char *) session_alloc(current_session, length);
129
memcpy(blob_rec+packlength, &blob, sizeof(char*));
131
memcpy(blob, blob_url_buffer, length);
138
//====================
139
int pbms_delete_row_blobs(TABLE *table, const uchar *row_buffer, PBMSResultPtr result)
142
const char *blob_rec;
144
size_t packlength, i, length;
148
if (table->s->blob_fields == 0)
151
for (i= 0; i < table->s->blob_fields; i++) {
152
field = GET_BLOB_FIELD(table, i);
154
// Note: field->type() always returns MYSQL_TYPE_BLOB regardless of the type of BLOB
155
field->sql_type(type_name);
156
if (strcasecmp(type_name.c_ptr(), "LongBlob"))
159
// Get the blob record:
160
blob_rec = (char *)row_buffer + field->offset(field->table->record[0]);
161
packlength = field->pack_length() - field->table->s->blob_ptr_size;
163
length = field->get_length((uchar *)blob_rec);
164
memcpy(&blob, blob_rec +packlength, sizeof(char*));
166
// Signal PBMS to delete the reference to the BLOB.
167
err = pbms_api.releaseBlob(DB_NAME(field), TAB_NAME(field), blob, length, result);
175
#define MAX_NAME_SIZE 64
176
static void parse_table_path(const char *path, char *db_name, char *tab_name)
178
const char *ptr = path + strlen(path) -1, *eptr;
181
*db_name = *tab_name = 0;
183
while ((ptr > path) && (*ptr != '/'))ptr --;
187
strncpy(tab_name, ptr+1, MAX_NAME_SIZE);
188
tab_name[MAX_NAME_SIZE-1] = 0;
192
while ((ptr > path) && (*ptr != '/'))ptr --;
198
if (len >= MAX_NAME_SIZE)
199
len = MAX_NAME_SIZE-1;
201
memcpy(db_name, ptr, len);
206
//====================
207
int pbms_rename_table_with_blobs(const char *old_table_path, const char *new_table_path, PBMSResultPtr result)
209
char o_db_name[MAX_NAME_SIZE], n_db_name[MAX_NAME_SIZE], o_tab_name[MAX_NAME_SIZE], n_tab_name[MAX_NAME_SIZE];
211
parse_table_path(old_table_path, o_db_name, o_tab_name);
212
parse_table_path(new_table_path, n_db_name, n_tab_name);
214
if (strcmp(o_db_name, n_db_name)) {
215
result->mr_code = MS_ERR_INVALID_OPERATION;
216
strcpy(result->mr_message, "PBMS does not support renaming tables across databases.");
217
strcpy(result->mr_stack, "pbms_rename_table_with_blobs()");
218
return MS_ERR_INVALID_OPERATION;
222
return pbms_api.renameTable(o_db_name, o_tab_name, n_tab_name, result);
225
//====================
226
int pbms_delete_table_with_blobs(const char *table_path, PBMSResultPtr result)
228
char db_name[MAX_NAME_SIZE], tab_name[MAX_NAME_SIZE];
230
parse_table_path(table_path, db_name, tab_name);
232
return pbms_api.dropTable(db_name, tab_name, result);
235
//====================
236
void pbms_completed(TABLE *table, bool ok)
238
if ((!table) || (table->s->blob_fields != 0))
239
pbms_api.completed(ok) ;
244
#endif // PBMS_ENABLED