~ubuntu-branches/ubuntu/trusty/drizzle/trusty

« back to all changes in this revision

Viewing changes to plugin/pbms/src/systab_dump_ms.cc

  • Committer: Bazaar Package Importer
  • Author(s): Monty Taylor
  • Date: 2010-10-02 14:17:48 UTC
  • mfrom: (1.1.1 upstream)
  • mto: (2.1.17 sid)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20101002141748-m6vbfbfjhrw1153e
Tags: 2010.09.1802-1
* New upstream release.
* Removed pid-file argument hack.
* Updated GPL-2 address to be new address.
* Directly copy in drizzledump.1 since debian doesn't have sphinx 1.0 yet.
* Link to jquery from libjs-jquery. Add it as a depend.
* Add drizzled.8 symlink to the install files.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 2009 PrimeBase Technologies GmbH, Germany
 
2
 *
 
3
 * PrimeBase Media Stream for MySQL
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License as published by
 
7
 * the Free Software Foundation; either version 2 of the License, or
 
8
 * (at your option) any later version.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program; if not, write to the Free Software
 
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
18
 *
 
19
 * Barry Leslie
 
20
 *
 
21
 * System dump table.
 
22
 *
 
23
 */
 
24
#ifdef DRIZZLED
 
25
#include "config.h"
 
26
#include <drizzled/common.h>
 
27
#include <drizzled/session.h>
 
28
#include <drizzled/field/blob.h>
 
29
#endif
 
30
 
 
31
#include "cslib/CSConfig.h"
 
32
 
 
33
#include <sys/types.h>
 
34
#include <sys/stat.h>
 
35
#include <stdlib.h>
 
36
#include <time.h>
 
37
 
 
38
 
 
39
//#include "mysql_priv.h"
 
40
#include "cslib/CSGlobal.h"
 
41
#include "cslib/CSStrUtil.h"
 
42
 
 
43
#include "ha_pbms.h"
 
44
//#include <plugin.h>
 
45
 
 
46
#include "mysql_ms.h"
 
47
#include "repository_ms.h"
 
48
#include "database_ms.h"
 
49
#include "compactor_ms.h"
 
50
#include "open_table_ms.h"
 
51
#include "discover_ms.h"
 
52
#include "transaction_ms.h"
 
53
#include "systab_variable_ms.h"
 
54
#include "backup_ms.h"
 
55
 
 
56
 
 
57
#include "systab_dump_ms.h"
 
58
 
 
59
 
 
60
DT_FIELD_INFO pbms_dump_info[]=
 
61
{
 
62
        {"Data",                        NULL, NULL, MYSQL_TYPE_LONG_BLOB,       &my_charset_bin,        NOT_NULL_FLAG,  "A BLOB repository record"},
 
63
        {NULL,NULL, NULL, MYSQL_TYPE_STRING,NULL, 0, NULL}
 
64
};
 
65
 
 
66
DT_KEY_INFO pbms_dump_keys[]=
 
67
{
 
68
        {NULL, 0, {NULL}}
 
69
};
 
70
 
 
71
 
 
72
/*
 
73
 * -------------------------------------------------------------------------
 
74
 * DUMP TABLE
 
75
 */
 
76
//-----------------------
 
77
MSDumpTable::MSDumpTable(MSSystemTableShare *share, TABLE *table):
 
78
        MSRepositoryTable(share, table)
 
79
{
 
80
}
 
81
 
 
82
//-----------------------
 
83
MSDumpTable::~MSDumpTable()
 
84
{
 
85
}
 
86
 
 
87
//-----------------------
 
88
void MSDumpTable::use()
 
89
{       
 
90
        dt_hasInfo = dt_hasCompleted = dt_haveCloudInfo = false;
 
91
        dt_headerSize = 0;
 
92
        
 
93
        // Suspend the transaction writer while the dump is running.
 
94
        MSTransactionManager::suspend(true);
 
95
 
 
96
        MSRepositoryTable::use();
 
97
}
 
98
 
 
99
//-----------------------
 
100
void MSDumpTable::unuse()
 
101
{
 
102
        MSBackupInfo *backupInfo;
 
103
        
 
104
        backupInfo = myShare->mySysDatabase->myBlobCloud->cl_getBackupInfo();
 
105
        if (backupInfo) {
 
106
                enter_();
 
107
                push_(backupInfo);
 
108
                myShare->mySysDatabase->myBlobCloud->cl_clearBackupInfo();
 
109
                if (backupInfo->isBackupRunning()) {
 
110
                        if (dt_hasCompleted) 
 
111
                                backupInfo->backupCompleted(RETAIN(myShare->mySysDatabase));
 
112
                        else
 
113
                                backupInfo->backupTerminated(RETAIN(myShare->mySysDatabase));
 
114
                }
 
115
                release_(backupInfo);
 
116
                outer_();
 
117
        }
 
118
        
 
119
        MSTransactionManager::resume();
 
120
        MSRepositoryTable::unuse();
 
121
}
 
122
 
 
123
//-----------------------
 
124
void MSDumpTable::seqScanInit()
 
125
{
 
126
        dt_hasInfo = dt_hasCompleted = false;
 
127
        return MSRepositoryTable::seqScanInit();
 
128
}
 
129
//-----------------------
 
130
bool MSDumpTable::seqScanNext(char *buf)
 
131
{
 
132
        if (!dt_hasInfo) {
 
133
                dt_hasInfo = true;
 
134
                return returnInfoRow(buf);
 
135
        }
 
136
        // Reset the position
 
137
        if (!MSRepositoryTable::seqScanNext(buf)) 
 
138
                dt_hasCompleted = true;
 
139
        
 
140
        return !dt_hasCompleted;
 
141
}
 
142
 
 
143
//-----------------------
 
144
bool MSDumpTable::returnDumpRow(char *record, uint64_t record_size, char *buf)
 
145
{
 
146
        TABLE           *table = mySQLTable;
 
147
        Field           *curr_field;
 
148
        byte            *save;
 
149
        MY_BITMAP       *save_write_set;
 
150
 
 
151
 
 
152
 
 
153
 
 
154
        /* ASSERT_COLUMN_MARKED_FOR_WRITE is failing when
 
155
         * I use store()!??
 
156
         * But I want to use it! :(
 
157
         */
 
158
        save_write_set = table->write_set;
 
159
        table->write_set = NULL;
 
160
        memset(buf, 0xFF, table->s->null_bytes);
 
161
        
 
162
        for (Field **field=GET_TABLE_FIELDS(table) ; *field ; field++) {
 
163
                curr_field = *field;
 
164
 
 
165
                save = curr_field->ptr;
 
166
#if MYSQL_VERSION_ID < 50114
 
167
                curr_field->ptr = (byte *) buf + curr_field->offset();
 
168
#else
 
169
                curr_field->ptr = (byte *) buf + curr_field->offset(curr_field->getTable()->getInsertRecord());
 
170
#endif
 
171
                switch (curr_field->field_name[0]) {
 
172
                        case 'D':
 
173
                        case 'd':
 
174
                                // Data         LONGBLOB
 
175
                                ASSERT(strcmp(curr_field->field_name, "Data") == 0);
 
176
                                if (record_size <= 0xFFFFFFF) {
 
177
                                        ((Field_blob *) curr_field)->set_ptr(record_size, (byte *) record);
 
178
                                        setNotNullInRecord(curr_field, buf);
 
179
                                }
 
180
                                break;
 
181
                }
 
182
                curr_field->ptr = save;
 
183
        }
 
184
 
 
185
        table->write_set = save_write_set;
 
186
        return true;
 
187
}
 
188
 
 
189
//-----------------------
 
190
bool MSDumpTable::returnRow(MSBlobHeadPtr blob, char *buf)
 
191
{
 
192
        uint64_t                record_size, blob_repo_size;
 
193
        uint16_t                ref_size, ref_count, refs = 0, table_refs = 0, header_size;
 
194
        uint8_t         blob_storage_type;
 
195
        MSRepoPointersRec       ptr;
 
196
        MSDatabase *myDB = myShare->mySysDatabase;
 
197
        enter_();
 
198
 
 
199
        // Reset the references for the BLOB and recreate
 
200
        // the temp log references.
 
201
        ref_count = CS_GET_DISK_2(blob->rb_ref_count_2);
 
202
        ref_size = CS_GET_DISK_1(blob->rb_ref_size_1);
 
203
 
 
204
        blob_storage_type = CS_GET_DISK_1(blob->rb_storage_type_1);
 
205
 
 
206
        header_size = CS_GET_DISK_2(blob->rb_head_size_2);
 
207
        blob_repo_size = CS_GET_DISK_6(blob->rb_blob_repo_size_6);
 
208
        
 
209
        iBlobBuffer->setLength(header_size);
 
210
        iRepoFile->read(iBlobBuffer->getBuffer(0), iRepoOffset, (size_t) header_size, header_size);
 
211
 
 
212
        // First check to see if the BLOB is referenced
 
213
        ptr.rp_chars = iBlobBuffer->getBuffer(0) + dt_headerSize;
 
214
        for (int count = 0; count < ref_count; count++) {
 
215
                int ref_type = CS_GET_DISK_2(ptr.rp_ref->rr_type_2);
 
216
                
 
217
                switch (ref_type) {
 
218
                        case MS_BLOB_TABLE_REF:
 
219
                                table_refs++;
 
220
                                break;
 
221
                                
 
222
                        case MS_BLOB_FREE_REF:
 
223
                        case MS_BLOB_DELETE_REF:
 
224
                                break;
 
225
                
 
226
                        default: // Assumed to be a MSRepoBlobRefRec.
 
227
                                // Only committed references are backed up.
 
228
                                if (IS_COMMITTED(CS_GET_DISK_8(ptr.rp_blob_ref->er_blob_ref_id_8))) {
 
229
                                        refs++;
 
230
                                } else {
 
231
                                        CS_SET_DISK_2(ptr.rp_ref->rr_type_2, MS_BLOB_FREE_REF);
 
232
                                }
 
233
                                
 
234
                                break;
 
235
                }
 
236
                
 
237
                ptr.rp_chars += ref_size;               
 
238
        }
 
239
        
 
240
        
 
241
        if (refs && table_refs) { // Unreferenced BLOBs are ignored.
 
242
                if (blob_storage_type == MS_CLOUD_STORAGE) {
 
243
                        CloudKeyRec     cloud_key;
 
244
                        MSRepoFile::getBlobKey(blob, &cloud_key);
 
245
                        myDB->myBlobCloud->cl_backupBLOB(&cloud_key);
 
246
                        record_size = header_size;
 
247
                } else {
 
248
                        record_size = header_size + blob_repo_size;
 
249
                        iBlobBuffer->setLength(record_size);
 
250
                        iRepoFile->read(iBlobBuffer->getBuffer(header_size), iRepoOffset + header_size, (size_t) blob_repo_size, blob_repo_size);
 
251
                }
 
252
        } else {
 
253
                record_size = 0; // An empty record is returned for unreferenced BLOBs.
 
254
        }
 
255
 
 
256
 
 
257
        return returnDumpRow(iBlobBuffer->getBuffer(0), record_size, buf);
 
258
}
 
259
 
 
260
//-----------------------
 
261
#define INC_INFO_SPACE(i) record_size+=i; space-=i;ptr+=i;
 
262
#define MS_DUMP_MAGIC 0x5A74C1EB
 
263
typedef struct {
 
264
        CSDiskValue4 ti_table_id_4;
 
265
        char             ti_name[1]; // variable length buffer
 
266
} TabInfoRec, *TabInfoPtr;
 
267
 
 
268
typedef struct {
 
269
        CSDiskValue4 di_magic_4;
 
270
        CSDiskValue2 di_header_size_2;
 
271
}       RepInfoRec, *RepInfoPtr;
 
272
 
 
273
// Repository DUMP info record format: 
 
274
// <Dump magic><BLOB header size><database ID><backup number><sysTables size><sysTables dump>[<table ID><table name>]...
 
275
bool MSDumpTable::returnInfoRow(char *buf)
 
276
{
 
277
        uint64_t                record_size = 0, space = 1024;
 
278
        char            *ptr;
 
279
        MSTable         *tab;
 
280
        uint32_t                space_needed, next_tab = 0, cloudRef, cloudbackupNo, backupRef;
 
281
        RepInfoPtr      rep_info;
 
282
        TabInfoPtr      tab_info;
 
283
        CSStringBuffer *sysTablesDump;
 
284
        MSBackupInfo *backupInfo;
 
285
        CSDiskData      d;
 
286
        enter_();
 
287
 
 
288
        // Setup the sysvar table with the cloud backup number then dump it.
 
289
        if (myShare->mySysDatabase->myBlobType == MS_CLOUD_STORAGE) {
 
290
                cloudbackupNo = myShare->mySysDatabase->myBlobCloud->cl_getNextBackupNumber();
 
291
                cloudRef = myShare->mySysDatabase->myBlobCloud->cl_getDefaultCloudRef();
 
292
        } else {
 
293
                // It is still possible that the database contains BLOBs in cloud storage
 
294
                // even if it isn't currently flaged to use cloud storage.
 
295
                cloudbackupNo = cloudRef = 0;
 
296
        }
 
297
 
 
298
        backupInfo = MSBackupInfo::startDump(RETAIN(myShare->mySysDatabase), cloudRef, cloudbackupNo);
 
299
        backupRef = backupInfo->getBackupRefId();
 
300
        myShare->mySysDatabase->myBlobCloud->cl_setBackupInfo(backupInfo);      
 
301
        
 
302
        dt_cloudbackupDBID = myShare->mySysDatabase->myDatabaseID;
 
303
        
 
304
        sysTablesDump = PBMSSystemTables::dumpSystemTables(RETAIN(myShare->mySysDatabase));
 
305
        push_(sysTablesDump);
 
306
        
 
307
        iBlobBuffer->setLength(space + sysTablesDump->length() + 4 + 4);
 
308
        ptr = iBlobBuffer->getBuffer(0);
 
309
        rep_info = (RepInfoPtr) iBlobBuffer->getBuffer(0);
 
310
        dt_headerSize = sizeof(MSBlobHeadRec);
 
311
        
 
312
        
 
313
        CS_SET_DISK_4(rep_info->di_magic_4, MS_DUMP_MAGIC);
 
314
        CS_SET_DISK_2(rep_info->di_header_size_2, dt_headerSize);
 
315
        
 
316
        INC_INFO_SPACE(sizeof(RepInfoRec));
 
317
        
 
318
        d.rec_chars = ptr;
 
319
        CS_SET_DISK_4(d.int_val->val_4, dt_cloudbackupDBID);
 
320
        INC_INFO_SPACE(4);
 
321
        
 
322
        d.rec_chars = ptr;
 
323
        CS_SET_DISK_4(d.int_val->val_4, backupRef);
 
324
        INC_INFO_SPACE(4);
 
325
        
 
326
        // Add the system tables to the dump
 
327
        d.rec_chars = ptr;
 
328
        CS_SET_DISK_4(d.int_val->val_4, sysTablesDump->length());
 
329
        INC_INFO_SPACE(4);
 
330
        memcpy(ptr, sysTablesDump->getBuffer(0), sysTablesDump->length());
 
331
        INC_INFO_SPACE(sysTablesDump->length());
 
332
        sysTablesDump->release();
 
333
        sysTablesDump = NULL;
 
334
                        
 
335
        tab_info = (TabInfoPtr)ptr;
 
336
        
 
337
        // Get a list of the tables containing BLOB references. 
 
338
        while ((tab = myShare->mySysDatabase->getNextTable(&next_tab))) {
 
339
                push_(tab);
 
340
                space_needed = tab->myTableName->length() + 5;
 
341
                if (space < space_needed) {
 
342
                        space += 1024;
 
343
                        iBlobBuffer->setLength(space);
 
344
                        ptr = iBlobBuffer->getBuffer(0) + record_size;
 
345
                }
 
346
                
 
347
                tab_info = (TabInfoPtr)ptr;
 
348
                CS_SET_DISK_4(tab_info->ti_table_id_4, tab->myTableID);
 
349
                strcpy(tab_info->ti_name, tab->myTableName->getCString());
 
350
                INC_INFO_SPACE(space_needed);
 
351
                
 
352
                release_(tab);
 
353
        }
 
354
        
 
355
        return_(returnDumpRow(iBlobBuffer->getBuffer(0), record_size, buf));
 
356
}
 
357
 
 
358
#define INC_INFO_REC(i) info_buffer+=i; length-=i; tab_info = (TabInfoPtr) info_buffer;
 
359
//-----------------------
 
360
void MSDumpTable::setUpRepository(const char *info_buffer, uint32_t length)
 
361
{
 
362
        uint32_t tab_id, magic;
 
363
        MSDatabase *myDB = myShare->mySysDatabase;
 
364
        RepInfoPtr      rep_info = (RepInfoPtr) info_buffer;
 
365
        TabInfoPtr      tab_info;
 
366
        uint32_t                sys_size, backupRefID;
 
367
        MSBackupInfo *backupInfo;       
 
368
        CSDiskData      d;
 
369
        
 
370
        if (length < sizeof(RepInfoRec)) {
 
371
                CSException::throwException(CS_CONTEXT, CS_ERR_INVALID_RECORD, "Invalid repository info record.");
 
372
        }
 
373
 
 
374
        magic = CS_GET_DISK_4(rep_info->di_magic_4);
 
375
        if (CS_GET_DISK_4(rep_info->di_magic_4) != MS_DUMP_MAGIC) {
 
376
                CSException::throwException(CS_CONTEXT, CS_ERR_BAD_HEADER_MAGIC, "Invalid repository info record.");
 
377
        }
 
378
        
 
379
        dt_headerSize = CS_GET_DISK_2(rep_info->di_header_size_2);
 
380
        INC_INFO_REC(sizeof(RepInfoRec));
 
381
        
 
382
        d.rec_cchars = info_buffer;
 
383
        dt_cloudbackupDBID = CS_GET_DISK_4(d.int_val->val_4);
 
384
        INC_INFO_REC(4);
 
385
        
 
386
        // Get the backup information
 
387
        d.rec_cchars = info_buffer;
 
388
        backupRefID = CS_GET_DISK_4(d.int_val->val_4);
 
389
        INC_INFO_REC(4);
 
390
        
 
391
        // If the backup information is missing then the restore may still
 
392
        // be able to complete so long as cloud storage was not used.
 
393
        backupInfo = MSBackupInfo::findBackupInfo(backupRefID);
 
394
        if (backupInfo)  {
 
395
                myShare->mySysDatabase->myBlobCloud->cl_setBackupInfo(backupInfo);
 
396
                dt_haveCloudInfo = true;
 
397
        }
 
398
        
 
399
        // Restore the System table.
 
400
        d.rec_cchars = info_buffer;
 
401
        sys_size = CS_GET_DISK_4(d.int_val->val_4);
 
402
        INC_INFO_REC(4);
 
403
        
 
404
        PBMSSystemTables::restoreSystemTables(RETAIN(myDB), info_buffer, sys_size);
 
405
        INC_INFO_REC(sys_size);
 
406
 
 
407
        while (length > 5) {
 
408
                tab_id = CS_GET_DISK_4(tab_info->ti_table_id_4);
 
409
                myDB->addTable(tab_id, tab_info->ti_name, 0, false);
 
410
                INC_INFO_REC(strlen(tab_info->ti_name) +5);
 
411
        }
 
412
        
 
413
        if (length)
 
414
                CSException::throwException(CS_CONTEXT, CS_ERR_INVALID_RECORD, "Invalid repository info record.");              
 
415
}
 
416
 
 
417
 
 
418
//-----------------------
 
419
void MSDumpTable::insertRow(char *buf)
 
420
{       
 
421
        TABLE   *table = mySQLTable;
 
422
        Field_blob *field;
 
423
        uint32_t packlength, length;
 
424
        const char *blob_rec, *blob_ptr;
 
425
        
 
426
        field = (Field_blob *)GET_FIELD(table, 0);
 
427
        
 
428
    /* Get the blob record: */
 
429
    blob_rec= buf + field->offset(table->getInsertRecord());
 
430
    packlength= field->pack_length() - table->s->blob_ptr_size;
 
431
 
 
432
    memcpy(&blob_ptr, blob_rec +packlength, sizeof(char*));
 
433
    length= field->get_length();
 
434
        
 
435
        if (!dt_hasInfo) {
 
436
                setUpRepository(blob_ptr, length);
 
437
                dt_hasInfo = true;
 
438
        } else
 
439
                insertRepoRow((MSBlobHeadPtr)blob_ptr, length);
 
440
        
 
441
}
 
442
 
 
443
//-----------------------
 
444
void MSDumpTable::insertRepoRow(MSBlobHeadPtr blob, uint32_t length)
 
445
{       
 
446
        MSRepository *repo;
 
447
        MSRepoFile *repo_file;
 
448
        uint64_t                repo_offset;
 
449
        uint64_t                blob_data_size;
 
450
        uint32_t                auth_code;
 
451
        uint16_t ref_size, ref_count, refs = 0, table_refs = 0;
 
452
        uint8_t         blob_storage_type;
 
453
        MSRepoPointersRec       ptr;
 
454
        MSDatabase *myDB = myShare->mySysDatabase;
 
455
        CloudKeyRec     cloud_key;
 
456
        enter_();
 
457
 
 
458
        if (!length)
 
459
                exit_();
 
460
        
 
461
        if (length != (CS_GET_DISK_2(blob->rb_head_size_2) + CS_GET_DISK_6(blob->rb_blob_repo_size_6))) {
 
462
                CSException::throwException(CS_CONTEXT, MS_ERR_INVALID_RECORD, "Damaged Repository record");
 
463
        }
 
464
        
 
465
        // Get a repository file.
 
466
        repo = myDB->lockRepo(length);
 
467
        frompool_(repo);
 
468
        
 
469
        repo_file = myDB->getRepoFileFromPool(repo->myRepoID, false);
 
470
        frompool_(repo_file);
 
471
 
 
472
        repo_offset = repo->myRepoFileSize;
 
473
        
 
474
        // Reset the references for the BLOB and recreate
 
475
        // the temp log references.
 
476
        auth_code = CS_GET_DISK_4(blob->rb_auth_code_4);
 
477
        ref_count = CS_GET_DISK_2(blob->rb_ref_count_2);
 
478
        ref_size = CS_GET_DISK_1(blob->rb_ref_size_1);
 
479
        blob_data_size = CS_GET_DISK_6(blob->rb_blob_data_size_6);
 
480
 
 
481
        blob_storage_type = CS_GET_DISK_1(blob->rb_storage_type_1);
 
482
        if (blob_storage_type == MS_CLOUD_STORAGE) {
 
483
                MSRepoFile::getBlobKey(blob, &cloud_key);
 
484
        }
 
485
 
 
486
        // First check to see if the BLOB is referenced
 
487
        ptr.rp_chars = ((char*) blob) + dt_headerSize;
 
488
        for (int count = 0; count < ref_count; count++) {
 
489
                int ref_type = CS_GET_DISK_2(ptr.rp_ref->rr_type_2);
 
490
                
 
491
                switch (ref_type) {
 
492
                        case MS_BLOB_TABLE_REF:
 
493
                                table_refs++;
 
494
                                break;
 
495
                                
 
496
                        case MS_BLOB_FREE_REF:
 
497
                        case MS_BLOB_DELETE_REF:
 
498
                                break;
 
499
                
 
500
                        default: // Assumed to be a MSRepoBlobRefRec.
 
501
                                // Only committed references are backed up.
 
502
                                if (IS_COMMITTED(CS_GET_DISK_8(ptr.rp_blob_ref->er_blob_ref_id_8))) {
 
503
                                        refs++;
 
504
                                } else {
 
505
                                        CS_SET_DISK_2(ptr.rp_ref->rr_type_2, MS_BLOB_FREE_REF);
 
506
                                }
 
507
                                
 
508
                                break;
 
509
                }
 
510
                
 
511
                ptr.rp_chars += ref_size;               
 
512
        }
 
513
        
 
514
        
 
515
        if (refs && table_refs) { // Unreferenced BLOBs are ignored.
 
516
        
 
517
        
 
518
                // Set table references.
 
519
                ptr.rp_chars = ((char*) blob) + dt_headerSize;
 
520
                for (int count = 0; count < ref_count; count++) {
 
521
                        int ref_type = CS_GET_DISK_2(ptr.rp_ref->rr_type_2);
 
522
                        MSOpenTable     *otab;
 
523
                        uint32_t                tab_id;
 
524
                        uint64_t                blob_id;
 
525
                        
 
526
                        switch (ref_type) {
 
527
                                case MS_BLOB_TABLE_REF:
 
528
                                        tab_id = CS_GET_DISK_4(ptr.rp_tab_ref->tr_table_id_4);
 
529
                                        blob_id = CS_GET_DISK_6(ptr.rp_tab_ref->tr_blob_id_6);
 
530
                                        otab = MSTableList::getOpenTableByID(myDB->myDatabaseID, tab_id);
 
531
                        
 
532
                                        frompool_(otab);
 
533
                                        otab->getDBTable()->setBlobHandle(otab, blob_id, repo->myRepoID, repo_offset, blob_data_size, dt_headerSize, auth_code);
 
534
                                        backtopool_(otab);
 
535
                                        break;
 
536
                                        
 
537
                                case MS_BLOB_DELETE_REF:
 
538
                                        break;
 
539
                                                                
 
540
                                case MS_BLOB_FREE_REF:
 
541
                                default: 
 
542
                                        break;
 
543
                        }
 
544
                                
 
545
                        ptr.rp_chars += ref_size;               
 
546
                }       
 
547
        
 
548
                // Write the repository record.
 
549
                repo_file->write(blob, repo_offset, length);
 
550
                repo->myRepoFileSize += length;
 
551
                
 
552
#ifdef HAVE_ALIAS_SUPPORT
 
553
                uint16_t alias_offset;
 
554
                if (alias_offset = CS_GET_DISK_2(blob->rb_alias_offset_2)) { 
 
555
                        myDB->registerBlobAlias(repo->myRepoID, repo_offset, ((char*)blob) + alias_offset);
 
556
                }
 
557
#endif          
 
558
                if (blob_storage_type == MS_CLOUD_STORAGE) {
 
559
                        if (!dt_haveCloudInfo) {
 
560
                                CSException::throwException(CS_CONTEXT, MS_ERR_MISSING_CLOUD_REFFERENCE, "Missing cloud backup information.");
 
561
                        }
 
562
                        myDB->myBlobCloud->cl_restoreBLOB(&cloud_key, dt_cloudbackupDBID);
 
563
                }
 
564
        }
 
565
 
 
566
        backtopool_(repo_file);
 
567
        backtopool_(repo);
 
568
        exit_();
 
569
}
 
570
 
 
571
 
 
572