44
#ifdef USE_PRAGMA_IMPLEMENTATION
45
#pragma implementation // gcc: Class implementation
48
#include "mysql_priv.h"
49
#include <mysql/plugin.h>
43
#include <drizzled/common_includes.h>
50
44
#include "ha_tina.h"
54
uchar + uchar + uint64_t + uint64_t + uint64_t + uint64_t + uchar
48
unsigned char + unsigned char + uint64_t + uint64_t + uint64_t + uint64_t + unsigned char
56
#define META_BUFFER_SIZE sizeof(uchar) + sizeof(uchar) + sizeof(uint64_t) \
57
+ sizeof(uint64_t) + sizeof(uint64_t) + sizeof(uint64_t) + sizeof(uchar)
50
#define META_BUFFER_SIZE sizeof(unsigned char) + sizeof(unsigned char) + sizeof(uint64_t) \
51
+ sizeof(uint64_t) + sizeof(uint64_t) + sizeof(uint64_t) + sizeof(unsigned char)
58
52
#define TINA_CHECK_HEADER 254 // The number we use to determine corruption
59
53
#define BLOB_MEMROOT_ALLOC_SIZE 8192
64
58
#define CSM_EXT ".CSM" // Meta file
67
static TINA_SHARE *get_share(const char *table_name, TABLE *table);
61
static TINA_SHARE *get_share(const char *table_name, Table *table);
68
62
static int free_share(TINA_SHARE *share);
69
63
static int read_meta_file(File meta_file, ha_rows *rows);
70
64
static int write_meta_file(File meta_file, ha_rows rows, bool dirty);
97
91
return ( a->begin > b->begin ? 1 : ( a->begin < b->begin ? -1 : 0 ) );
100
static uchar* tina_get_key(TINA_SHARE *share, size_t *length,
94
static unsigned char* tina_get_key(TINA_SHARE *share, size_t *length,
101
95
bool not_used __attribute__((unused)))
103
97
*length=share->table_name_length;
104
return (uchar*) share->table_name;
98
return (unsigned char*) share->table_name;
107
101
static int tina_init_func(void *p)
109
103
handlerton *tina_hton;
111
105
tina_hton= (handlerton *)p;
112
VOID(pthread_mutex_init(&tina_mutex,MY_MUTEX_INIT_FAST));
106
pthread_mutex_init(&tina_mutex,MY_MUTEX_INIT_FAST);
113
107
(void) hash_init(&tina_open_tables,system_charset_info,32,0,0,
114
108
(hash_get_key) tina_get_key,0,0);
115
109
tina_hton->state= SHOW_OPTION_YES;
116
tina_hton->db_type= DB_TYPE_CSV_DB;
117
110
tina_hton->create= tina_create_handler;
118
111
tina_hton->flags= (HTON_CAN_RECREATE | HTON_SUPPORT_LOG_TABLES |
119
112
HTON_NO_PARTITION);
123
static int tina_done_func(void *p __attribute__((__unused__)))
116
static int tina_done_func(void *p __attribute__((unused)))
125
118
hash_free(&tina_open_tables);
126
119
pthread_mutex_destroy(&tina_mutex);
133
126
Simple lock controls.
135
128
static TINA_SHARE *get_share(const char *table_name,
136
TABLE *table __attribute__((__unused__)))
129
Table *table __attribute__((unused)))
138
131
TINA_SHARE *share;
139
132
char meta_file_name[FN_REFLEN];
140
133
struct stat file_stat;
144
137
pthread_mutex_lock(&tina_mutex);
145
138
length=(uint) strlen(table_name);
149
142
initialize its members.
151
144
if (!(share=(TINA_SHARE*) hash_search(&tina_open_tables,
145
(unsigned char*) table_name,
155
148
if (!my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
156
149
&share, sizeof(*share),
157
150
&tmp_name, length+1,
160
153
pthread_mutex_unlock(&tina_mutex);
164
157
share->use_count= 0;
165
share->is_log_table= false;
166
158
share->table_name_length= length;
167
159
share->table_name= tmp_name;
168
160
share->crashed= false;
170
162
share->update_file_opened= false;
171
163
share->tina_write_opened= false;
172
164
share->data_file_version= 0;
173
strmov(share->table_name, table_name);
165
my_stpcpy(share->table_name, table_name);
174
166
fn_format(share->data_file_name, table_name, "", CSV_EXT,
175
167
MY_REPLACE_EXT|MY_UNPACK_FILENAME);
176
168
fn_format(meta_file_name, table_name, "", CSM_EXT,
181
173
share->saved_data_file_length= file_stat.st_size;
183
if (my_hash_insert(&tina_open_tables, (uchar*) share))
175
if (my_hash_insert(&tina_open_tables, (unsigned char*) share))
185
177
thr_lock_init(&share->lock);
186
178
pthread_mutex_init(&share->mutex,MY_MUTEX_INIT_FAST);
237
229
static int read_meta_file(File meta_file, ha_rows *rows)
239
uchar meta_buffer[META_BUFFER_SIZE];
240
uchar *ptr= meta_buffer;
242
DBUG_ENTER("ha_tina::read_meta_file");
244
VOID(my_seek(meta_file, 0, MY_SEEK_SET, MYF(0)));
245
if (my_read(meta_file, (uchar*)meta_buffer, META_BUFFER_SIZE, 0)
231
unsigned char meta_buffer[META_BUFFER_SIZE];
232
unsigned char *ptr= meta_buffer;
234
my_seek(meta_file, 0, MY_SEEK_SET, MYF(0));
235
if (my_read(meta_file, (unsigned char*)meta_buffer, META_BUFFER_SIZE, 0)
246
236
!= META_BUFFER_SIZE)
247
DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
237
return(HA_ERR_CRASHED_ON_USAGE);
250
240
Parse out the meta data, we ignore version at the moment
253
ptr+= sizeof(uchar)*2; // Move past header
243
ptr+= sizeof(unsigned char)*2; // Move past header
254
244
*rows= (ha_rows)uint8korr(ptr);
255
245
ptr+= sizeof(uint64_t); // Move past rows
260
250
ptr+= 3*sizeof(uint64_t);
262
252
/* check crashed bit and magic number */
263
if ((meta_buffer[0] != (uchar)TINA_CHECK_HEADER) ||
253
if ((meta_buffer[0] != (unsigned char)TINA_CHECK_HEADER) ||
264
254
((bool)(*ptr)== true))
265
DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
255
return(HA_ERR_CRASHED_ON_USAGE);
267
257
my_sync(meta_file, MYF(MY_WME));
292
282
static int write_meta_file(File meta_file, ha_rows rows, bool dirty)
294
uchar meta_buffer[META_BUFFER_SIZE];
295
uchar *ptr= meta_buffer;
297
DBUG_ENTER("ha_tina::write_meta_file");
299
*ptr= (uchar)TINA_CHECK_HEADER;
301
*ptr= (uchar)TINA_VERSION;
284
unsigned char meta_buffer[META_BUFFER_SIZE];
285
unsigned char *ptr= meta_buffer;
287
*ptr= (unsigned char)TINA_CHECK_HEADER;
288
ptr+= sizeof(unsigned char);
289
*ptr= (unsigned char)TINA_VERSION;
290
ptr+= sizeof(unsigned char);
303
291
int8store(ptr, (uint64_t)rows);
304
292
ptr+= sizeof(uint64_t);
305
293
memset(ptr, 0, 3*sizeof(uint64_t));
308
296
We'll need them later.
310
298
ptr+= 3*sizeof(uint64_t);
299
*ptr= (unsigned char)dirty;
313
VOID(my_seek(meta_file, 0, MY_SEEK_SET, MYF(0)));
314
if (my_write(meta_file, (uchar *)meta_buffer, META_BUFFER_SIZE, 0)
301
my_seek(meta_file, 0, MY_SEEK_SET, MYF(0));
302
if (my_write(meta_file, (unsigned char *)meta_buffer, META_BUFFER_SIZE, 0)
315
303
!= META_BUFFER_SIZE)
318
306
my_sync(meta_file, MYF(MY_WME));
323
311
bool ha_tina::check_and_repair(THD *thd)
325
313
HA_CHECK_OPT check_opt;
326
DBUG_ENTER("ha_tina::check_and_repair");
328
315
check_opt.init();
330
DBUG_RETURN(repair(thd, &check_opt));
317
return(repair(thd, &check_opt));
334
321
int ha_tina::init_tina_writer()
336
DBUG_ENTER("ha_tina::init_tina_writer");
339
324
Mark the file as crashed. We will set the flag back when we close
340
325
the file. In the case of the crash it will remain marked crashed,
345
330
if ((share->tina_write_filedes=
346
331
my_open(share->data_file_name, O_RDWR|O_APPEND, MYF(0))) == -1)
348
DBUG_PRINT("info", ("Could not open tina file writes"));
349
333
share->crashed= true;
352
336
share->tina_write_opened= true;
358
342
bool ha_tina::is_crashed() const
360
DBUG_ENTER("ha_tina::is_crashed");
361
DBUG_RETURN(share->crashed);
344
return(share->crashed);
382
364
share->tina_write_opened= false;
385
hash_delete(&tina_open_tables, (uchar*) share);
367
hash_delete(&tina_open_tables, (unsigned char*) share);
386
368
thr_lock_delete(&share->lock);
387
369
pthread_mutex_destroy(&share->mutex);
388
my_free((uchar*) share, MYF(0));
370
free((unsigned char*) share);
390
372
pthread_mutex_unlock(&tina_mutex);
392
DBUG_RETURN(result_code);
460
442
Encode a buffer into the quoted format.
463
int ha_tina::encode_quote(uchar *buf __attribute__((__unused__)))
445
int ha_tina::encode_quote(unsigned char *buf __attribute__((unused)))
465
447
char attribute_buffer[1024];
466
448
String attribute(attribute_buffer, sizeof(attribute_buffer),
467
449
&my_charset_bin);
469
my_bitmap_map *org_bitmap= dbug_tmp_use_all_columns(table, table->read_set);
470
451
buffer.length(0);
472
453
for (Field **field=table->field ; *field ; field++)
542
523
//buffer.replace(buffer.length(), 0, "\n", 1);
544
dbug_tmp_restore_column_map(table->read_set, org_bitmap);
545
525
return (buffer.length());
564
544
if (chain_alloced)
566
546
/* Must cast since my_malloc unlike malloc doesn't have a void ptr */
567
if ((chain= (tina_set *) my_realloc((uchar*)chain,
547
if ((chain= (tina_set *) my_realloc((unsigned char*)chain,
568
548
chain_size, MYF(MY_WME))) == NULL)
593
int ha_tina::find_current_row(uchar *buf)
573
int ha_tina::find_current_row(unsigned char *buf)
595
575
off_t end_offset, curr_offset= current_position;
597
my_bitmap_map *org_bitmap;
600
DBUG_ENTER("ha_tina::find_current_row");
602
580
free_root(&blobroot, MYF(MY_MARK_BLOCKS_FREE));
609
587
find_eoln_buff(file_buff, current_position,
610
588
local_saved_data_file_length, &eoln_len)) == 0)
611
DBUG_RETURN(HA_ERR_END_OF_FILE);
589
return(HA_ERR_END_OF_FILE);
613
591
/* We must read all columns in case a table is opened for update */
614
592
read_all= !bitmap_is_clear_all(table->write_set);
615
/* Avoid asserts in ::store() for columns that are not going to be updated */
616
org_bitmap= dbug_tmp_use_all_columns(table, table->write_set);
617
593
error= HA_ERR_CRASHED_ON_USAGE;
619
595
memset(buf, 0, table->s->null_bytes);
691
667
if ((*field)->flags & BLOB_FLAG)
693
669
Field_blob *blob= *(Field_blob**) field;
695
uint length, packlength;
670
unsigned char *src, *tgt;
671
uint32_t length, packlength;
697
673
packlength= blob->pack_length_no_ptr();
698
674
length= blob->get_length(blob->ptr);
699
memcpy_fixed(&src, blob->ptr + packlength, sizeof(char*));
675
memcpy(&src, blob->ptr + packlength, sizeof(char*));
702
tgt= (uchar*) alloc_root(&blobroot, length);
703
bmove(tgt, src, length);
704
memcpy_fixed(blob->ptr + packlength, &tgt, sizeof(char*));
678
tgt= (unsigned char*) alloc_root(&blobroot, length);
679
memcpy(tgt, src, length);
680
memcpy(blob->ptr + packlength, &tgt, sizeof(char*));
738
713
void tina_get_status(void* param,
739
int concurrent_insert __attribute__((__unused__)))
714
int concurrent_insert __attribute__((unused)))
741
716
ha_tina *tina= (ha_tina*) param;
742
717
tina->get_status();
769
744
void ha_tina::get_status()
771
if (share->is_log_table)
774
We have to use mutex to follow pthreads memory visibility
775
rules for share->saved_data_file_length
777
pthread_mutex_lock(&share->mutex);
778
local_saved_data_file_length= share->saved_data_file_length;
779
pthread_mutex_unlock(&share->mutex);
782
746
local_saved_data_file_length= share->saved_data_file_length;
800
764
For log tables concurrent insert works different. The reason is that
801
765
log tables are always opened and locked. And as they do not unlock
802
766
tables, the file length after writes should be updated in a different
803
way. For this purpose we need is_log_table flag. When this flag is set
804
we call update_status() explicitly after each row write.
807
770
void ha_tina::update_status()
816
779
this will not be called for every request. Any sort of positions
817
780
that need to be reset should be kept in the ::extra() call.
819
int ha_tina::open(const char *name, int mode __attribute__((__unused__)),
782
int ha_tina::open(const char *name, int mode __attribute__((unused)),
783
uint32_t open_options)
822
DBUG_ENTER("ha_tina::open");
824
785
if (!(share= get_share(name, table)))
825
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
786
return(HA_ERR_OUT_OF_MEM);
827
788
if (share->crashed && !(open_options & HA_OPEN_FOR_REPAIR))
829
790
free_share(share);
830
DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
791
return(HA_ERR_CRASHED_ON_USAGE);
833
794
local_data_file_version= share->data_file_version;
834
795
if ((data_file= my_open(share->data_file_name, O_RDONLY, MYF(0))) == -1)
838
799
Init locking. Pass handler object to the locking routines,
857
818
int ha_tina::close(void)
860
DBUG_ENTER("ha_tina::close");
861
821
rc= my_close(data_file, MYF(0));
862
DBUG_RETURN(free_share(share) || rc);
822
return(free_share(share) || rc);
867
827
of the file and appends the data. In an error case it really should
868
828
just truncate to the original position (this is not done yet).
870
int ha_tina::write_row(uchar * buf)
830
int ha_tina::write_row(unsigned char * buf)
873
DBUG_ENTER("ha_tina::write_row");
875
834
if (share->crashed)
876
DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
835
return(HA_ERR_CRASHED_ON_USAGE);
878
837
ha_statistic_increment(&SSV::ha_write_count);
885
844
if (!share->tina_write_opened)
886
845
if (init_tina_writer())
889
848
/* use pwrite, as concurrent reader could have changed the position */
890
if (my_write(share->tina_write_filedes, (uchar*)buffer.ptr(), size,
849
if (my_write(share->tina_write_filedes, (unsigned char*)buffer.ptr(), size,
891
850
MYF(MY_WME | MY_NABP)))
894
853
/* update local copy of the max position to see our own changes */
895
854
local_saved_data_file_length+= size;
933
890
This will be called in a table scan right before the previous ::rnd_next()
936
int ha_tina::update_row(const uchar * old_data __attribute__((__unused__)),
893
int ha_tina::update_row(const unsigned char * old_data __attribute__((unused)),
894
unsigned char * new_data)
941
DBUG_ENTER("ha_tina::update_row");
943
899
ha_statistic_increment(&SSV::ha_update_count);
960
916
if (open_update_temp_file_if_needed())
963
if (my_write(update_temp_file, (uchar*)buffer.ptr(), size,
919
if (my_write(update_temp_file, (unsigned char*)buffer.ptr(), size,
964
920
MYF(MY_WME | MY_NABP)))
966
922
temp_file_length+= size;
969
/* UPDATE should never happen on the log tables */
970
DBUG_ASSERT(!share->is_log_table);
973
DBUG_PRINT("info",("rc = %d", rc));
984
936
The table will then be deleted/positioned based on the ORDER (so RANDOM,
987
int ha_tina::delete_row(const uchar * buf __attribute__((__unused__)))
939
int ha_tina::delete_row(const unsigned char * buf __attribute__((unused)))
989
DBUG_ENTER("ha_tina::delete_row");
990
941
ha_statistic_increment(&SSV::ha_delete_count);
992
943
if (chain_append())
996
947
/* Update shared info */
997
DBUG_ASSERT(share->rows_recorded);
948
assert(share->rows_recorded);
998
949
pthread_mutex_lock(&share->mutex);
999
950
share->rows_recorded--;
1000
951
pthread_mutex_unlock(&share->mutex);
1002
/* DELETE should never happen on the log table */
1003
DBUG_ASSERT(!share->is_log_table);
1067
int ha_tina::rnd_init(bool scan __attribute__((__unused__)))
1015
int ha_tina::rnd_init(bool scan __attribute__((unused)))
1069
DBUG_ENTER("ha_tina::rnd_init");
1071
1017
/* set buffer to the beginning of the file */
1072
1018
if (share->crashed || init_data_file())
1073
DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
1019
return(HA_ERR_CRASHED_ON_USAGE);
1075
1021
current_position= next_position= 0;
1076
1022
stats.records= 0;
1096
1042
NULL and "". This is ok since this table handler is for spreadsheets and
1097
1043
they don't know about them either :)
1099
int ha_tina::rnd_next(uchar *buf)
1045
int ha_tina::rnd_next(unsigned char *buf)
1102
DBUG_ENTER("ha_tina::rnd_next");
1104
1049
if (share->crashed)
1105
DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
1050
return(HA_ERR_CRASHED_ON_USAGE);
1107
1052
ha_statistic_increment(&SSV::ha_read_rnd_next_count);
1111
1056
/* don't scan an empty file */
1112
1057
if (!local_saved_data_file_length)
1113
DBUG_RETURN(HA_ERR_END_OF_FILE);
1058
return(HA_ERR_END_OF_FILE);
1115
1060
if ((rc= find_current_row(buf)))
1118
1063
stats.records++;
1128
1073
its just a position. Look at the bdb code if you want to see a case
1129
1074
where something other then a number is stored.
1131
void ha_tina::position(const uchar *record __attribute__((__unused__)))
1076
void ha_tina::position(const unsigned char *record __attribute__((unused)))
1133
DBUG_ENTER("ha_tina::position");
1134
1078
my_store_ptr(ref, ref_length, current_position);
1141
1085
my_get_ptr() retrieves the data for you.
1144
int ha_tina::rnd_pos(uchar * buf, uchar *pos)
1088
int ha_tina::rnd_pos(unsigned char * buf, unsigned char *pos)
1146
DBUG_ENTER("ha_tina::rnd_pos");
1147
1090
ha_statistic_increment(&SSV::ha_read_rnd_count);
1148
1091
current_position= (off_t)my_get_ptr(pos,ref_length);
1149
DBUG_RETURN(find_current_row(buf));
1092
return(find_current_row(buf));
1154
1097
Currently this table handler doesn't implement most of the fields
1155
1098
really needed. SHOW also makes use of this data
1157
int ha_tina::info(uint flag __attribute__((__unused__)))
1100
int ha_tina::info(uint32_t flag __attribute__((unused)))
1159
DBUG_ENTER("ha_tina::info");
1160
1102
/* This is a lie, but you don't want the optimizer to see zero or 1 */
1161
1103
if (!records_is_known && stats.records < 2)
1162
1104
stats.records= 2;
1173
1115
if (closest_hole == chain_ptr) /* no more chains */
1174
1116
*end_pos= file_buff->end();
1176
*end_pos= min(file_buff->end(),
1177
closest_hole->begin);
1118
*end_pos= std::min(file_buff->end(),
1119
closest_hole->begin);
1178
1120
return (closest_hole != chain_ptr) && (*end_pos == closest_hole->begin);
1190
1132
char updated_fname[FN_REFLEN];
1191
1133
off_t file_buffer_start= 0;
1192
DBUG_ENTER("ha_tina::rnd_end");
1194
1135
free_root(&blobroot, MYF(0));
1195
1136
records_is_known= 1;
1216
1157
/* create the file to write updated table if it wasn't yet created */
1217
1158
if (open_update_temp_file_if_needed())
1220
1161
/* write the file with updated info */
1221
1162
while ((file_buffer_start != -1)) // while not end of file
1227
1168
if (write_length)
1229
1170
if (my_write(update_temp_file,
1230
(uchar*) (file_buff->ptr() +
1171
(unsigned char*) (file_buff->ptr() +
1231
1172
(write_begin - file_buff->start())),
1232
1173
write_length, MYF_RW))
1252
1193
if (my_sync(update_temp_file, MYF(MY_WME)) ||
1253
1194
my_close(update_temp_file, MYF(0)))
1256
1197
share->update_file_opened= false;
1258
1199
if (share->tina_write_opened)
1260
1201
if (my_close(share->tina_write_filedes, MYF(0)))
1263
1204
Mark that the writer fd is closed, so that init_tina_writer()
1264
1205
will reopen it later.
1274
1215
my_rename(fn_format(updated_fname, share->table_name, "", CSN_EXT,
1275
1216
MY_REPLACE_EXT | MY_UNPACK_FILENAME),
1276
1217
share->data_file_name, MYF(0)))
1279
1220
/* Open the file again */
1280
1221
if (((data_file= my_open(share->data_file_name, O_RDONLY, MYF(0))) == -1))
1283
1224
As we reopened the data file, increase share->data_file_version
1284
1225
in order to force other threads waiting on a table lock and
1331
1272
int ha_tina::repair(THD* thd,
1332
HA_CHECK_OPT* check_opt __attribute__((__unused__)))
1273
HA_CHECK_OPT* check_opt __attribute__((unused)))
1334
1275
char repaired_fname[FN_REFLEN];
1336
1277
File repair_file;
1338
1279
ha_rows rows_repaired= 0;
1339
1280
off_t write_begin= 0, write_end;
1340
DBUG_ENTER("ha_tina::repair");
1342
1282
/* empty file */
1343
1283
if (!share->saved_data_file_length)
1349
1289
/* Don't assert in field::val() functions */
1350
1290
table->use_all_columns();
1351
if (!(buf= (uchar*) my_malloc(table->s->reclength, MYF(MY_WME))))
1352
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
1291
if (!(buf= (unsigned char*) my_malloc(table->s->reclength, MYF(MY_WME))))
1292
return(HA_ERR_OUT_OF_MEM);
1354
1294
/* position buffer to the start of the file */
1355
1295
if (init_data_file())
1356
DBUG_RETURN(HA_ERR_CRASHED_ON_REPAIR);
1296
return(HA_ERR_CRASHED_ON_REPAIR);
1359
1299
Local_saved_data_file_length is initialized during the lock phase.
1398
1338
MY_REPLACE_EXT|MY_UNPACK_FILENAME),
1399
1339
0, O_RDWR | O_TRUNC,MYF(MY_WME))) < 0)
1400
DBUG_RETURN(HA_ERR_CRASHED_ON_REPAIR);
1340
return(HA_ERR_CRASHED_ON_REPAIR);
1402
1342
file_buff->init_buff(data_file);
1408
1348
/* write repaired file */
1411
write_end= min(file_buff->end(), current_position);
1351
write_end= std::min(file_buff->end(), current_position);
1412
1352
if ((write_end - write_begin) &&
1413
(my_write(repair_file, (uchar*)file_buff->ptr(),
1353
(my_write(repair_file, (unsigned char*)file_buff->ptr(),
1414
1354
write_end - write_begin, MYF_RW)))
1417
1357
write_begin= write_end;
1418
1358
if (write_end== current_position)
1430
1370
if (my_close(data_file,MYF(0)) || my_close(repair_file, MYF(0)) ||
1431
1371
my_rename(repaired_fname, share->data_file_name, MYF(0)))
1434
1374
/* Open the file again, it should now be repaired */
1435
1375
if ((data_file= my_open(share->data_file_name, O_RDWR|O_APPEND,
1436
1376
MYF(0))) == -1)
1439
1379
/* Set new file size. The file size will be updated by ::update_status() */
1440
1380
local_saved_data_file_length= (size_t) current_position;
1443
1383
share->crashed= false;
1444
DBUG_RETURN(HA_ADMIN_OK);
1384
return(HA_ADMIN_OK);
1451
1391
int ha_tina::delete_all_rows()
1454
DBUG_ENTER("ha_tina::delete_all_rows");
1456
1395
if (!records_is_known)
1457
DBUG_RETURN(my_errno=HA_ERR_WRONG_COMMAND);
1396
return(my_errno=HA_ERR_WRONG_COMMAND);
1459
1398
if (!share->tina_write_opened)
1460
1399
if (init_tina_writer())
1463
1402
/* Truncate the file to zero size */
1464
1403
rc= ftruncate(share->tina_write_filedes, 0);
1469
1408
share->rows_recorded= 0;
1470
1409
pthread_mutex_unlock(&share->mutex);
1471
1410
local_saved_data_file_length= 0;
1476
1415
Called by the database to lock the table. Keep in mind that this
1477
1416
is an internal lock.
1479
THR_LOCK_DATA **ha_tina::store_lock(THD *thd __attribute__((__unused__)),
1418
THR_LOCK_DATA **ha_tina::store_lock(THD *thd __attribute__((unused)),
1480
1419
THR_LOCK_DATA **to,
1481
1420
enum thr_lock_type lock_type)
1491
1430
this (the database will call ::open() if it needs to).
1494
int ha_tina::create(const char *name, TABLE *table_arg,
1495
HA_CREATE_INFO *create_info __attribute__((__unused__)))
1433
int ha_tina::create(const char *name, Table *table_arg,
1434
HA_CREATE_INFO *create_info __attribute__((unused)))
1497
1436
char name_buff[FN_REFLEN];
1498
1437
File create_file;
1499
DBUG_ENTER("ha_tina::create");
1506
1444
if ((*field)->real_maybe_null())
1508
1446
my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), "nullable columns");
1509
DBUG_RETURN(HA_ERR_UNSUPPORTED);
1447
return(HA_ERR_UNSUPPORTED);
1514
1452
if ((create_file= my_create(fn_format(name_buff, name, "", CSM_EXT,
1515
1453
MY_REPLACE_EXT|MY_UNPACK_FILENAME), 0,
1516
1454
O_RDWR | O_TRUNC,MYF(MY_WME))) < 0)
1519
1457
write_meta_file(create_file, 0, false);
1520
1458
my_close(create_file, MYF(0));
1522
1460
if ((create_file= my_create(fn_format(name_buff, name, "", CSV_EXT,
1523
1461
MY_REPLACE_EXT|MY_UNPACK_FILENAME),0,
1524
1462
O_RDWR | O_TRUNC,MYF(MY_WME))) < 0)
1527
1465
my_close(create_file, MYF(0));
1532
1470
int ha_tina::check(THD* thd,
1533
HA_CHECK_OPT* check_opt __attribute__((__unused__)))
1471
HA_CHECK_OPT* check_opt __attribute__((unused)))
1537
1475
const char *old_proc_info;
1538
1476
ha_rows count= share->rows_recorded;
1539
DBUG_ENTER("ha_tina::check");
1541
old_proc_info= thd_proc_info(thd, "Checking table");
1542
if (!(buf= (uchar*) my_malloc(table->s->reclength, MYF(MY_WME))))
1543
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
1478
old_proc_info= get_thd_proc_info(thd);
1479
set_thd_proc_info(thd, "Checking table");
1480
if (!(buf= (unsigned char*) my_malloc(table->s->reclength, MYF(MY_WME))))
1481
return(HA_ERR_OUT_OF_MEM);
1545
1483
/* position buffer to the start of the file */
1546
1484
if (init_data_file())
1547
DBUG_RETURN(HA_ERR_CRASHED);
1485
return(HA_ERR_CRASHED);
1550
1488
Local_saved_data_file_length is initialized during the lock phase.
1568
1506
free_root(&blobroot, MYF(0));
1570
my_free((char*)buf, MYF(0));
1571
thd_proc_info(thd, old_proc_info);
1509
set_thd_proc_info(thd, old_proc_info);
1573
1511
if ((rc != HA_ERR_END_OF_FILE) || count)
1575
1513
share->crashed= true;
1576
DBUG_RETURN(HA_ADMIN_CORRUPT);
1514
return(HA_ADMIN_CORRUPT);
1579
DBUG_RETURN(HA_ADMIN_OK);
1517
return(HA_ADMIN_OK);
1583
bool ha_tina::check_if_incompatible_data(HA_CREATE_INFO *info __attribute__((__unused__)),
1584
uint table_changes __attribute__((__unused__)))
1521
bool ha_tina::check_if_incompatible_data(HA_CREATE_INFO *info __attribute__((unused)),
1522
uint32_t table_changes __attribute__((unused)))
1586
1524
return COMPATIBLE_DATA_YES;
1589
struct st_mysql_storage_engine csv_storage_engine=
1590
{ MYSQL_HANDLERTON_INTERFACE_VERSION };
1592
1527
mysql_declare_plugin(csv)
1594
MYSQL_STORAGE_ENGINE_PLUGIN,
1595
&csv_storage_engine,
1529
DRIZZLE_STORAGE_ENGINE_PLUGIN,
1597
1532
"Brian Aker, MySQL AB",
1598
1533
"CSV storage engine",
1599
1534
PLUGIN_LICENSE_GPL,
1600
1535
tina_init_func, /* Plugin Init */
1601
1536
tina_done_func, /* Plugin Deinit */
1603
1537
NULL, /* status variables */
1604
1538
NULL, /* system variables */
1605
1539
NULL /* config options */