~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/pbms/src/cloud.h

Added the PBMS daemon plugin.

(Augen zu und durch!)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#ifndef __CLOUD_H__
 
2
#define __CLOUD_H__
 
3
/* Copyright (c) 2009 PrimeBase Technologies GmbH, Germany
 
4
 *
 
5
 * PrimeBase Media Stream for MySQL
 
6
 *
 
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.
 
11
 *
 
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.
 
16
 *
 
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
 
20
 *
 
21
 *  Created by Barry Leslie on 3/20/09.
 
22
 *
 
23
 */
 
24
#include <inttypes.h>
 
25
#include "CSMd5.h"
 
26
 
 
27
 
 
28
/* NOTES:
 
29
 *
 
30
 * - TODO: If cl_deleteData() fails then the BLOB deletion must fail and be rescheduled to try again
 
31
 *                      later.
 
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
 
34
 *                      cload storage.
 
35
 */
 
36
 
 
37
//===============================
 
38
class CSS3Protocol;     
 
39
class MSCloudInfo : public CSRefObject {
 
40
        private:
 
41
        static uint32_t gMaxInfoRef;
 
42
        static CSSyncSparseArray *gCloudInfo;
 
43
 
 
44
        friend class MSCloudTable;
 
45
        friend class CloudDB;
 
46
        
 
47
        private:        
 
48
        uint32_t                        cloudRefId;
 
49
        CSString                *bucket;
 
50
        CSS3Protocol    *s3Prot;
 
51
        
 
52
public:
 
53
 
 
54
        static void startUp()
 
55
        {
 
56
                new_(gCloudInfo, CSSyncSparseArray(5));
 
57
                gMaxInfoRef = 0;
 
58
        }
 
59
        
 
60
        static void shutDown()
 
61
        {
 
62
                if (gCloudInfo) {
 
63
                        gCloudInfo->clear();
 
64
                        gCloudInfo->release();
 
65
                        gCloudInfo = NULL;
 
66
                }       
 
67
        }
 
68
 
 
69
 
 
70
        static MSCloudInfo *getCloudInfo(uint32_t cloudRefId)
 
71
        {
 
72
                MSCloudInfo *info;
 
73
                enter_();
 
74
                
 
75
                lock_(gCloudInfo);
 
76
                
 
77
                info = (MSCloudInfo *) gCloudInfo->get(cloudRefId);
 
78
                if (!info) {
 
79
                        char msg[80];
 
80
                        snprintf(msg, 80, "Cloud info with reference ID %"PRIu32" not found", cloudRefId);
 
81
                        CSException::throwException(CS_CONTEXT, CS_ERR_GENERIC_ERROR, msg);
 
82
                }
 
83
                info->retain();
 
84
                unlock_(gCloudInfo);
 
85
                return_(info);
 
86
        }
 
87
        
 
88
        MSCloudInfo(uint32_t id, const char *server, const char *bucket, const char *publicKey, const char *privateKey );
 
89
        ~MSCloudInfo();
 
90
        
 
91
        uint32_t getCloudRefId() { return cloudRefId;}
 
92
        
 
93
        const char *getServer();
 
94
        
 
95
        const char *getBucket();
 
96
        
 
97
        const char *getPublicKey();
 
98
        
 
99
        const char *getPrivateKey();
 
100
 
 
101
        CSString *getSignature(const char *key, const char *content_type, uint32_t *s3AuthorizationTime);
 
102
        
 
103
        CSString *getDataURL(const char *key, int keep_alive);
 
104
 
 
105
        void send(CSInputStream *input, const char *key, off_t size);
 
106
        
 
107
        void receive(CSOutputStream *output, const char *key);
 
108
        
 
109
        void copy(MSCloudInfo *dst_cloud, const char *dst_key, const char *src_key);
 
110
 
 
111
        void cDelete(const char *key);
 
112
        
 
113
        CSVector *list(const char *key_prefix, uint32_t max = 0);
 
114
};
 
115
 
 
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;
 
121
 
 
122
 
 
123
//===============================
 
124
class CloudObjectKey : public CSStringBuffer
 
125
{
 
126
        uint32_t default_db_id;
 
127
        
 
128
        public:
 
129
        CloudObjectKey(uint32_t id): CSStringBuffer(), default_db_id(id){ }
 
130
        ~CloudObjectKey(){}
 
131
        
 
132
        static const uint32_t base_key_size = 64; // enough space for <db_id>/<backup_id>/<creation_time>/<ref_index>
 
133
 
 
134
        void setObjectKey(const char *object_key)
 
135
        {
 
136
                setLength(base_key_size + strlen(object_key) +1);
 
137
                
 
138
                snprintf(getBuffer(0), length(), "%"PRIu32"/0/%s",default_db_id,  object_key);
 
139
        }
 
140
        
 
141
        void setObjectKey(CloudKeyPtr key = NULL, uint32_t backup_id = 0, uint32_t db_id = 0)
 
142
        {
 
143
                if (!db_id) db_id = default_db_id;
 
144
                setLength(base_key_size);
 
145
                
 
146
                if (key)
 
147
                        snprintf(getBuffer(0), length(), "%"PRIu32"/%"PRIu32"/%"PRIu32".%"PRIu32".%"PRIu32"", db_id, backup_id, key->cloud_ref, key->creation_time, key->ref_index);
 
148
                else 
 
149
                        snprintf(getBuffer(0), length(), "%"PRIu32"/%"PRIu32"s/", db_id, backup_id);
 
150
                        
 
151
        }
 
152
        
 
153
        static void parseObjectKey(const char *object_key, CloudKeyPtr key, uint32_t *backup_id = NULL, uint32_t *db_id = NULL)
 
154
        {
 
155
                uint32_t v1;
 
156
                
 
157
                if (!backup_id) backup_id = &v1;
 
158
                if (!db_id) db_id = &v1;
 
159
                
 
160
                sscanf(object_key, "%"PRIu32"/%"PRIu32"/%"PRIu32".%"PRIu32".%"PRIu32"", db_id, backup_id, &(key->cloud_ref), &(key->creation_time), &(key->ref_index));
 
161
        }
 
162
};
 
163
 
 
164
//===============================
 
165
class MSBackupInfo;
 
166
class CloudDB: public CSRefObject {
 
167
        
 
168
private:
 
169
        static uint32_t gKeyIndex;
 
170
        static CSMutex  gCloudKeyLock;
 
171
        
 
172
        uint32_t        dfltCloudRefId;
 
173
        
 
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.
 
176
        uint32_t        blob_db_id;
 
177
        
 
178
        bool isBackup;
 
179
        MSBackupInfo *backupInfo;
 
180
        MSCloudInfo     *backupCloud;
 
181
        
 
182
        static const uint32_t base_key_size = 64; // enough space for <db_id>/<backup_id>/<creation_time>/<ref_index>
 
183
 
 
184
public:
 
185
        CSStringBuffer          *clObjectKey;
 
186
        
 
187
        CloudDB(uint32_t db_id);
 
188
        ~CloudDB();
 
189
        
 
190
        void cl_setDefaultCloudRef(uint32_t dflt) { dfltCloudRefId = dflt;}
 
191
        uint32_t cl_getDefaultCloudRef() { return dfltCloudRefId;}
 
192
 
 
193
        MSCloudInfo *cl_getCloudInfo(uint32_t cloudRefId = 0)
 
194
        {
 
195
                return MSCloudInfo::getCloudInfo((cloudRefId)?cloudRefId:dfltCloudRefId);
 
196
        }
 
197
        
 
198
        void cl_getNewKey(CloudKeyPtr key)
 
199
        {
 
200
                enter_();
 
201
                lock_(&gCloudKeyLock);  
 
202
                
 
203
                key->creation_time = time(NULL);
 
204
                key->ref_index = gKeyIndex++;
 
205
                key->cloud_ref = dfltCloudRefId;
 
206
                
 
207
                unlock_(&gCloudKeyLock);        
 
208
                exit_();
 
209
        }
 
210
 
 
211
        bool cl_mustRecoverBlobs() { return (blob_recovery_no != 0);}
 
212
        
 
213
        void cl_setRecoveryNumber(const char *number)
 
214
        {
 
215
                blob_recovery_no = atol(number);
 
216
        }
 
217
 
 
218
        const char *cl_getRecoveryNumber()
 
219
        {
 
220
                static char number[20];
 
221
                
 
222
                snprintf(number, 20, "%"PRIu32"", blob_recovery_no);
 
223
                return number;
 
224
        }
 
225
 
 
226
        CSString *cl_getObjectKey(CloudKeyPtr key)
 
227
        {
 
228
                CloudObjectKey *objectKey;
 
229
                enter_();
 
230
                
 
231
                new_(objectKey, CloudObjectKey(blob_db_id));
 
232
                push_(objectKey);
 
233
                
 
234
                objectKey->setObjectKey(key);
 
235
                
 
236
                CSString *str = CSString::newString(objectKey->getCString());
 
237
                release_(objectKey);
 
238
                
 
239
                return_(str);
 
240
        }
 
241
        
 
242
        void cl_setKeepAlive(uint32_t keep_alive_arg) {keep_alive = keep_alive_arg;}
 
243
        
 
244
        void cl_createDB();
 
245
        void cl_dropDB();
 
246
        void cl_restoreDB();
 
247
        uint32_t cl_getNextBackupNumber(uint32_t cloud_ref = 0);
 
248
        bool cl_dbExists();
 
249
        
 
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();
 
255
        
 
256
        void cl_backupBLOB(CloudKeyPtr key);
 
257
        void cl_restoreBLOB(CloudKeyPtr key, uint32_t backup_db_id);
 
258
 
 
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);
 
264
        
 
265
};
 
266
 
 
267
#endif // __CLOUD_H__