~jlukas79/+junk/mysql-server

« back to all changes in this revision

Viewing changes to sql/backup/image_info.cc

manual merge 6.0-main --> 6.0-bka-review

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#include "../mysql_priv.h"
2
2
 
3
 
#include <backup_stream.h>
4
 
#include "backup_aux.h"
5
 
#include "catalog.h"
6
 
#include "be_snapshot.h"
7
 
#include "be_default.h"
 
3
#include "image_info.h"
8
4
#include "be_native.h"
9
5
 
10
6
/**
12
8
 
13
9
  @brief Implements @c Image_info class and friends.
14
10
 
15
 
  @todo Error reporting
16
 
  @todo Store endianess info in the image.
17
11
*/
18
12
 
19
13
namespace backup {
20
14
 
21
 
/* Image_info implementation */
22
 
 
23
 
Image_info::Image_info():
24
 
  backup_prog_id(0), table_count(0), data_size(0), m_items(32,128)
 
15
Image_info::Image_info()
 
16
  :data_size(0), m_table_count(0), m_dbs(16, 16), m_ts_map(16,16)
25
17
{
 
18
  init_alloc_root(&mem_root, 4 * 1024, 0);
 
19
 
26
20
  /* initialize st_bstream_image_header members */
27
 
  version= 1;
 
21
 
 
22
  bzero(static_cast<st_bstream_image_header*>(this),
 
23
        sizeof(st_bstream_image_header));
 
24
 
 
25
  /* 
 
26
    This code reads and writes backup image using version 1 of the backup 
 
27
    image format.
 
28
   */ 
 
29
  version= 1; 
28
30
 
29
31
  /*
30
 
    The arithmetic below assumes that MYSQL_VERSION_ID digits are arrenged
 
32
    The arithmetic below assumes that MYSQL_VERSION_ID digits are arranged
31
33
    as follows: HLLRR where
32
34
    H - major version number
33
35
    L - minor version number
34
36
    R - release
35
 
 
36
 
    TODO: check if this is correct
37
37
  */
38
 
  DBUG_PRINT("backup",("version %d",MYSQL_VERSION_ID));
 
38
  DBUG_PRINT("backup",("version %d", MYSQL_VERSION_ID));
39
39
  server_version.major= MYSQL_VERSION_ID / 10000;
40
40
  server_version.minor= (MYSQL_VERSION_ID % 10000) / 100;
41
41
  server_version.release= MYSQL_VERSION_ID % 100;
43
43
  server_version.extra.end= server_version.extra.begin +
44
44
                            strlen((const char*)server_version.extra.begin);
45
45
 
46
 
  flags= 0;  // TODO: set BSTREAM_FLAG_BIG_ENDIAN flag accordingly
47
 
  snap_count= 0;
48
 
 
49
 
  bzero(&start_time,sizeof(start_time));
50
 
  bzero(&end_time,sizeof(end_time));
51
 
  bzero(&vp_time,sizeof(vp_time));
52
 
  bzero(&binlog_pos,sizeof(binlog_pos));
53
 
  bzero(&binlog_group,sizeof(binlog_group));
 
46
  flags= 0;
 
47
 
 
48
#ifdef WORDS_BIGENDIAN
 
49
  flags|= BSTREAM_FLAG_BIG_ENDIAN;
 
50
#endif
 
51
 
54
52
  bzero(m_snap, sizeof(m_snap));
55
53
}
56
54
 
57
55
Image_info::~Image_info()
58
56
{
59
 
  // Delete snapshot objects
60
 
 
61
 
  for (uint no=0; no<256; ++no)
62
 
  {
63
 
    Snapshot_info *snap= m_snap[no];
64
 
    
65
 
    if (!snap)
66
 
      continue;
67
 
    
68
 
    for (uint i=0; i < snap->table_count(); ++i)
69
 
    {
70
 
      Table_item *t= snap->get_table(i);
71
 
      
72
 
      if (!t)
73
 
        continue;
74
 
        
75
 
      delete t->obj_ptr();
76
 
    }
77
 
    
78
 
    delete snap;
79
 
    m_snap[no]= NULL;
80
 
  }
81
 
  
82
 
  // delete server object instances as we own them.
83
 
 
84
 
  for (uint i=0; i < db_count(); ++i)
85
 
  {
86
 
    Db_item *db= m_db[i];
87
 
    
88
 
    if (db)
89
 
      delete db->obj_ptr();
90
 
  }
91
 
  
92
 
  for (uint i=0; i < m_items.size(); ++i)
93
 
  {
94
 
    PerDb_item *it= m_items[i];
95
 
    
96
 
    if (it)
97
 
      delete it->obj_ptr();
98
 
  }
99
 
}
100
 
 
101
 
 
102
 
void Image_info::save_time(const time_t t, bstream_time_t &buf)
103
 
{
104
 
  struct tm time;
105
 
  gmtime_r(&t,&time);
106
 
  buf.year= time.tm_year;
107
 
  buf.mon= time.tm_mon;
108
 
  buf.mday= time.tm_mday;
109
 
  buf.hour= time.tm_hour;
110
 
  buf.min= time.tm_min;
111
 
  buf.sec= time.tm_sec;  
112
 
}
113
 
 
114
 
result_t Image_info::Item::get_serialization(THD *thd, ::String &buf)
115
 
{
116
 
  obs::Obj *obj= obj_ptr();
117
 
  
118
 
  DBUG_ASSERT(obj);
119
 
  
120
 
  if (!obj)
121
 
    return ERROR;
122
 
    
123
 
  return obj->serialize(thd, &buf) ? ERROR : OK;
124
 
}
125
 
 
126
 
/// Add table to database's table list.
127
 
result_t Image_info::Db_item::add_table(Table_item &t)
128
 
{
129
 
  t.next_table= NULL;
130
 
  t.base.db= this;
131
 
 
132
 
  if (!m_last_table)
133
 
  {
134
 
    m_tables= m_last_table= &t;
135
 
  }
136
 
  else
137
 
  {
138
 
    m_last_table->next_table= &t;
139
 
    m_last_table= &t;
140
 
  }
141
 
 
142
 
  table_count++;
143
 
 
144
 
  return OK;
145
 
}
146
 
 
147
 
/**
148
 
  Locate in the catalogue an object described by the @c st_bstream_item_info
149
 
  structure.
150
 
 
151
 
  @todo Handle unknown item types.
152
 
*/
153
 
Image_info::Item*
154
 
Image_info::locate_item(const st_bstream_item_info *item) const
155
 
{
156
 
  switch (item->type) {
 
57
  /* 
 
58
    We need to explicitly call destructors for all objects in the catalogue
 
59
    since they are allocated using mem_root and thus destructors will not be
 
60
    invoked when the mem_root is freed.
 
61
  */
 
62
 
 
63
  // first tablespaces
 
64
 
 
65
  Ts_iterator tsit(*this);
 
66
  Ts *ts;
 
67
 
 
68
  while ((ts= static_cast<Ts*>(tsit++)))
 
69
    ts->~Ts();
 
70
 
 
71
  Db_iterator dbit(*this);
 
72
  Db *db;
 
73
 
 
74
  // then databases and all objects inside each database
 
75
 
 
76
  while ((db= static_cast<Db*>(dbit++)))
 
77
  {
 
78
    // iterate over objects in the database
 
79
 
 
80
    Dbobj_iterator it(*this,*db);
 
81
    Obj *o;
 
82
 
 
83
    while ((o= it++))
 
84
      o->~Obj();
 
85
 
 
86
    db->~Db(); 
 
87
  }
 
88
 
 
89
  free_root(&mem_root, MYF(0)); 
 
90
}
 
91
 
 
92
/**
 
93
  Add database to the catalogue.
 
94
 
 
95
  @param[in] db_name  name of the database
 
96
  @param[in] pos      position at which this database should be stored
 
97
 
 
98
  @returns Pointer to @c Image_info::Db instance storing information 
 
99
  about the database or NULL in case of error.
 
100
 
 
101
  @see @c get_db().
 
102
 */
 
103
Image_info::Db* 
 
104
Image_info::add_db(const String &db_name, uint pos)
 
105
{
 
106
  Db *db= new (&mem_root) Db(db_name);
 
107
  
 
108
  if (!db)
 
109
    return NULL;
 
110
  
 
111
  // call destructor if position is occupied
 
112
  if (m_dbs[pos])
 
113
    m_dbs[pos]->~Db();
 
114
 
 
115
  if (m_dbs.insert(pos, db))
 
116
    return NULL;
 
117
  
 
118
  db->base.pos= pos;
 
119
  
 
120
  return db;
 
121
}
 
122
 
 
123
/**
 
124
  Add tablespace to the catalogue.
 
125
 
 
126
  @param[in] ts_name  name of the tablespace
 
127
  @param[in] pos      position at which this database should be stored
 
128
 
 
129
  @returns Pointer to @c Image_info::Ts instance storing information 
 
130
  about the tablespace or NULL in case of error.
 
131
 
 
132
  @see @c get_ts().
 
133
 */
 
134
Image_info::Ts* 
 
135
Image_info::add_ts(const String &ts_name, uint pos)
 
136
{
 
137
  Ts *ts= new (&mem_root) Ts(ts_name);
 
138
  
 
139
  if (!ts)
 
140
    return NULL;
 
141
  
 
142
  // call destructor if position is occupied
 
143
  if (m_ts_map[pos])
 
144
    m_ts_map[pos]->~Ts();
 
145
 
 
146
  if (m_ts_map.insert(pos, ts))
 
147
    return NULL;
 
148
  
 
149
  ts->base.pos= pos;
 
150
  
 
151
  return ts;
 
152
}
 
153
 
 
154
/**
 
155
  Add snapshot to the catalogue.
 
156
  
 
157
  The snapshot should be non-empty, that is contain data of at least one table.
 
158
  Snapshot is added to the list of snapshots used in the image and a number is
 
159
  assigned to it. This number is stored in @c snap.m_num. If snapshot's number
 
160
  is @c n then pointer to a corresponding @c Snapshot_info object is stored in 
 
161
  @c m_snap[n-1].
 
162
  
 
163
  The @c Snapshot_info object is not owned by @c Image_info instance - it must
 
164
  be deleted externally.
 
165
 
 
166
  @returns Snapshot's number or -1 in case of error.
 
167
 */ 
 
168
int Image_info::add_snapshot(Snapshot_info &snap)
 
169
{
 
170
  uint num= st_bstream_image_header::snap_count++;
 
171
 
 
172
  // The limit of 256 snapshots is imposed by backup stream format.  
 
173
  if (num > 256)
 
174
    return -1;
 
175
  
 
176
  m_snap[num]= &snap;
 
177
  snap.m_num= num + 1;
 
178
  
 
179
  /* 
 
180
    Store information about snapshot in the snapshot[] table for the
 
181
    backup stream library
 
182
   */
 
183
 
 
184
  st_bstream_snapshot_info &info= snapshot[num];
 
185
  
 
186
  bzero(&info, sizeof(st_bstream_snapshot_info));
 
187
  info.type= enum_bstream_snapshot_type(snap.type());
 
188
  info.version= snap.version();
 
189
  info.table_count= snap.table_count();
 
190
  
 
191
  if (snap.type() == Snapshot_info::NATIVE_SNAPSHOT)
 
192
  {
 
193
    Native_snapshot &ns= static_cast<Native_snapshot&>(snap);
 
194
    uint se_ver= ns.se_ver();
 
195
    const char *se_name= ns.se_name();
 
196
    
 
197
    info.engine.major= se_ver >> 8;
 
198
    info.engine.minor= se_ver & 0xFF;
 
199
    info.engine.name.begin= (byte*)se_name;
 
200
    info.engine.name.end= info.engine.name.begin + strlen(se_name);    
 
201
  }
 
202
  
 
203
  return num + 1;
 
204
}
 
205
 
 
206
/**
 
207
  Check if catalogue contains given database.
 
208
 */ 
 
209
bool Image_info::has_db(const String &db_name)
 
210
{
 
211
  for (uint n=0; n < m_dbs.count() ; ++n)
 
212
    if (m_dbs[n] && m_dbs[n]->name() == db_name)
 
213
      return TRUE;
 
214
 
 
215
  return FALSE;
 
216
}
 
217
 
 
218
/** 
 
219
  Add per database object to the catalogue.
 
220
 
 
221
  @param[in]  db  database to which this object belongs - this database must
 
222
                  already be in the catalogue
 
223
  @param[in] type type of the object
 
224
  @param[in] name name of the object
 
225
  @param[in] pos  position where the object will be stored inside database's
 
226
                  object list
 
227
 
 
228
  @returns Pointer to @c Image_info::Dbobj instance storing information 
 
229
  about the object or NULL in case of error.
 
230
 
 
231
  @note There is a specialized method @c add_table() for adding tables.
 
232
 
 
233
  @see @c get_db_object().
 
234
 */
 
235
Image_info::Dbobj* Image_info::add_db_object(Db &db,
 
236
                                             const enum_bstream_item_type type,
 
237
                                             const ::String &name, ulong pos)
 
238
{
 
239
  Dbobj *o= new (&mem_root) Dbobj(db, type, name);
 
240
 
 
241
  if (!o)
 
242
    return NULL;  
 
243
  
 
244
  if (db.add_obj(*o, pos))
 
245
    return NULL;
 
246
    
 
247
  o->base.pos= pos;
 
248
 
 
249
  return o;
 
250
}
 
251
 
 
252
/**
 
253
  Return per database object stored in catalogue.
 
254
 
 
255
  This method is used only for non-table objects.
 
256
 
 
257
  @param[in]  db_num  position of object's database in the catalogue 
 
258
  @param[in]  pos     position of the object inside the database
 
259
 
 
260
  @returns Pointer to @c Image_info::Dbobj instance storing information 
 
261
  about the object or NULL if there is no object with given coordinates.
 
262
 */
 
263
Image_info::Dbobj* Image_info::get_db_object(uint db_num, ulong pos) const
 
264
{
 
265
  Db *db= get_db(db_num);
 
266
 
 
267
  if (!db)
 
268
    return NULL;
 
269
 
 
270
  return db->get_obj(pos);
 
271
}
 
272
 
 
273
/**
 
274
  Add table to the catalogue.
 
275
 
 
276
  @param[in]  db  table's database - this database must already be in 
 
277
                  the catalogue
 
278
  @param[in] name name of the table
 
279
  @param[in] snap snapshot containing table's data
 
280
  @param[in] pos  table's position within the snapshot
 
281
 
 
282
  @returns Pointer to @c Image_info::Table instance storing information 
 
283
  about the table or NULL in case of error.
 
284
 
 
285
  @note The snapshot is added to the catalogue if it was not there already.
 
286
 
 
287
  @see @c get_table().
 
288
 */
 
289
Image_info::Table* 
 
290
Image_info::add_table(Db &db, const ::String &table_name, 
 
291
                      Snapshot_info &snap, ulong pos)
 
292
{
 
293
  Table *t= new (&mem_root) Table(db, table_name);
 
294
  
 
295
  if (!t)
 
296
    return NULL;
 
297
 
 
298
  if (snap.add_table(*t, pos))
 
299
    return NULL;
 
300
  
 
301
  if (db.add_table(*t))
 
302
    return NULL;
 
303
 
 
304
  if (!snap.m_num)
 
305
    snap.m_num= add_snapshot(snap);
 
306
 
 
307
  if (!snap.m_num)
 
308
   return NULL;
 
309
 
 
310
  t->snap_num= snap.m_num - 1;
 
311
  t->base.base.pos= pos;
 
312
 
 
313
  m_table_count++;
 
314
 
 
315
  return t;  
 
316
}
 
317
 
 
318
/**
 
319
  Return table stored in the catalogue.
 
320
 
 
321
  @param[in] snap_num position of table's snapshot within the catalogue
 
322
  @param[in] pos      position of the table within the snapshot
 
323
 
 
324
  @returns Pointer to @c Image_info::Table instance storing information 
 
325
  about the table or NULL if there is no table with given coordinates.
 
326
 */ 
 
327
Image_info::Table* 
 
328
Image_info::get_table(ushort snap_num, ulong pos) const
 
329
{
 
330
  if (snap_num > snap_count() || m_snap[snap_num] == NULL)
 
331
    return NULL;
 
332
  
 
333
  Table *t= m_snap[snap_num]->get_table(pos);
 
334
  
 
335
  if (!t)
 
336
    return NULL;
 
337
  
 
338
  return t;
 
339
}
 
340
 
 
341
/**
 
342
  Find object in the catalogue.
 
343
  
 
344
  The object is identified by its coordinates stored in a 
 
345
  @c st_bstream_item_info structure. Normally these coordinates are
 
346
  filled by backup stream library when reading backup image.
 
347
  
 
348
  @returns Pointer to the corresponding @c Obj instance or NULL if object
 
349
  was not found.
 
350
 */ 
 
351
Image_info::Obj *find_obj(const Image_info &info, 
 
352
                          const st_bstream_item_info &item)
 
353
{
 
354
  switch (item.type) {
 
355
 
 
356
  case BSTREAM_IT_TABLESPACE:
 
357
    return info.get_ts(item.pos);
157
358
 
158
359
  case BSTREAM_IT_DB:
159
 
    return get_db(item->pos);
 
360
    return info.get_db(item.pos);
160
361
 
161
362
  case BSTREAM_IT_TABLE:
162
363
  {
163
 
    const st_bstream_table_info *ti= reinterpret_cast<const st_bstream_table_info*>(item);
164
 
    return get_table(ti->snap_no,item->pos);
 
364
    const st_bstream_table_info &ti= 
 
365
                           reinterpret_cast<const st_bstream_table_info&>(item);
 
366
 
 
367
    return info.get_table(ti.snap_num, item.pos);
165
368
  }
166
369
 
167
370
  case BSTREAM_IT_VIEW:
169
372
  case BSTREAM_IT_SFUNC:
170
373
  case BSTREAM_IT_EVENT:
171
374
  case BSTREAM_IT_TRIGGER:
172
 
    return get_db_object(item->pos);
 
375
  {
 
376
    const st_bstream_dbitem_info &it=
 
377
                          reinterpret_cast<const st_bstream_dbitem_info&>(item);
 
378
 
 
379
    return info.get_db_object(it.db->base.pos, item.pos);
 
380
  }
173
381
 
174
382
  default:
175
 
    // TODO: warn or report error
176
 
    return NULL;
177
 
  }
178
 
}
179
 
 
180
 
/**
181
 
  Store in Backup_image all objects enumerated by the iterator.
182
 
 */ 
183
 
int Image_info::add_objects(Db_item &dbi,
184
 
                            const enum_bstream_item_type type, 
185
 
                            obs::ObjIterator &it)
186
 
{
187
 
  using namespace obs;
188
 
  
189
 
  Obj *obj;
190
 
  
191
 
  while ((obj= it.next()))
192
 
    if (!add_db_object(dbi, type, *obj))
193
 
    {
194
 
      delete obj;
195
 
      return TRUE;
196
 
    }
197
 
 
198
 
  return FALSE;
199
 
}
200
 
 
201
 
Image_info::PerDb_item* Image_info::add_db_object(Db_item &dbi,
202
 
                                                  const enum_bstream_item_type type,
203
 
                                                  obs::Obj &obj)
204
 
{
205
 
  ulong pos= m_items.size();
206
 
  
207
 
  PerDb_item *it= m_items.get_entry(pos);
208
 
  
209
 
  if (!it)
210
 
    return NULL;
211
 
    
212
 
  *it= obj;
213
 
  it->base.type= type;
214
 
  it->base.pos= pos;
215
 
  it->db= &dbi;
216
 
 
217
 
  return it;
218
 
}
219
 
 
220
 
Image_info::PerDb_item* Image_info::add_db_object(Db_item &dbi,
221
 
                                                  const enum_bstream_item_type type,
222
 
                                                  const ::String &name)
223
 
{
224
 
  ulong pos= m_items.size();
225
 
  
226
 
  PerDb_item *it= m_items.get_entry(pos);
227
 
  
228
 
  if (!it)
229
 
    return NULL;
230
 
    
231
 
  *it= name;
232
 
  it->base.type= type;
233
 
  it->base.pos= pos;
234
 
  it->db= &dbi;
235
 
  it->m_db_name= dbi.name();
236
 
 
237
 
  return it;
238
 
}
239
 
 
240
 
obs::Obj* Image_info::PerDb_item::obj_ptr(uint ver, ::String &sdata)
241
 
242
 
  using namespace obs;
243
 
 
244
 
  delete m_obj;
245
 
  
246
 
  switch (base.type) {
247
 
  case BSTREAM_IT_VIEW:   
248
 
    m_obj= materialize_view(&m_db_name, &m_name, ver, &sdata); break;
249
 
  case BSTREAM_IT_SPROC:  
250
 
    m_obj= materialize_stored_procedure(&m_db_name, &m_name, ver, &sdata); break;
251
 
  case BSTREAM_IT_SFUNC:
252
 
    m_obj= materialize_stored_function(&m_db_name, &m_name, ver, &sdata); break;
253
 
  case BSTREAM_IT_EVENT:
254
 
    m_obj= materialize_event(&m_db_name, &m_name, ver, &sdata); break;
255
 
  case BSTREAM_IT_TRIGGER:   
256
 
    m_obj= materialize_trigger(&m_db_name, &m_name, ver, &sdata); break;
257
 
  default: m_obj= NULL;
258
 
  }
259
 
 
260
 
  return m_obj;
261
 
}
262
 
 
263
 
bool Image_info::Ditem_iterator::next()
264
 
{
265
 
  if (ptr)
266
 
    ptr= ptr->next_table;
267
 
    
268
 
  if (ptr)
269
 
    return TRUE;
270
 
 
271
 
  bool more=TRUE;
272
 
 
273
 
  // advance to next element in other list if we are inside it
274
 
  if (other_list)
275
 
     more= PerDb_iterator::next();
276
 
 
277
 
  other_list= TRUE; // mark that we are now inside the other list
278
 
 
279
 
  // return if there are no more elements in the other list
280
 
  if (!more)
281
 
    return FALSE;
282
 
 
283
 
  // find an element belonging to our database  
284
 
  do
285
 
  {
286
 
    PerDb_item *it= (PerDb_item*)PerDb_iterator::get_ptr();
287
 
 
288
 
    if (!it)
289
 
      return FALSE;
290
 
    
291
 
    if (it->m_db_name == db_name)
292
 
      return TRUE;
293
 
  }
294
 
  while (PerDb_iterator::next());
295
 
    
296
 
  // we haven't found any object belonging to our database
297
 
  return FALSE;
 
383
    return NULL;
 
384
  }
298
385
}
299
386
 
300
387
} // backup namespace
301
388
 
302
 
 
303
 
/* catalogue services for backup stream library */
304
 
 
305
 
extern "C" {
306
 
 
307
 
/* iterators */
308
 
 
309
 
static uint cset_iter;  ///< Used to implement trivial charset iterator.
310
 
static uint null_iter;  ///< Used to implement trivial empty iterator.
311
 
 
312
 
void* bcat_iterator_get(st_bstream_image_header *catalogue, unsigned int type)
313
 
{
314
 
  switch (type) {
315
 
 
316
 
  case BSTREAM_IT_PERDB:
317
 
    return
318
 
    new backup::Image_info::PerDb_iterator(*static_cast<backup::Image_info*>(catalogue));
319
 
 
320
 
  case BSTREAM_IT_PERTABLE:
321
 
    return &null_iter;
322
 
 
323
 
  case BSTREAM_IT_CHARSET:
324
 
    cset_iter= 0;
325
 
    return &cset_iter;
326
 
 
327
 
  case BSTREAM_IT_USER:
328
 
    return &null_iter;
329
 
 
330
 
  case BSTREAM_IT_GLOBAL:
331
 
    // only global items (for which meta-data is stored) are databases
332
 
  case BSTREAM_IT_DB:
333
 
    return
334
 
    new backup::Image_info::Db_iterator(*static_cast<backup::Image_info*>(catalogue));
335
 
    // TODO: report error if iterator could not be created
336
 
 
337
 
  default:
338
 
    return NULL;
339
 
 
340
 
  }
341
 
}
342
 
 
343
 
struct st_bstream_item_info*
344
 
bcat_iterator_next(st_bstream_image_header *catalogue, void *iter)
345
 
{
346
 
  /* If this is the null iterator, return NULL immediately */
347
 
  if (iter == &null_iter)
348
 
    return NULL;
349
 
 
350
 
  static bstream_blob name= {NULL, NULL};
351
 
 
352
 
  /*
353
 
    If it is cset iterator then cset_iter variable contains iterator position.
354
 
    We return only 2 charsets: the utf8 charset used to encode all strings and
355
 
    the default server charset.
356
 
  */
357
 
  if (iter == &cset_iter)
358
 
  {
359
 
    switch (cset_iter) {
360
 
      case 0: name.begin= (byte*)::my_charset_utf8_bin.csname; break;
361
 
      case 1: name.begin= (byte*)::system_charset_info->csname; break;
362
 
      default: name.begin= NULL; break;
363
 
    }
364
 
 
365
 
    name.end= name.begin ? name.begin + strlen((char*)name.begin) : NULL;
366
 
    cset_iter++;
367
 
 
368
 
    return name.begin ? (st_bstream_item_info*)&name : NULL;
369
 
  }
370
 
 
371
 
  /*
372
 
    In all other cases assume that iter points at instance of
373
 
    @c Image_info::Iterator and use this instance to get next item.
374
 
   */
375
 
  const backup::Image_info::Item *ptr= (*(backup::Image_info::Iterator*)iter)++;
376
 
 
377
 
  return ptr ? (st_bstream_item_info*)(ptr->info()) : NULL;
378
 
}
379
 
 
380
 
void  bcat_iterator_free(st_bstream_image_header *catalogue, void *iter)
381
 
{
382
 
  /*
383
 
    Do nothing for the null and cset iterators, but delete the
384
 
    @c Image_info::Iterator object otherwise.
385
 
  */
386
 
  if (iter == &null_iter)
387
 
    return;
388
 
 
389
 
  if (iter == &cset_iter)
390
 
    return;
391
 
 
392
 
  delete (backup::Image_info::Iterator*)iter;
393
 
}
394
 
 
395
 
/* db-items iterator */
396
 
 
397
 
void* bcat_db_iterator_get(st_bstream_image_header *catalogue, struct st_bstream_db_info *db)
398
 
{
399
 
  using namespace backup;
400
 
 
401
 
  Image_info::Db_item *dbi = static_cast<Image_info::Db_item*>(db);
402
 
 
403
 
  return
404
 
  new Image_info::Ditem_iterator(*static_cast<backup::Image_info*>(catalogue),
405
 
                                 *dbi);
406
 
}
407
 
 
408
 
struct st_bstream_dbitem_info*
409
 
bcat_db_iterator_next(st_bstream_image_header *catalogue,
410
 
                        struct st_bstream_db_info *db,
411
 
                        void *iter)
412
 
{
413
 
  const backup::Image_info::Item *ptr= (*(backup::Image_info::Iterator*)iter)++;
414
 
 
415
 
  return ptr ? (st_bstream_dbitem_info*)ptr->info() : NULL;
416
 
}
417
 
 
418
 
void  bcat_db_iterator_free(st_bstream_image_header *catalogue,
419
 
                              struct st_bstream_db_info *db,
420
 
                              void *iter)
421
 
{
422
 
  delete (backup::Image_info::Iterator*)iter;
423
 
}
424
 
 
425
 
}
426
 
 
 
389
template class Map<uint, backup::Image_info::Db>;