3
/* Copyright (c) 2009 PrimeBase Technologies GmbH, Germany
5
* PrimeBase Media Stream for MySQL
7
* This program is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation; either version 2 of the License, or
10
* (at your option) any later version.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with this program; if not, write to the Free Software
19
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
* Created by Barry Leslie on 3/20/09.
30
* - TODO: If cl_deleteData() fails then the BLOB deletion must fail and be rescheduled to try again
32
* - TODO: Copying of BLOBs from one database to another needs to be handled. Look for copyBlob() and
33
* resetBlobHead(). There are 3 cases to handle depending on if the databases involved use
37
//===============================
39
class MSCloudInfo : public CSRefObject {
41
static uint32_t gMaxInfoRef;
42
static CSSyncSparseArray *gCloudInfo;
44
friend class MSCloudTable;
56
new_(gCloudInfo, CSSyncSparseArray(5));
60
static void shutDown()
64
gCloudInfo->release();
70
static MSCloudInfo *getCloudInfo(uint32_t cloudRefId)
77
info = (MSCloudInfo *) gCloudInfo->get(cloudRefId);
80
snprintf(msg, 80, "Cloud info with reference ID %"PRIu32" not found", cloudRefId);
81
CSException::throwException(CS_CONTEXT, CS_ERR_GENERIC_ERROR, msg);
88
MSCloudInfo(uint32_t id, const char *server, const char *bucket, const char *publicKey, const char *privateKey );
91
uint32_t getCloudRefId() { return cloudRefId;}
93
const char *getServer();
95
const char *getBucket();
97
const char *getPublicKey();
99
const char *getPrivateKey();
101
CSString *getSignature(const char *key, const char *content_type, uint32_t *s3AuthorizationTime);
103
CSString *getDataURL(const char *key, int keep_alive);
105
void send(CSInputStream *input, const char *key, off_t size);
107
void receive(CSOutputStream *output, const char *key);
109
void copy(MSCloudInfo *dst_cloud, const char *dst_key, const char *src_key);
111
void cDelete(const char *key);
113
CSVector *list(const char *key_prefix, uint32_t max = 0);
116
typedef struct CloudKey {
117
uint32_t creation_time;
118
uint32_t ref_index; // Just a sequence counter in case 2 blobs have the same creation time.
119
uint32_t cloud_ref; // A reference into the pbms.pbms_cloud table.
120
} CloudKeyRec, *CloudKeyPtr;
123
//===============================
124
class CloudObjectKey : public CSStringBuffer
126
uint32_t default_db_id;
129
CloudObjectKey(uint32_t id): CSStringBuffer(), default_db_id(id){ }
132
static const uint32_t base_key_size = 64; // enough space for <db_id>/<backup_id>/<creation_time>/<ref_index>
134
void setObjectKey(const char *object_key)
136
setLength(base_key_size + strlen(object_key) +1);
138
snprintf(getBuffer(0), length(), "%"PRIu32"/0/%s",default_db_id, object_key);
141
void setObjectKey(CloudKeyPtr key = NULL, uint32_t backup_id = 0, uint32_t db_id = 0)
143
if (!db_id) db_id = default_db_id;
144
setLength(base_key_size);
147
snprintf(getBuffer(0), length(), "%"PRIu32"/%"PRIu32"/%"PRIu32".%"PRIu32".%"PRIu32"", db_id, backup_id, key->cloud_ref, key->creation_time, key->ref_index);
149
snprintf(getBuffer(0), length(), "%"PRIu32"/%"PRIu32"s/", db_id, backup_id);
153
static void parseObjectKey(const char *object_key, CloudKeyPtr key, uint32_t *backup_id = NULL, uint32_t *db_id = NULL)
157
if (!backup_id) backup_id = &v1;
158
if (!db_id) db_id = &v1;
160
sscanf(object_key, "%"PRIu32"/%"PRIu32"/%"PRIu32".%"PRIu32".%"PRIu32"", db_id, backup_id, &(key->cloud_ref), &(key->creation_time), &(key->ref_index));
164
//===============================
166
class CloudDB: public CSRefObject {
169
static uint32_t gKeyIndex;
170
static CSMutex gCloudKeyLock;
172
uint32_t dfltCloudRefId;
174
uint32_t keep_alive; // The length of time a redirect URL will remain valid. In seconds.
175
uint32_t blob_recovery_no; // This is the backup number from which the recovery should be done.
179
MSBackupInfo *backupInfo;
180
MSCloudInfo *backupCloud;
182
static const uint32_t base_key_size = 64; // enough space for <db_id>/<backup_id>/<creation_time>/<ref_index>
185
CSStringBuffer *clObjectKey;
187
CloudDB(uint32_t db_id);
190
void cl_setDefaultCloudRef(uint32_t dflt) { dfltCloudRefId = dflt;}
191
uint32_t cl_getDefaultCloudRef() { return dfltCloudRefId;}
193
MSCloudInfo *cl_getCloudInfo(uint32_t cloudRefId = 0)
195
return MSCloudInfo::getCloudInfo((cloudRefId)?cloudRefId:dfltCloudRefId);
198
void cl_getNewKey(CloudKeyPtr key)
201
lock_(&gCloudKeyLock);
203
key->creation_time = time(NULL);
204
key->ref_index = gKeyIndex++;
205
key->cloud_ref = dfltCloudRefId;
207
unlock_(&gCloudKeyLock);
211
bool cl_mustRecoverBlobs() { return (blob_recovery_no != 0);}
213
void cl_setRecoveryNumber(const char *number)
215
blob_recovery_no = atol(number);
218
const char *cl_getRecoveryNumber()
220
static char number[20];
222
snprintf(number, 20, "%"PRIu32"", blob_recovery_no);
226
CSString *cl_getObjectKey(CloudKeyPtr key)
228
CloudObjectKey *objectKey;
231
new_(objectKey, CloudObjectKey(blob_db_id));
234
objectKey->setObjectKey(key);
236
CSString *str = CSString::newString(objectKey->getCString());
242
void cl_setKeepAlive(uint32_t keep_alive_arg) {keep_alive = keep_alive_arg;}
247
uint32_t cl_getNextBackupNumber(uint32_t cloud_ref = 0);
250
// setting backup_blob_no to -1 ensures that if the database is dropped no BLOBs will be deleted.
251
void cl_setCloudIsBackup(){ isBackup = true;}
252
void cl_setBackupInfo(MSBackupInfo *info){ backupInfo = info;}
253
MSBackupInfo *cl_getBackupInfo();
254
void cl_clearBackupInfo();
256
void cl_backupBLOB(CloudKeyPtr key);
257
void cl_restoreBLOB(CloudKeyPtr key, uint32_t backup_db_id);
259
void cl_putData( CloudKeyPtr key, CSInputStream *stream, off_t size);
260
off_t cl_getData(CloudKeyPtr key, char *data, off_t size);
261
CSString *cl_getDataURL(CloudKeyPtr key);
262
void cl_deleteData(CloudKeyPtr key);
263
CSString *cl_getSignature(CloudKeyPtr key, CSString *content_type, uint32_t *s3AuthorizationTime);
267
#endif // __CLOUD_H__