~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/drizzlebinlog.cc

  • Committer: Monty Taylor
  • Date: 2008-09-05 22:55:50 UTC
  • mfrom: (373.1.9 stl-client-progs)
  • Revision ID: monty@inaugust.com-20080905225550-zco374c9s7kxwqyb
Merged removal of DYNAMIC_STRING.

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
 
31
31
#define DRIZZLE_CLIENT
32
32
#undef DRIZZLE_SERVER
 
33
 
 
34
#include <map>
 
35
 
33
36
#include <libdrizzle/my_time.h>
34
37
#include <drizzled/global.h>
35
38
#include <mysys/my_sys.h>
41
44
#include <drizzled/log_event.h>
42
45
#include <libdrizzle/sql_common.h>
43
46
 
 
47
using namespace std;
44
48
 
45
49
enum options_drizzlebinlog
46
50
{
141
145
  /*
142
146
    When we see first event corresponding to some LOAD DATA statement in
143
147
    binlog, we create temporary file to store data to be loaded.
144
 
    We add name of this file to file_names array using its file_id as index.
 
148
    We add name of this file to file_names map using its file_id as index.
145
149
    If we have Create_file event (i.e. we have binary log in pre-5.0.3
146
150
    format) we also store save event object to be able which is needed to
147
151
    emit LOAD DATA statement when we will meet Exec_load_data event.
153
157
    char *fname;
154
158
    Create_file_log_event *event;
155
159
  };
156
 
  /*
157
 
    @todo Should be a map (e.g., a hash map), not an array.  With the
158
 
    present implementation, the number of elements in this array is
159
 
    about the number of files loaded since the server started, which
160
 
    may be big after a few years.  We should be able to use existing
161
 
    library data structures for this. /Sven
162
 
  */
163
 
  DYNAMIC_ARRAY file_names;
 
160
 
 
161
  map<unsigned int, File_name_record *> file_names;
164
162
 
165
163
  /**
166
164
    Looks for a non-existing filename by adding a numerical suffix to
195
193
  Load_log_processor() {}
196
194
  ~Load_log_processor() {}
197
195
 
198
 
  int init()
199
 
  {
200
 
    return init_dynamic_array(&file_names, sizeof(File_name_record),
201
 
            100,100 CALLER_INFO);
202
 
  }
203
 
 
204
196
  void init_by_dir_name(const char *dir)
205
197
    {
206
198
      target_dir_name_len= (convert_dirname(target_dir_name, dir, NullS) -
214
206
    }
215
207
  void destroy()
216
208
  {
217
 
    File_name_record *ptr= (File_name_record *)file_names.buffer;
218
 
    File_name_record *end= ptr + file_names.elements;
219
 
    for (; ptr < end; ptr++)
 
209
    // TODO: Is this necessary? Can't we make the map dtor do this for us?
 
210
    map<unsigned int, File_name_record *>::iterator i;
 
211
    for ( i= file_names.begin() ; i != file_names.end() ; i++)
220
212
    {
221
 
      if (ptr->fname)
 
213
      File_name_record *record_to_delete = file_names[i->first];
 
214
      if (record_to_delete->fname)
222
215
      {
223
 
        my_free(ptr->fname, MYF(MY_WME));
224
 
        delete ptr->event;
225
 
        memset(ptr, 0, sizeof(File_name_record));
 
216
        free(record_to_delete->fname);
 
217
        delete record_to_delete->event;
226
218
      }
 
219
      file_names.erase(i->first);
227
220
    }
228
 
 
229
 
    delete_dynamic(&file_names);
230
221
  }
231
222
 
232
223
  /**
247
238
  Create_file_log_event *grab_event(uint file_id)
248
239
    {
249
240
      File_name_record *ptr;
250
 
      Create_file_log_event *res;
251
241
 
252
 
      if (file_id >= file_names.elements)
253
 
        return 0;
254
 
      ptr= dynamic_element(&file_names, file_id, File_name_record*);
255
 
      if ((res= ptr->event))
256
 
        memset(ptr, 0, sizeof(File_name_record));
257
 
      return res;
 
242
      if ((ptr= file_names[file_id]))
 
243
      {
 
244
        file_names.erase(file_id);
 
245
      }
 
246
      return ptr->event;
258
247
    }
259
248
 
260
249
  /**
275
264
  char *grab_fname(uint file_id)
276
265
    {
277
266
      File_name_record *ptr;
278
 
      char *res= 0;
 
267
      char *res= NULL;
279
268
 
280
 
      if (file_id >= file_names.elements)
281
 
        return 0;
282
 
      ptr= dynamic_element(&file_names, file_id, File_name_record*);
283
 
      if (!ptr->event)
 
269
      if ((ptr= file_names[file_id]))
284
270
      {
285
 
        res= ptr->fname;
286
 
        memset(ptr, 0, sizeof(File_name_record));
 
271
        if (ptr->event != NULL)
 
272
        {
 
273
          res= ptr->fname;
 
274
          file_names.erase(file_id);
 
275
        }
287
276
      }
288
277
      return res;
289
278
    }
 
279
 
290
280
  Exit_status process(Create_file_log_event *ce);
291
281
  Exit_status process(Begin_load_query_log_event *ce);
292
282
  Exit_status process(Append_block_log_event *ae);
429
419
  Exit_status retval= OK_CONTINUE;
430
420
  char *fname, *ptr;
431
421
  File file;
432
 
  File_name_record rec;
 
422
  File_name_record *rec;
433
423
 
434
424
 
435
425
  if (!(fname= (char*) my_malloc(full_len,MYF(MY_WME))))
453
443
    return(ERROR_STOP);
454
444
  }
455
445
 
456
 
  rec.fname= fname;
457
 
  rec.event= ce;
 
446
  rec= (File_name_record *)malloc(sizeof(File_name_record));
 
447
  rec->fname= fname;
 
448
  rec->event= ce;
458
449
 
459
 
  if (set_dynamic(&file_names, (uchar*)&rec, file_id))
460
 
  {
461
 
    error("Out of memory.");
462
 
    delete ce;
463
 
    return(ERROR_STOP);
464
 
  }
 
450
  file_names[file_id]= rec;
465
451
 
466
452
  if (ce)
467
453
    ce->set_fname_outside_temp_buf(fname, strlen(fname));
542
528
Exit_status Load_log_processor::process(Append_block_log_event *ae)
543
529
{
544
530
 
545
 
  const char* fname= ((ae->file_id < file_names.elements) ?
546
 
                       dynamic_element(&file_names, ae->file_id,
547
 
                                       File_name_record*)->fname : 0);
 
531
 
 
532
  const char* fname= 0;
 
533
  File_name_record *ptr= file_names[ae->file_id];
 
534
  if (ptr != NULL)
 
535
  {
 
536
    fname= ptr->fname;
 
537
  }
548
538
 
549
539
  if (fname)
550
540
  {
1912
1902
    dirname_for_local_load= my_strdup(my_tmpdir(&tmpdir), MY_WME);
1913
1903
  }
1914
1904
 
1915
 
  if (load_processor.init())
1916
 
    exit(1);
1917
1905
  if (dirname_for_local_load)
1918
1906
    load_processor.init_by_dir_name(dirname_for_local_load);
1919
1907
  else