~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Mark Atwood
  • Date: 2011-12-20 02:32:53 UTC
  • mfrom: (2469.1.1 drizzle-build)
  • Revision ID: me@mark.atwood.name-20111220023253-bvu0kr14kwsdvz7g
mergeĀ lp:~brianaker/drizzle/deprecate-pbms

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