Drizzled Public API Documentation

systab_httpheader_ms.cc
00001 /* Copyright (C) 2009 PrimeBase Technologies GmbH, Germany
00002  *
00003  * PrimeBase Media Stream for MySQL
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
00018  *
00019  * Barry Leslie
00020  *
00021  * System variables table.
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 //#include "mysql_priv.h"
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 //#include <plugin.h>
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  * HTTP HEADER TABLE
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) { // Load the defaults if they exist.
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   // Build the table records
00176   headerData->clear();
00177   lock_(&db->iHTTPMetaDataHeaders);
00178   
00179   // Note: the object returned by itemAt() is not returnd referenced.
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   //unuse();
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; // This is probably an error condition.
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