00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef DRIZZLED
00025 #include <config.h>
00026 #include <drizzled/common.h>
00027 #include <drizzled/session.h>
00028 #include <drizzled/field/blob.h>
00029 #include <drizzled/field/varstring.h>
00030 #endif
00031
00032 #include "cslib/CSConfig.h"
00033
00034 #include <sys/types.h>
00035 #include <sys/stat.h>
00036 #include <stdlib.h>
00037 #include <time.h>
00038
00039
00040 #include "cslib/CSGlobal.h"
00041 #include "cslib/CSStrUtil.h"
00042 #include "cslib/CSLog.h"
00043 #include "cslib/CSPath.h"
00044
00045 #include "ha_pbms.h"
00046
00047
00048 #include "mysql_ms.h"
00049 #include "database_ms.h"
00050 #include "open_table_ms.h"
00051 #include "discover_ms.h"
00052 #include "systab_util_ms.h"
00053 #include "pbmslib.h"
00054
00055 #include "systab_httpheader_ms.h"
00056
00057 #define METADATA_HEADER_FILE "http-meta-data-headers"
00058 #define MIN_METADATA_HEADER_FILE_SIZE 3
00059
00060 SysTabRec *MSHTTPHeaderTable::gDefaultMetaDataHeaders;
00061
00062 DT_FIELD_INFO pbms_metadata_headers_info[]=
00063 {
00064 {"Name", 32, NULL, MYSQL_TYPE_VARCHAR, &UTF8_CHARSET, NOT_NULL_FLAG, "HTTP field name"},
00065 {NULL, NOVAL, NULL, MYSQL_TYPE_STRING, NULL, 0, NULL}
00066 };
00067
00068 DT_KEY_INFO pbms_metadata_headers_keys[]=
00069 {
00070 {NULL, 0, {NULL}}
00071 };
00072
00073
00074
00075
00076
00077 void MSHTTPHeaderTable::releaseDefaultMetaDataHeaders()
00078 {
00079 if (gDefaultMetaDataHeaders)
00080 gDefaultMetaDataHeaders->release();
00081 gDefaultMetaDataHeaders = NULL;
00082 }
00083
00084 void MSHTTPHeaderTable::setDefaultMetaDataHeaders(const char *defaults)
00085 {
00086 const char *ptr;
00087 enter_();
00088
00089 if (!gDefaultMetaDataHeaders)
00090 new_(gDefaultMetaDataHeaders, SysTabRec("", METADATA_HEADER_FILE".dat", METADATA_HEADER_NAME));
00091
00092 gDefaultMetaDataHeaders->clear();
00093 if (defaults) {
00094 while (*defaults) {
00095 for (ptr = defaults; *ptr && (*ptr != ':'); ptr++){}
00096 if (ptr != defaults) {
00097 gDefaultMetaDataHeaders->beginRecord();
00098 gDefaultMetaDataHeaders->setStringField(defaults, ptr - defaults);
00099 gDefaultMetaDataHeaders->endRecord();
00100 }
00101 if (!*ptr)
00102 break;
00103
00104 defaults = ptr +1;
00105 }
00106 }
00107 exit_();
00108 }
00109
00110
00111 void MSHTTPHeaderTable::loadTable(MSDatabase *db)
00112 {
00113 CSPath *path;
00114 SysTabRec *headerData = NULL;
00115
00116 enter_();
00117
00118 push_(db);
00119 path = getSysFile(RETAIN(db->myDatabasePath), METADATA_HEADER_FILE, MIN_METADATA_HEADER_FILE_SIZE);
00120 push_(path);
00121
00122 if (path->exists()) {
00123 CSFile *file;
00124 size_t size;
00125
00126 new_(headerData, SysTabRec(db->myDatabaseName->getCString(), METADATA_HEADER_FILE".dat", METADATA_HEADER_NAME));
00127 push_(headerData);
00128
00129 file = path->openFile(CSFile::READONLY);
00130 push_(file);
00131 size = file->getEOF();
00132 headerData->setLength(size);
00133 file->read(headerData->getBuffer(0), 0, size, size);
00134 release_(file);
00135
00136
00137 } else if (gDefaultMetaDataHeaders) {
00138 headerData = gDefaultMetaDataHeaders;
00139 }
00140
00141 if (headerData) {
00142 while (headerData->nextRecord()) {
00143 const char *header = headerData->getStringField();
00144
00145 if (headerData->isValidRecord()) {
00146 db->iHTTPMetaDataHeaders.add(CSString::newString(header));
00147 }
00148 }
00149
00150 if (headerData == gDefaultMetaDataHeaders)
00151 gDefaultMetaDataHeaders->resetRecord();
00152 else {
00153 release_(headerData);
00154 }
00155 }
00156
00157 release_(path);
00158 release_(db);
00159
00160 exit_();
00161 }
00162
00163
00164 void MSHTTPHeaderTable::saveTable(MSDatabase *db)
00165 {
00166 CSString *str;
00167 SysTabRec *headerData;
00168 enter_();
00169
00170 push_(db);
00171
00172 new_(headerData, SysTabRec(db->myDatabaseName->getCString(), METADATA_HEADER_FILE".dat", METADATA_HEADER_NAME));
00173 push_(headerData);
00174
00175
00176 headerData->clear();
00177 lock_(&db->iHTTPMetaDataHeaders);
00178
00179
00180 for (uint32_t i =0; (str = (CSString*) db->iHTTPMetaDataHeaders.itemAt(i)); i++) {
00181 headerData->beginRecord();
00182 headerData->setStringField(str->getCString());
00183 headerData->endRecord();
00184 }
00185 unlock_(&db->iHTTPMetaDataHeaders);
00186
00187 restoreTable(RETAIN(db), headerData->getBuffer(0), headerData->length(), false);
00188
00189 release_(headerData);
00190 release_(db);
00191 exit_();
00192 }
00193
00194
00195 CSStringBuffer *MSHTTPHeaderTable::dumpTable(MSDatabase *db)
00196 {
00197
00198 CSPath *path;
00199 CSStringBuffer *dump;
00200
00201 enter_();
00202
00203 push_(db);
00204 path = getSysFile(RETAIN(db->myDatabasePath), METADATA_HEADER_FILE, MIN_METADATA_HEADER_FILE_SIZE);
00205 release_(db);
00206
00207 push_(path);
00208 new_(dump, CSStringBuffer(20));
00209 push_(dump);
00210
00211 if (path->exists()) {
00212 CSFile *file;
00213 size_t size;
00214
00215 file = path->openFile(CSFile::READONLY);
00216 push_(file);
00217
00218 size = file->getEOF();
00219 dump->setLength(size);
00220 file->read(dump->getBuffer(0), 0, size, size);
00221 release_(file);
00222 }
00223
00224 pop_(dump);
00225 release_(path);
00226 return_(dump);
00227 }
00228
00229
00230 void MSHTTPHeaderTable::restoreTable(MSDatabase *db, const char *data, size_t size, bool reload)
00231 {
00232 CSPath *path;
00233 CSFile *file;
00234
00235 enter_();
00236
00237 push_(db);
00238 path = getSysFile(RETAIN(db->myDatabasePath), METADATA_HEADER_FILE, MIN_METADATA_HEADER_FILE_SIZE);
00239 push_(path);
00240
00241 file = path->openFile(CSFile::CREATE | CSFile::TRUNCATE);
00242 push_(file);
00243
00244 file->write(data, 0, size);
00245 file->close();
00246 release_(file);
00247
00248 release_(path);
00249
00250 pop_(db);
00251 if (reload)
00252 loadTable(db);
00253 else
00254 db->release();
00255 exit_();
00256 }
00257
00258
00259 void MSHTTPHeaderTable::transferTable(MSDatabase *dst_db, MSDatabase *src_db)
00260 {
00261 CSPath *path;
00262 enter_();
00263
00264 push_(src_db);
00265 push_(dst_db);
00266
00267 path = CSPath::newPath(RETAIN(src_db->myDatabasePath), METADATA_HEADER_FILE".dat");
00268 push_(path);
00269 if (path->exists()) {
00270 CSPath *bu_path;
00271 bu_path = CSPath::newPath(RETAIN(dst_db->myDatabasePath), METADATA_HEADER_FILE".dat");
00272 path->copyTo(bu_path, true);
00273 }
00274
00275 release_(path);
00276 release_(dst_db);
00277 release_(src_db);
00278
00279 exit_();
00280 }
00281
00282 void MSHTTPHeaderTable::removeTable(CSString *db_path)
00283 {
00284 CSPath *path;
00285 enter_();
00286
00287 path = getSysFile(db_path, METADATA_HEADER_FILE, 0);
00288 push_(path);
00289
00290 path->removeFile();
00291 release_(path);
00292 exit_();
00293 }
00294
00295 MSHTTPHeaderTable::MSHTTPHeaderTable(MSSystemTableShare *share, TABLE *table):
00296 MSOpenSystemTable(share, table),
00297 iHeaderIndex(0),
00298 iDirty(false)
00299 {
00300 }
00301
00302 MSHTTPHeaderTable::~MSHTTPHeaderTable()
00303 {
00304
00305 }
00306
00307 void MSHTTPHeaderTable::use()
00308 {
00309 myShare->mySysDatabase->iHTTPMetaDataHeaders.lock();
00310 iDirty = false;
00311 }
00312
00313 void MSHTTPHeaderTable::unuse()
00314 {
00315 if (iDirty) {
00316 saveTable(RETAIN(myShare->mySysDatabase));
00317 iDirty = false;
00318 }
00319 myShare->mySysDatabase->iHTTPMetaDataHeaders.unlock();
00320
00321 }
00322
00323
00324 void MSHTTPHeaderTable::seqScanInit()
00325 {
00326 iHeaderIndex = 0;
00327 }
00328
00329 bool MSHTTPHeaderTable::seqScanNext(char *buf)
00330 {
00331 TABLE *table = mySQLTable;
00332 Field *curr_field;
00333 byte *save;
00334 MY_BITMAP *save_write_set;
00335 CSString *header;
00336 const char *name;
00337
00338 enter_();
00339
00340 header = (CSString*) (myShare->mySysDatabase->iHTTPMetaDataHeaders.itemAt(iHeaderIndex));
00341 if (!header)
00342 return_(false);
00343
00344 iHeaderIndex++;
00345 name = header->getCString();
00346
00347 save_write_set = table->write_set;
00348 table->write_set = NULL;
00349
00350 #ifdef DRIZZLED
00351 memset(buf, 0xFF, table->getNullBytes());
00352 #else
00353 memset(buf, 0xFF, table->s->null_bytes);
00354 #endif
00355 for (Field **field=GET_TABLE_FIELDS(table); *field ; field++) {
00356 curr_field = *field;
00357 save = curr_field->ptr;
00358 #if MYSQL_VERSION_ID < 50114
00359 curr_field->ptr = (byte *) buf + curr_field->offset();
00360 #else
00361 #ifdef DRIZZLED
00362 curr_field->ptr = (byte *) buf + curr_field->offset(curr_field->getTable()->getInsertRecord());
00363 #else
00364 curr_field->ptr = (byte *) buf + curr_field->offset(curr_field->table->record[0]);
00365 #endif
00366 #endif
00367 switch (curr_field->field_name[0]) {
00368 case 'N':
00369 ASSERT(strcmp(curr_field->field_name, "Name") == 0);
00370 curr_field->store(name, strlen(name), &UTF8_CHARSET);
00371 setNotNullInRecord(curr_field, buf);
00372 break;
00373
00374 }
00375 curr_field->ptr = save;
00376 }
00377
00378 table->write_set = save_write_set;
00379 return_(true);
00380 }
00381
00382 void MSHTTPHeaderTable::seqScanPos(unsigned char *pos)
00383 {
00384 int32_t index = iHeaderIndex -1;
00385 if (index < 0)
00386 index = 0;
00387
00388 mi_int4store(pos, index);
00389 }
00390
00391 void MSHTTPHeaderTable::seqScanRead(unsigned char *pos, char *buf)
00392 {
00393 iHeaderIndex = mi_uint4korr(pos);
00394 seqScanNext(buf);
00395 }
00396
00397 void MSHTTPHeaderTable::insertRow(char *data)
00398 {
00399 CSString *header;
00400 String name;
00401 enter_();
00402
00403 getFieldValue(data, 0, &name);
00404
00405 header = CSString::newString(name.c_ptr_safe());
00406 myShare->mySysDatabase->iHTTPMetaDataHeaders.add(header);
00407 iDirty = true;
00408
00409 exit_();
00410 }
00411
00412 void MSHTTPHeaderTable::deleteRow(char *data)
00413 {
00414 CSString *header;
00415 String name;
00416 enter_();
00417
00418 getFieldValue(data, 0, &name);
00419
00420 header = CSString::newString(name.c_ptr_safe());
00421 push_(header);
00422 myShare->mySysDatabase->iHTTPMetaDataHeaders.remove(header);
00423 release_(header);
00424 iDirty = true;
00425
00426 exit_();
00427 }
00428
00429 void MSHTTPHeaderTable::updateRow(char *old_data, char *new_data)
00430 {
00431 enter_();
00432 insertRow(new_data);
00433 try_(a) {
00434 deleteRow(old_data);
00435 }
00436 catch_(a) {
00437 deleteRow(new_data);
00438 throw_();
00439 }
00440 cont_(a);
00441 exit_();
00442 }
00443