Drizzled Public API Documentation

system_table_ms.h
00001 /* Copyright (C) 2008 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  * Original author: Paul McCullagh
00020  * Continued development: Barry Leslie
00021  *
00022  * 2007-07-18
00023  *
00024  * H&G2JCtL
00025  *
00026  * System tables.
00027  *
00028  */
00029 
00030 /*
00031 
00032 DROP TABLE IF EXISTS pbms_repository;
00033 CREATE TABLE pbms_repository (
00034   Repository_id     INT COMMENT 'The reppository file number',
00035   Repo_blob_offset  BIGINT COMMENT 'The offset of the BLOB in the repository file',
00036   Blob_size         BIGINT COMMENT 'The size of the BLOB in bytes',
00037   Head_size         SMALLINT UNSIGNED COMMENT 'The size of the BLOB header - preceeds the BLOB data',
00038   Access_code       INT COMMENT 'The 4-byte authorisation code required to access the BLOB - part of the BLOB URL',
00039   Creation_time     TIMESTAMP COMMENT 'The time the BLOB was created',
00040   Last_ref_time     TIMESTAMP COMMENT 'The last time the BLOB was referenced',
00041   Last_access_time  TIMESTAMP COMMENT 'The last time the BLOB was accessed (read)',
00042   Content_type      CHAR(128) COMMENT 'The content type of the BLOB - returned by HTTP GET calls',
00043   Blob_data         LONGBLOB COMMENT 'The data of this BLOB'
00044 ) ENGINE=PBMS;
00045 
00046   PRIMARY KEY (Repository_id, Repo_blob_offset)
00047 
00048 DROP TABLE IF EXISTS pbms_reference;
00049 CREATE TABLE pbms_reference (
00050   Table_name        CHAR(64) COMMENT 'The name of the referencing table',
00051   Blob_id           BIGINT COMMENT 'The BLOB reference number - part of the BLOB URL',
00052   Column_name       CHAR(64) COMMENT 'The column name of the referencing field',
00053   Row_condition     VARCHAR(255) COMMENT 'This condition identifies the row in the table',
00054   Blob_url          VARCHAR(200) COMMENT 'The BLOB URL for HTTP GET access',
00055   Repository_id     INT COMMENT 'The repository file number of the BLOB',
00056   Repo_blob_offset  BIGINT COMMENT 'The offset in the repository file',
00057   Blob_size         BIGINT COMMENT 'The size of the BLOB in bytes',
00058   Deletion_time     TIMESTAMP COMMENT 'The time the BLOB was deleted',
00059   Remove_in         INT COMMENT 'The number of seconds before the reference/BLOB is removed perminently',
00060   Temp_log_id       INT COMMENT 'Temporary log number of the referencing deletion entry',
00061   Temp_log_offset   BIGINT COMMENT 'Temporary log offset of the referencing deletion entry'
00062 ) ENGINE=PBMS;
00063 
00064   PRIMARY KEY (Table_name, Blob_id, Column_name, Condition)
00065 */
00066 
00067 #pragma once
00068 #ifndef __SYSTEMTABLE_MS_H__
00069 #define __SYSTEMTABLE_MS_H__
00070 
00071 #include "cslib/CSMutex.h"
00072 
00073 #include "defs_ms.h"
00074 #include "repository_ms.h"
00075 #include "cloud_ms.h"
00076 
00077 #ifdef DRIZZLED
00078 using namespace drizzled;
00079 #else
00080 int pbms_discover_system_tables(handlerton *hton, THD* thd, const char *db, const char *name, uchar **frmblob, size_t *frmlen);
00081 #endif
00082 
00083 class PBMSSystemTables
00084 {
00085   public:
00086   
00087   #ifdef DRIZZLED
00088   static int getSystemTableInfo(const char *name, drizzled::message::Table &table);
00089   static void getSystemTableNames(bool isPBMS, std::set<std::string> &set_of_names);
00090   #endif
00091 
00092   static bool isSystemTable(bool isPBMS, const char *name);
00093 
00094   static void transferSystemTables(MSDatabase *dst_db, MSDatabase *src_db);
00095   static void loadSystemTables(MSDatabase *db);
00096   static void removeSystemTables(CSString *path);
00097 
00098   static CSStringBuffer *dumpSystemTables(MSDatabase *db);
00099   static void restoreSystemTables(MSDatabase *db, const char *data, size_t size);
00100 
00101   static void systemTablesStartUp();
00102   static void systemTableShutDown();
00103 
00104   private:
00105   static bool try_loadSystemTables(CSThread *self, int i, MSDatabase *db);
00106 };
00107 
00108 class MSSystemTableShare;
00109 class MSDatabase;
00110 class CSDaemon;
00111 class MSTempLogFile;
00112 
00113 #ifdef DRIZZLED
00114 #define GET_FIELD(table, column_index) table->getField(column_index)
00115 #define GET_TABLE_FIELDS(table) table->getFields()
00116 #else
00117 #define GET_FIELD(table, column_index) table->field[column_index]
00118 #define GET_TABLE_FIELDS(table) table->field
00119 #endif
00120 
00121 
00122 class MSOpenSystemTable : public CSRefObject {
00123 public:
00124   MSSystemTableShare    *myShare;
00125   TABLE         *mySQLTable;
00126 
00127   MSOpenSystemTable(MSSystemTableShare *share, TABLE *table);
00128   virtual ~MSOpenSystemTable();
00129 
00130   /*
00131    * The getFieldValue() methods access fields in a server record.
00132    * They assumes the caller knows what it is doing and does no error checking.
00133    */
00134   inline void getFieldValue(const char *row, uint16_t column_index, String *value)
00135   {
00136     Field *assumed_str_field = GET_FIELD(mySQLTable, column_index);
00137     unsigned char *old_ptr = assumed_str_field->ptr;
00138     
00139 
00140 #ifdef DRIZZLED
00141     assumed_str_field->ptr = (unsigned char *)row + assumed_str_field->offset(mySQLTable->getInsertRecord());
00142     assumed_str_field->setReadSet();
00143 #else
00144     assumed_str_field->ptr = (unsigned char *)row + assumed_str_field->offset(mySQLTable->record[0]);
00145     assumed_str_field->table->use_all_columns();
00146 #endif
00147     value = assumed_str_field->val_str_internal(value);
00148     
00149     assumed_str_field->ptr = old_ptr;
00150   }
00151 
00152   inline void getFieldValue(const char *row, uint16_t column_index, uint64_t *value)
00153   {
00154     Field *assumed_int_field = GET_FIELD(mySQLTable, column_index);
00155     unsigned char *old_ptr = assumed_int_field->ptr;
00156 
00157 
00158 #ifdef DRIZZLED
00159     assumed_int_field->ptr = (unsigned char *)row + assumed_int_field->offset(mySQLTable->getInsertRecord());
00160     assumed_int_field->setReadSet();
00161 #else
00162     assumed_int_field->ptr = (unsigned char *)row + assumed_int_field->offset(mySQLTable->record[0]);
00163     assumed_int_field->table->use_all_columns();
00164 #endif
00165     *value = assumed_int_field->val_int();
00166     
00167     assumed_int_field->ptr = old_ptr;
00168   }
00169 
00170   inline void getFieldValue(const char *row, uint16_t column_index, uint32_t *value)
00171   {
00172     uint64_t v64;
00173     getFieldValue(row, column_index, &v64);
00174     *value = (uint32_t) v64;
00175   }
00176 
00177   virtual void use() { }
00178   virtual void unuse() { }
00179   virtual void backupSeqScanInit() { }
00180   virtual void seqScanInit() { }
00181   virtual bool seqScanNext(char *buf) { UNUSED(buf); return false; }
00182   virtual int getRefLen() { return 0; }
00183   virtual void seqScanPos(unsigned char *pos) { UNUSED(pos);}
00184   virtual void seqScanRead(unsigned char *pos , char *buf) {UNUSED(pos);UNUSED(buf); }
00185   virtual void insertRow(char *buf) {UNUSED(buf); }
00186   virtual void deleteRow(char *buf) {UNUSED(buf);  }
00187   virtual void updateRow(char *old_data, char *new_data) {UNUSED(old_data);UNUSED(new_data); }
00188 /*  
00189   virtual void index_init(uint8_t idx) { }
00190   virtual void index_end() { }
00191   virtual bool index_read(char *buf, const char *key,
00192                  uint key_len, enum ha_rkey_function find_flag){ return false;}
00193   virtual bool index_read_idx(char *buf, uint idx, const char *key,
00194                      uint key_len, enum ha_rkey_function find_flag){ return false;}
00195   virtual bool index_next(char *buf){ return false;}
00196   virtual bool index_prev(char *buf){ return false;}
00197   virtual bool index_first(char *buf){ return false;}
00198   virtual bool index_last(char *buf){ return false;}
00199   virtual bool index_read_last(char *buf, const char *key, uint key_len){ return false;}
00200 */
00201   
00202   static void setNotNullInRecord(Field *field, char *record);
00203   static void setNullInRecord(Field *field, char *record);
00204 
00205 private:
00206 };
00207 
00208 typedef struct MSRefData {
00209   uint32_t        rd_ref_count;
00210   uint32_t        rd_tab_id;
00211   uint64_t        rd_blob_id;
00212   uint64_t        rd_blob_ref_id;
00213   uint32_t        rd_temp_log_id;
00214   uint32_t        rd_temp_log_offset;
00215   uint16_t        rd_col_index;
00216 } MSRefDataRec, *MSRefDataPtr;
00217 
00218 class MSRepositoryTable : public MSOpenSystemTable {
00219 public:
00220   MSRepositoryTable(MSSystemTableShare *share, TABLE *table);
00221   virtual ~MSRepositoryTable();
00222 
00223   virtual void use();
00224   virtual void unuse();
00225   virtual void seqScanInit();
00226   virtual bool seqScanNext(char *buf);
00227   virtual int getRefLen();
00228   virtual void seqScanPos(unsigned char *pos);
00229   virtual void seqScanRead(uint32_t repo, uint64_t offset, char *buf);
00230   virtual void seqScanRead(unsigned char *pos, char *buf);
00231 
00232   friend class MSReferenceTable;
00233   friend class MSBlobDataTable;
00234   friend class MSMetaDataTable;
00235   friend class MSBlobAliasTable;
00236   friend class MSDumpTable;
00237 
00238 private:
00239   uint32_t      iRepoIndex;
00240   uint64_t      iRepoCurrentOffset;
00241   uint64_t      iRepoOffset;
00242   uint64_t      iRepoFileSize;
00243   CSDaemon    *iCompactor;
00244   MSRepoFile    *iRepoFile;
00245   CSStringBuffer  *iBlobBuffer;
00246 
00247   virtual bool returnRecord(char *buf);
00248   virtual bool returnSubRecord(char *buf);
00249   virtual bool returnRow(MSBlobHeadPtr blob, char *buf);
00250   virtual bool resetScan(bool positioned, uint32_t iRepoIndex = 0);
00251 };
00252 
00253 class MSBlobDataTable : public MSRepositoryTable {
00254 public:
00255   MSBlobDataTable(MSSystemTableShare *share, TABLE *table);
00256   ~MSBlobDataTable();
00257   
00258 private:
00259   virtual bool returnRow(MSBlobHeadPtr blob, char *buf);
00260 };
00261 
00262 // The main purpose of this class if for internal use when
00263 // building the alias index.
00264 class MSBlobAliasTable : public MSRepositoryTable {
00265 public:
00266   MSBlobAliasTable(MSSystemTableShare *share, TABLE *table):MSRepositoryTable(share, table){} 
00267 private:
00268   
00269   virtual bool returnRow(MSBlobHeadPtr blob, char *buf);
00270 };
00271 
00272 
00273 class MSReferenceTable : public MSRepositoryTable {
00274 public:
00275   MSReferenceTable(MSSystemTableShare *share, TABLE *table);
00276   virtual ~MSReferenceTable();
00277 
00278   void unuse();
00279   void seqScanInit();
00280   int getRefLen();
00281   void seqScanPos(unsigned char *pos);
00282   virtual void seqScanRead(uint32_t repo, uint64_t offset, char *buf) { return MSRepositoryTable::seqScanRead(repo, offset, buf);}
00283   void seqScanRead(unsigned char *pos, char *buf);
00284   bool seqScanNext(char *buf);
00285 
00286 private:
00287   MSRefDataPtr  iRefDataList;
00288   /* 
00289    * I need my own copy of the current repository index and offset
00290    * to ensure it referess to the same blob as the reference data position.
00291   */
00292   uint32_t      iRefCurrentIndex;   
00293   uint64_t      iRefCurrentOffset;    
00294   uint32_t      iRefCurrentDataUsed;
00295   uint32_t      iRefCurrentDataPos;
00296   uint32_t      iRefDataSize;
00297   uint32_t      iRefDataUsed;
00298   uint32_t      iRefDataPos;
00299   uint32_t      iRefAuthCode;
00300   uint64_t      iRefBlobSize;
00301   uint32_t      iRefBlobRepo;
00302   uint64_t      iRefBlobOffset;
00303   MSOpenTable   *iRefOpenTable;
00304   MSTempLogFile *iRefTempLog;
00305 
00306   virtual bool returnRecord(char *buf);
00307   virtual bool returnSubRecord(char *buf);
00308   virtual bool returnRow(MSBlobHeadPtr blob, char *buf) { return MSRepositoryTable::returnRow(blob, buf);}
00309   virtual void returnRow(MSRefDataPtr ref_data, char *buf);
00310   virtual bool resetScan(bool positioned, uint32_t iRepoIndex = 0);
00311 };
00312 
00313 class MSMetaDataTable : public MSRepositoryTable {
00314 public:
00315   MSMetaDataTable(MSSystemTableShare *share, TABLE *table);
00316   virtual ~MSMetaDataTable();
00317 
00318   void use();
00319   void unuse();
00320   void seqScanInit();
00321   int getRefLen();
00322   void seqScanPos(unsigned char *pos);
00323   virtual void seqScanRead(uint32_t repo, uint64_t offset, char *buf) { return MSRepositoryTable::seqScanRead(repo, offset, buf);}
00324   void seqScanRead(unsigned char *pos, char *buf);
00325   bool seqScanNext(char *buf);
00326   void insertRow(char *buf);
00327   void deleteRow(char *buf);
00328   void updateRow(char *old_data, char *new_data);
00329 
00330 #ifdef HAVE_ALIAS_SUPPORT
00331   bool matchAlias(uint32_t repo_id, uint64_t offset, const char *alias);
00332 #endif
00333 
00334   friend class MSSysMeta;
00335 
00336 private:
00337   CSStringBuffer  *iMetData;
00338   uint32_t    iMetCurrentBlobRepo;    
00339   uint64_t    iMetCurrentBlobOffset;    
00340   uint32_t      iMetCurrentDataPos;
00341   uint32_t      iMetCurrentDataSize;
00342   uint32_t      iMetDataPos;
00343   uint32_t      iMetDataSize;
00344   uint32_t    iMetBlobRepo;
00345   uint64_t    iMetBlobOffset;
00346   uint8_t     iMetState[20];
00347   bool      iMetStateSaved;
00348   
00349   bool nextRecord(char **name, char **value);
00350   void seqScanReset();
00351   
00352   virtual bool returnRecord(char *buf);
00353   virtual bool returnSubRecord(char *buf);
00354   virtual bool returnRow(MSBlobHeadPtr blob, char *buf) { return MSRepositoryTable::returnRow(blob, buf);}
00355   virtual void returnRow(char *name, char *value, char *buf);
00356   virtual bool resetScan(bool positioned, uint32_t index = 0) {bool have_data= false; return resetScan(positioned, &have_data, index);}
00357   virtual bool resetScan(bool positioned, bool *have_data, uint32_t iRepoIndex = 0);
00358   
00359   static MSMetaDataTable *newMSMetaDataTable(MSDatabase *db);
00360 };
00361 
00362 class MSSystemTableShare : public CSRefObject {
00363 public:
00364   CSString        *myTablePath;
00365   THR_LOCK        myThrLock;
00366   MSDatabase        *mySysDatabase;
00367 
00368   MSSystemTableShare();
00369   ~MSSystemTableShare();
00370 
00371   /* Make this object sortable: */
00372   virtual CSObject *getKey();
00373   virtual int compareKey(CSObject *);
00374 
00375 private:
00376   uint32_t          iOpenCount;
00377 
00378 public:
00379   static CSSyncSortedList *gSystemTableList;
00380 
00381   // Close all open system tables for the database being dropped.
00382   static void removeDatabaseSystemTables(MSDatabase *doomed_db); 
00383   static void startUp();
00384   static void shutDown();
00385 
00386   static MSOpenSystemTable *openSystemTable(const char *table_path, TABLE *table);
00387   static void releaseSystemTable(MSOpenSystemTable *tab);
00388 
00389   static MSSystemTableShare *newTableShare(CSString *table_path);
00390 };
00391 
00392 #endif