~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/csv/ha_tina.cc

  • Committer: Monty Taylor
  • Date: 2008-09-15 17:24:04 UTC
  • Revision ID: monty@inaugust.com-20080915172404-ygh6hiyu0q7qpa9x
Removed strndup calls.

Show diffs side-by-side

added added

removed removed

Lines of Context:
42
42
*/
43
43
#include <drizzled/common_includes.h>
44
44
#include "ha_tina.h"
45
 
#include <drizzled/error.h>
46
45
 
47
46
 
48
47
/*
49
 
  unsigned char + unsigned char + uint64_t + uint64_t + uint64_t + uint64_t + unsigned char
 
48
  uchar + uchar + uint64_t + uint64_t + uint64_t + uint64_t + uchar
50
49
*/
51
 
#define META_BUFFER_SIZE sizeof(unsigned char) + sizeof(unsigned char) + sizeof(uint64_t) \
52
 
  + sizeof(uint64_t) + sizeof(uint64_t) + sizeof(uint64_t) + sizeof(unsigned char)
 
50
#define META_BUFFER_SIZE sizeof(uchar) + sizeof(uchar) + sizeof(uint64_t) \
 
51
  + sizeof(uint64_t) + sizeof(uint64_t) + sizeof(uint64_t) + sizeof(uchar)
53
52
#define TINA_CHECK_HEADER 254 // The number we use to determine corruption
54
53
#define BLOB_MEMROOT_ALLOC_SIZE 8192
55
54
 
92
91
  return ( a->begin > b->begin ? 1 : ( a->begin < b->begin ? -1 : 0 ) );
93
92
}
94
93
 
95
 
static unsigned char* tina_get_key(TINA_SHARE *share, size_t *length,
 
94
static uchar* tina_get_key(TINA_SHARE *share, size_t *length,
96
95
                          bool not_used __attribute__((unused)))
97
96
{
98
97
  *length=share->table_name_length;
99
 
  return (unsigned char*) share->table_name;
 
98
  return (uchar*) share->table_name;
100
99
}
101
100
 
102
101
static int tina_init_func(void *p)
104
103
  handlerton *tina_hton;
105
104
 
106
105
  tina_hton= (handlerton *)p;
107
 
  pthread_mutex_init(&tina_mutex,MY_MUTEX_INIT_FAST);
 
106
  VOID(pthread_mutex_init(&tina_mutex,MY_MUTEX_INIT_FAST));
108
107
  (void) hash_init(&tina_open_tables,system_charset_info,32,0,0,
109
108
                   (hash_get_key) tina_get_key,0,0);
110
109
  tina_hton->state= SHOW_OPTION_YES;
 
110
  tina_hton->db_type= DB_TYPE_CSV_DB;
111
111
  tina_hton->create= tina_create_handler;
112
112
  tina_hton->flags= (HTON_CAN_RECREATE | HTON_SUPPORT_LOG_TABLES | 
113
113
                     HTON_NO_PARTITION);
133
133
  char meta_file_name[FN_REFLEN];
134
134
  struct stat file_stat;
135
135
  char *tmp_name;
136
 
  uint32_t length;
 
136
  uint length;
137
137
 
138
138
  pthread_mutex_lock(&tina_mutex);
139
139
  length=(uint) strlen(table_name);
143
143
    initialize its members.
144
144
  */
145
145
  if (!(share=(TINA_SHARE*) hash_search(&tina_open_tables,
146
 
                                        (unsigned char*) table_name,
 
146
                                        (uchar*) table_name,
147
147
                                       length)))
148
148
  {
149
149
    if (!my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
150
150
                         &share, sizeof(*share),
151
151
                         &tmp_name, length+1,
152
 
                         NULL))
 
152
                         NullS))
153
153
    {
154
154
      pthread_mutex_unlock(&tina_mutex);
155
155
      return NULL;
163
163
    share->update_file_opened= false;
164
164
    share->tina_write_opened= false;
165
165
    share->data_file_version= 0;
166
 
    my_stpcpy(share->table_name, table_name);
 
166
    stpcpy(share->table_name, table_name);
167
167
    fn_format(share->data_file_name, table_name, "", CSV_EXT,
168
168
              MY_REPLACE_EXT|MY_UNPACK_FILENAME);
169
169
    fn_format(meta_file_name, table_name, "", CSM_EXT,
173
173
      goto error;
174
174
    share->saved_data_file_length= file_stat.st_size;
175
175
 
176
 
    if (my_hash_insert(&tina_open_tables, (unsigned char*) share))
 
176
    if (my_hash_insert(&tina_open_tables, (uchar*) share))
177
177
      goto error;
178
178
    thr_lock_init(&share->lock);
179
179
    pthread_mutex_init(&share->mutex,MY_MUTEX_INIT_FAST);
202
202
 
203
203
error:
204
204
  pthread_mutex_unlock(&tina_mutex);
205
 
  free((unsigned char*) share);
 
205
  my_free((uchar*) share, MYF(0));
206
206
 
207
207
  return NULL;
208
208
}
229
229
 
230
230
static int read_meta_file(File meta_file, ha_rows *rows)
231
231
{
232
 
  unsigned char meta_buffer[META_BUFFER_SIZE];
233
 
  unsigned char *ptr= meta_buffer;
 
232
  uchar meta_buffer[META_BUFFER_SIZE];
 
233
  uchar *ptr= meta_buffer;
234
234
 
235
 
  my_seek(meta_file, 0, MY_SEEK_SET, MYF(0));
236
 
  if (my_read(meta_file, (unsigned char*)meta_buffer, META_BUFFER_SIZE, 0)
 
235
  VOID(my_seek(meta_file, 0, MY_SEEK_SET, MYF(0)));
 
236
  if (my_read(meta_file, (uchar*)meta_buffer, META_BUFFER_SIZE, 0)
237
237
      != META_BUFFER_SIZE)
238
238
    return(HA_ERR_CRASHED_ON_USAGE);
239
239
 
241
241
    Parse out the meta data, we ignore version at the moment
242
242
  */
243
243
 
244
 
  ptr+= sizeof(unsigned char)*2; // Move past header
 
244
  ptr+= sizeof(uchar)*2; // Move past header
245
245
  *rows= (ha_rows)uint8korr(ptr);
246
246
  ptr+= sizeof(uint64_t); // Move past rows
247
247
  /*
251
251
  ptr+= 3*sizeof(uint64_t);
252
252
 
253
253
  /* check crashed bit and magic number */
254
 
  if ((meta_buffer[0] != (unsigned char)TINA_CHECK_HEADER) ||
 
254
  if ((meta_buffer[0] != (uchar)TINA_CHECK_HEADER) ||
255
255
      ((bool)(*ptr)== true))
256
256
    return(HA_ERR_CRASHED_ON_USAGE);
257
257
 
282
282
 
283
283
static int write_meta_file(File meta_file, ha_rows rows, bool dirty)
284
284
{
285
 
  unsigned char meta_buffer[META_BUFFER_SIZE];
286
 
  unsigned char *ptr= meta_buffer;
 
285
  uchar meta_buffer[META_BUFFER_SIZE];
 
286
  uchar *ptr= meta_buffer;
287
287
 
288
 
  *ptr= (unsigned char)TINA_CHECK_HEADER;
289
 
  ptr+= sizeof(unsigned char);
290
 
  *ptr= (unsigned char)TINA_VERSION;
291
 
  ptr+= sizeof(unsigned char);
 
288
  *ptr= (uchar)TINA_CHECK_HEADER;
 
289
  ptr+= sizeof(uchar);
 
290
  *ptr= (uchar)TINA_VERSION;
 
291
  ptr+= sizeof(uchar);
292
292
  int8store(ptr, (uint64_t)rows);
293
293
  ptr+= sizeof(uint64_t);
294
294
  memset(ptr, 0, 3*sizeof(uint64_t));
297
297
     We'll need them later.
298
298
  */
299
299
  ptr+= 3*sizeof(uint64_t);
300
 
  *ptr= (unsigned char)dirty;
 
300
  *ptr= (uchar)dirty;
301
301
 
302
 
  my_seek(meta_file, 0, MY_SEEK_SET, MYF(0));
303
 
  if (my_write(meta_file, (unsigned char *)meta_buffer, META_BUFFER_SIZE, 0)
 
302
  VOID(my_seek(meta_file, 0, MY_SEEK_SET, MYF(0)));
 
303
  if (my_write(meta_file, (uchar *)meta_buffer, META_BUFFER_SIZE, 0)
304
304
      != META_BUFFER_SIZE)
305
305
    return(-1);
306
306
 
309
309
  return(0);
310
310
}
311
311
 
312
 
bool ha_tina::check_and_repair(Session *session)
 
312
bool ha_tina::check_and_repair(THD *thd)
313
313
{
314
314
  HA_CHECK_OPT check_opt;
315
315
 
316
316
  check_opt.init();
317
317
 
318
 
  return(repair(session, &check_opt));
 
318
  return(repair(thd, &check_opt));
319
319
}
320
320
 
321
321
 
365
365
      share->tina_write_opened= false;
366
366
    }
367
367
 
368
 
    hash_delete(&tina_open_tables, (unsigned char*) share);
 
368
    hash_delete(&tina_open_tables, (uchar*) share);
369
369
    thr_lock_delete(&share->lock);
370
370
    pthread_mutex_destroy(&share->mutex);
371
 
    free((unsigned char*) share);
 
371
    my_free((uchar*) share, MYF(0));
372
372
  }
373
373
  pthread_mutex_unlock(&tina_mutex);
374
374
 
443
443
  Encode a buffer into the quoted format.
444
444
*/
445
445
 
446
 
int ha_tina::encode_quote(unsigned char *buf __attribute__((unused)))
 
446
int ha_tina::encode_quote(uchar *buf __attribute__((unused)))
447
447
{
448
448
  char attribute_buffer[1024];
449
449
  String attribute(attribute_buffer, sizeof(attribute_buffer),
545
545
      if (chain_alloced)
546
546
      {
547
547
        /* Must cast since my_malloc unlike malloc doesn't have a void ptr */
548
 
        if ((chain= (tina_set *) my_realloc((unsigned char*)chain,
 
548
        if ((chain= (tina_set *) my_realloc((uchar*)chain,
549
549
                                            chain_size, MYF(MY_WME))) == NULL)
550
550
          return -1;
551
551
      }
571
571
/*
572
572
  Scans for a row.
573
573
*/
574
 
int ha_tina::find_current_row(unsigned char *buf)
 
574
int ha_tina::find_current_row(uchar *buf)
575
575
{
576
576
  off_t end_offset, curr_offset= current_position;
577
577
  int eoln_len;
668
668
      if ((*field)->flags & BLOB_FLAG)
669
669
      {
670
670
        Field_blob *blob= *(Field_blob**) field;
671
 
        unsigned char *src, *tgt;
672
 
        uint32_t length, packlength;
 
671
        uchar *src, *tgt;
 
672
        uint length, packlength;
673
673
        
674
674
        packlength= blob->pack_length_no_ptr();
675
675
        length= blob->get_length(blob->ptr);
676
676
        memcpy(&src, blob->ptr + packlength, sizeof(char*));
677
677
        if (src)
678
678
        {
679
 
          tgt= (unsigned char*) alloc_root(&blobroot, length);
 
679
          tgt= (uchar*) alloc_root(&blobroot, length);
680
680
          memcpy(tgt, src, length);
681
681
          memcpy(blob->ptr + packlength, &tgt, sizeof(char*));
682
682
        }
698
698
static const char *ha_tina_exts[] = {
699
699
  CSV_EXT,
700
700
  CSM_EXT,
701
 
  NULL
 
701
  NullS
702
702
};
703
703
 
704
704
const char **ha_tina::bas_ext() const
781
781
  that need to be reset should be kept in the ::extra() call.
782
782
*/
783
783
int ha_tina::open(const char *name, int mode __attribute__((unused)),
784
 
                  uint32_t open_options)
 
784
                  uint open_options)
785
785
{
786
786
  if (!(share= get_share(name, table)))
787
787
    return(HA_ERR_OUT_OF_MEM);
828
828
  of the file and appends the data. In an error case it really should
829
829
  just truncate to the original position (this is not done yet).
830
830
*/
831
 
int ha_tina::write_row(unsigned char * buf)
 
831
int ha_tina::write_row(uchar * buf)
832
832
{
833
833
  int size;
834
834
 
847
847
      return(-1);
848
848
 
849
849
   /* use pwrite, as concurrent reader could have changed the position */
850
 
  if (my_write(share->tina_write_filedes, (unsigned char*)buffer.ptr(), size,
 
850
  if (my_write(share->tina_write_filedes, (uchar*)buffer.ptr(), size,
851
851
               MYF(MY_WME | MY_NABP)))
852
852
    return(-1);
853
853
 
891
891
  This will be called in a table scan right before the previous ::rnd_next()
892
892
  call.
893
893
*/
894
 
int ha_tina::update_row(const unsigned char * old_data __attribute__((unused)),
895
 
                        unsigned char * new_data)
 
894
int ha_tina::update_row(const uchar * old_data __attribute__((unused)),
 
895
                        uchar * new_data)
896
896
{
897
897
  int size;
898
898
  int rc= -1;
917
917
  if (open_update_temp_file_if_needed())
918
918
    goto err;
919
919
 
920
 
  if (my_write(update_temp_file, (unsigned char*)buffer.ptr(), size,
 
920
  if (my_write(update_temp_file, (uchar*)buffer.ptr(), size,
921
921
               MYF(MY_WME | MY_NABP)))
922
922
    goto err;
923
923
  temp_file_length+= size;
937
937
  The table will then be deleted/positioned based on the ORDER (so RANDOM,
938
938
  DESC, ASC).
939
939
*/
940
 
int ha_tina::delete_row(const unsigned char * buf __attribute__((unused)))
 
940
int ha_tina::delete_row(const uchar * buf __attribute__((unused)))
941
941
{
942
942
  ha_statistic_increment(&SSV::ha_delete_count);
943
943
 
1043
1043
  NULL and "". This is ok since this table handler is for spreadsheets and
1044
1044
  they don't know about them either :)
1045
1045
*/
1046
 
int ha_tina::rnd_next(unsigned char *buf)
 
1046
int ha_tina::rnd_next(uchar *buf)
1047
1047
{
1048
1048
  int rc;
1049
1049
 
1074
1074
  its just a position. Look at the bdb code if you want to see a case
1075
1075
  where something other then a number is stored.
1076
1076
*/
1077
 
void ha_tina::position(const unsigned char *record __attribute__((unused)))
 
1077
void ha_tina::position(const uchar *record __attribute__((unused)))
1078
1078
{
1079
1079
  my_store_ptr(ref, ref_length, current_position);
1080
1080
  return;
1086
1086
  my_get_ptr() retrieves the data for you.
1087
1087
*/
1088
1088
 
1089
 
int ha_tina::rnd_pos(unsigned char * buf, unsigned char *pos)
 
1089
int ha_tina::rnd_pos(uchar * buf, uchar *pos)
1090
1090
{
1091
1091
  ha_statistic_increment(&SSV::ha_read_rnd_count);
1092
1092
  current_position= (off_t)my_get_ptr(pos,ref_length);
1098
1098
  Currently this table handler doesn't implement most of the fields
1099
1099
  really needed. SHOW also makes use of this data
1100
1100
*/
1101
 
int ha_tina::info(uint32_t flag __attribute__((unused)))
 
1101
int ha_tina::info(uint flag __attribute__((unused)))
1102
1102
{
1103
1103
  /* This is a lie, but you don't want the optimizer to see zero or 1 */
1104
1104
  if (!records_is_known && stats.records < 2) 
1116
1116
  if (closest_hole == chain_ptr) /* no more chains */
1117
1117
    *end_pos= file_buff->end();
1118
1118
  else
1119
 
    *end_pos= std::min(file_buff->end(),
1120
 
                       closest_hole->begin);
 
1119
    *end_pos= min(file_buff->end(),
 
1120
                  closest_hole->begin);
1121
1121
  return (closest_hole != chain_ptr) && (*end_pos == closest_hole->begin);
1122
1122
}
1123
1123
 
1169
1169
      if (write_length)
1170
1170
      {
1171
1171
        if (my_write(update_temp_file, 
1172
 
                     (unsigned char*) (file_buff->ptr() +
 
1172
                     (uchar*) (file_buff->ptr() +
1173
1173
                               (write_begin - file_buff->start())),
1174
1174
                     write_length, MYF_RW))
1175
1175
          goto error;
1257
1257
 
1258
1258
  SYNOPSIS
1259
1259
    repair()
1260
 
    session         The thread, performing repair
 
1260
    thd         The thread, performing repair
1261
1261
    check_opt   The options for repair. We do not use it currently.
1262
1262
 
1263
1263
  DESCRIPTION
1270
1270
         rows (after the first bad one) as well.
1271
1271
*/
1272
1272
 
1273
 
int ha_tina::repair(Session* session,
 
1273
int ha_tina::repair(THD* thd,
1274
1274
                    HA_CHECK_OPT* check_opt __attribute__((unused)))
1275
1275
{
1276
1276
  char repaired_fname[FN_REFLEN];
1277
 
  unsigned char *buf;
 
1277
  uchar *buf;
1278
1278
  File repair_file;
1279
1279
  int rc;
1280
1280
  ha_rows rows_repaired= 0;
1289
1289
 
1290
1290
  /* Don't assert in field::val() functions */
1291
1291
  table->use_all_columns();
1292
 
  if (!(buf= (unsigned char*) my_malloc(table->s->reclength, MYF(MY_WME))))
 
1292
  if (!(buf= (uchar*) my_malloc(table->s->reclength, MYF(MY_WME))))
1293
1293
    return(HA_ERR_OUT_OF_MEM);
1294
1294
 
1295
1295
  /* position buffer to the start of the file */
1310
1310
  /* Read the file row-by-row. If everything is ok, repair is not needed. */
1311
1311
  while (!(rc= find_current_row(buf)))
1312
1312
  {
1313
 
    session_inc_row_count(session);
 
1313
    thd_inc_row_count(thd);
1314
1314
    rows_repaired++;
1315
1315
    current_position= next_position;
1316
1316
  }
1317
1317
 
1318
1318
  free_root(&blobroot, MYF(0));
1319
1319
 
1320
 
  free((char*)buf);
 
1320
  my_free((char*)buf, MYF(0));
1321
1321
 
1322
1322
  if (rc == HA_ERR_END_OF_FILE)
1323
1323
  {
1349
1349
  /* write repaired file */
1350
1350
  while (1)
1351
1351
  {
1352
 
    write_end= std::min(file_buff->end(), current_position);
 
1352
    write_end= min(file_buff->end(), current_position);
1353
1353
    if ((write_end - write_begin) &&
1354
 
        (my_write(repair_file, (unsigned char*)file_buff->ptr(),
 
1354
        (my_write(repair_file, (uchar*)file_buff->ptr(),
1355
1355
                  write_end - write_begin, MYF_RW)))
1356
1356
      return(-1);
1357
1357
 
1416
1416
  Called by the database to lock the table. Keep in mind that this
1417
1417
  is an internal lock.
1418
1418
*/
1419
 
THR_LOCK_DATA **ha_tina::store_lock(Session *session __attribute__((unused)),
 
1419
THR_LOCK_DATA **ha_tina::store_lock(THD *thd __attribute__((unused)),
1420
1420
                                    THR_LOCK_DATA **to,
1421
1421
                                    enum thr_lock_type lock_type)
1422
1422
{
1468
1468
  return(0);
1469
1469
}
1470
1470
 
1471
 
int ha_tina::check(Session* session,
 
1471
int ha_tina::check(THD* thd,
1472
1472
                   HA_CHECK_OPT* check_opt __attribute__((unused)))
1473
1473
{
1474
1474
  int rc= 0;
1475
 
  unsigned char *buf;
 
1475
  uchar *buf;
1476
1476
  const char *old_proc_info;
1477
1477
  ha_rows count= share->rows_recorded;
1478
1478
 
1479
 
  old_proc_info= get_session_proc_info(session);
1480
 
  set_session_proc_info(session, "Checking table");
1481
 
  if (!(buf= (unsigned char*) my_malloc(table->s->reclength, MYF(MY_WME))))
 
1479
  old_proc_info= thd_proc_info(thd, "Checking table");
 
1480
  if (!(buf= (uchar*) my_malloc(table->s->reclength, MYF(MY_WME))))
1482
1481
    return(HA_ERR_OUT_OF_MEM);
1483
1482
 
1484
1483
  /* position buffer to the start of the file */
1499
1498
  /* Read the file row-by-row. If everything is ok, repair is not needed. */
1500
1499
  while (!(rc= find_current_row(buf)))
1501
1500
  {
1502
 
    session_inc_row_count(session);
 
1501
    thd_inc_row_count(thd);
1503
1502
    count--;
1504
1503
    current_position= next_position;
1505
1504
  }
1506
1505
  
1507
1506
  free_root(&blobroot, MYF(0));
1508
1507
 
1509
 
  free((char*)buf);
1510
 
  set_session_proc_info(session, old_proc_info);
 
1508
  my_free((char*)buf, MYF(0));
 
1509
  thd_proc_info(thd, old_proc_info);
1511
1510
 
1512
1511
  if ((rc != HA_ERR_END_OF_FILE) || count)
1513
1512
  {
1520
1519
 
1521
1520
 
1522
1521
bool ha_tina::check_if_incompatible_data(HA_CREATE_INFO *info __attribute__((unused)),
1523
 
                                         uint32_t table_changes __attribute__((unused)))
 
1522
                                         uint table_changes __attribute__((unused)))
1524
1523
{
1525
1524
  return COMPATIBLE_DATA_YES;
1526
1525
}