Drizzled Public API Documentation

cloud_ms.h
00001 #pragma once
00002 #ifndef __CLOUD_H__
00003 #define __CLOUD_H__
00004 /* Copyright (C) 2009 PrimeBase Technologies GmbH, Germany
00005  *
00006  * PrimeBase Media Stream for MySQL
00007  *
00008  * This program is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * This program is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
00021  *
00022  *  Created by Barry Leslie on 3/20/09.
00023  *
00024  */
00025 #include "cslib/CSMd5.h"
00026 #include <inttypes.h>
00027 
00028 
00029 /* NOTES:
00030  *
00031  * - TODO: If cl_deleteData() fails then the BLOB deletion must fail and be rescheduled to try again
00032  *      later.
00033  * - TODO: Copying of BLOBs from one database to another needs to be handled. Look for copyBlob() and 
00034  *      resetBlobHead(). There are 3 cases to handle depending on if the databases involved use
00035  *      cload storage.
00036  */
00037  
00038 //===============================
00039 class CSS3Protocol; 
00040 class MSCloudInfo : public CSRefObject {
00041   private:
00042   static uint32_t gMaxInfoRef;
00043   static CSSyncSparseArray *gCloudInfo;
00044 
00045   friend class MSCloudTable;
00046   friend class CloudDB;
00047   
00048   private:  
00049   uint32_t      cloudRefId;
00050   CSString    *bucket;
00051   CSS3Protocol  *s3Prot;
00052   
00053 public:
00054 
00055   static void startUp()
00056   {
00057     new_(gCloudInfo, CSSyncSparseArray(5));
00058     gMaxInfoRef = 0;
00059   }
00060   
00061   static void shutDown()
00062   {
00063     if (gCloudInfo) {
00064       gCloudInfo->clear();
00065       gCloudInfo->release();
00066       gCloudInfo = NULL;
00067     } 
00068   }
00069 
00070 
00071   static MSCloudInfo *getCloudInfo(uint32_t in_cloudRefId)
00072   {
00073     MSCloudInfo *info;
00074     enter_();
00075     
00076     lock_(gCloudInfo);
00077     
00078     info = (MSCloudInfo *) gCloudInfo->get(in_cloudRefId);
00079     if (!info) {
00080       char msg[80];
00081       snprintf(msg, 80, "Cloud info with reference ID %"PRIu32" not found", in_cloudRefId);
00082       CSException::throwException(CS_CONTEXT, CS_ERR_GENERIC_ERROR, msg);
00083     }
00084     info->retain();
00085     unlock_(gCloudInfo);
00086     return_(info);
00087   }
00088   
00089   MSCloudInfo(uint32_t id, const char *server, const char *bucket, const char *publicKey, const char *privateKey );
00090   ~MSCloudInfo();
00091   
00092   uint32_t getCloudRefId() { return cloudRefId;}
00093   
00094   const char *getServer();
00095   
00096   const char *getBucket();
00097   
00098   const char *getPublicKey();
00099   
00100   const char *getPrivateKey();
00101 
00102   CSString *getSignature(const char *key, const char *content_type, uint32_t *s3AuthorizationTime);
00103   
00104   CSString *getDataURL(const char *key, int keep_alive);
00105 
00106   void send(CSInputStream *input, const char *key, off64_t size);
00107   
00108   void receive(CSOutputStream *output, const char *key);
00109   
00110   void copy(MSCloudInfo *dst_cloud, const char *dst_key, const char *src_key);
00111 
00112   void cDelete(const char *key);
00113   
00114   CSVector *list(const char *key_prefix, uint32_t max = 0);
00115 };
00116 
00117 typedef struct CloudKey {
00118   uint32_t creation_time;
00119   uint32_t ref_index;   // Just a sequence counter in case 2 blobs have the same creation time.
00120   uint32_t cloud_ref;   // A reference into the pbms.pbms_cloud table.
00121 } CloudKeyRec, *CloudKeyPtr;
00122 
00123 
00124 //===============================
00125 class CloudObjectKey : public CSStringBuffer
00126 {
00127   uint32_t default_db_id;
00128   
00129   public:
00130   CloudObjectKey(uint32_t id): CSStringBuffer(), default_db_id(id){ }
00131   ~CloudObjectKey(){}
00132   
00133   static const uint32_t base_key_size = 64; // enough space for <db_id>/<backup_id>/<creation_time>/<ref_index>
00134 
00135   void setObjectKey(const char *object_key)
00136   {
00137     setLength(base_key_size + strlen(object_key) +1);
00138     
00139     snprintf(getBuffer(0), length(), "%"PRIu32"/0/%s",default_db_id,  object_key);
00140   }
00141   
00142   void setObjectKey(CloudKeyPtr key = NULL, uint32_t backup_id = 0, uint32_t db_id = 0)
00143   {
00144     if (!db_id) db_id = default_db_id;
00145     setLength(base_key_size);
00146     
00147     if (key)
00148       snprintf(getBuffer(0), length(), "%"PRIu32"/%"PRIu32"/%"PRIu32".%"PRIu32".%"PRIu32"", db_id, backup_id, key->cloud_ref, key->creation_time, key->ref_index);
00149     else 
00150       snprintf(getBuffer(0), length(), "%"PRIu32"/%"PRIu32"s/", db_id, backup_id);
00151       
00152   }
00153   
00154   static void parseObjectKey(const char *object_key, CloudKeyPtr key, uint32_t *backup_id = NULL, uint32_t *db_id = NULL)
00155   {
00156     uint32_t v1;
00157     
00158     if (!backup_id) backup_id = &v1;
00159     if (!db_id) db_id = &v1;
00160     
00161     sscanf(object_key, "%"PRIu32"/%"PRIu32"/%"PRIu32".%"PRIu32".%"PRIu32"", db_id, backup_id, &(key->cloud_ref), &(key->creation_time), &(key->ref_index));
00162   }
00163 };
00164 
00165 //===============================
00166 class MSBackupInfo;
00167 class CloudDB: public CSRefObject {
00168   
00169 private:
00170   static uint32_t gKeyIndex;
00171   static CSMutex  gCloudKeyLock;
00172   
00173   uint32_t  dfltCloudRefId;
00174   
00175   uint32_t  keep_alive; // The length of time a redirect URL will remain valid. In seconds.
00176   uint32_t  blob_recovery_no; // This is the backup number from which the recovery should be done.
00177   uint32_t  blob_db_id;
00178   
00179   bool isBackup;
00180   MSBackupInfo *backupInfo;
00181   MSCloudInfo *backupCloud;
00182   
00183   static const uint32_t base_key_size = 64; // enough space for <db_id>/<backup_id>/<creation_time>/<ref_index>
00184 
00185 public:
00186   CSStringBuffer    *clObjectKey;
00187   
00188   CloudDB(uint32_t db_id);
00189   ~CloudDB();
00190   
00191   void cl_setDefaultCloudRef(uint32_t dflt) { dfltCloudRefId = dflt;}
00192   uint32_t cl_getDefaultCloudRef() { return dfltCloudRefId;}
00193 
00194   MSCloudInfo *cl_getCloudInfo(uint32_t cloudRefId = 0)
00195   {
00196     return MSCloudInfo::getCloudInfo((cloudRefId)?cloudRefId:dfltCloudRefId);
00197   }
00198   
00199   void cl_getNewKey(CloudKeyPtr key)
00200   {
00201     enter_();
00202     lock_(&gCloudKeyLock);  
00203     
00204     key->creation_time = time(NULL);
00205     key->ref_index = gKeyIndex++;
00206     key->cloud_ref = dfltCloudRefId;
00207     
00208     unlock_(&gCloudKeyLock);  
00209     exit_();
00210   }
00211 
00212   bool cl_mustRecoverBlobs() { return (blob_recovery_no != 0);}
00213   
00214   void cl_setRecoveryNumber(const char *number)
00215   {
00216     blob_recovery_no = atol(number);
00217   }
00218 
00219   const char *cl_getRecoveryNumber()
00220   {
00221     static char number[20];
00222     
00223     snprintf(number, 20, "%"PRIu32"", blob_recovery_no);
00224     return number;
00225   }
00226 
00227   CSString *cl_getObjectKey(CloudKeyPtr key)
00228   {
00229     CloudObjectKey *objectKey;
00230     enter_();
00231     
00232     new_(objectKey, CloudObjectKey(blob_db_id));
00233     push_(objectKey);
00234     
00235     objectKey->setObjectKey(key);
00236     
00237     CSString *str = CSString::newString(objectKey->getCString());
00238     release_(objectKey);
00239     
00240     return_(str);
00241   }
00242   
00243   void cl_setKeepAlive(uint32_t keep_alive_arg) {keep_alive = keep_alive_arg;}
00244   
00245   void cl_createDB();
00246   void cl_dropDB();
00247   void cl_restoreDB();
00248   uint32_t cl_getNextBackupNumber(uint32_t cloud_ref = 0);
00249   bool cl_dbExists();
00250   
00251   // setting backup_blob_no to -1 ensures that if the database is dropped no BLOBs will be deleted.
00252   void cl_setCloudIsBackup(){ isBackup = true;}
00253   void cl_setBackupInfo(MSBackupInfo *info){ backupInfo = info;}
00254   MSBackupInfo *cl_getBackupInfo();
00255   void cl_clearBackupInfo();
00256   
00257   void cl_backupBLOB(CloudKeyPtr key);
00258   void cl_restoreBLOB(CloudKeyPtr key, uint32_t backup_db_id);
00259 
00260   void cl_putData( CloudKeyPtr key, CSInputStream *stream, off64_t size);
00261   off64_t cl_getData(CloudKeyPtr key, char *data, off64_t size);
00262   CSString *cl_getDataURL(CloudKeyPtr key);
00263   void cl_deleteData(CloudKeyPtr key);
00264   CSString *cl_getSignature(CloudKeyPtr key, CSString *content_type, uint32_t *s3AuthorizationTime);
00265   
00266 };
00267 
00268 #endif // __CLOUD_H__