25
25
#include <drizzled/message/table.pb.h>
26
26
#include <google/protobuf/io/zero_copy_stream.h>
27
27
#include <google/protobuf/io/zero_copy_stream_impl.h>
29
#include <drizzled/table_proto.h>
28
31
using namespace std;
30
int drizzle_read_table_proto(const char* path, drizzled::message::Table* table)
32
int fd= open(path, O_RDONLY);
37
google::protobuf::io::ZeroCopyInputStream* input=
38
new google::protobuf::io::FileInputStream(fd);
40
if (!table->ParseFromZeroCopyStream(input))
52
static int fill_table_proto(drizzled::message::Table *table_proto,
53
const char *table_name,
54
List<Create_field> &create_fields,
55
HA_CREATE_INFO *create_info,
59
Create_field *field_arg;
60
List_iterator<Create_field> it(create_fields);
61
drizzled::message::Table::StorageEngine *engine= table_proto->mutable_engine();
62
drizzled::message::Table::TableOptions *table_options= table_proto->mutable_options();
35
int fill_table_proto(message::Table *table_proto,
36
const char *table_name,
37
List<CreateField> &create_fields,
38
HA_CREATE_INFO *create_info,
42
CreateField *field_arg;
43
List_iterator<CreateField> it(create_fields);
44
message::Table::TableOptions *table_options= table_proto->mutable_options();
64
46
if (create_fields.elements > MAX_FIELDS)
70
engine->set_name(create_info->db_type->getName());
52
assert(strcmp(table_proto->engine().name().c_str(),
53
create_info->db_type->getName().c_str())==0);
72
55
assert(strcmp(table_proto->name().c_str(),table_name)==0);
74
57
while ((field_arg= it++))
76
drizzled::message::Table::Field *attribute;
59
message::Table::Field *attribute;
78
61
attribute= table_proto->add_field();
79
62
attribute->set_name(field_arg->field_name);
81
attribute->set_pack_flag(field_arg->pack_flag); /* TODO: MUST DIE */
83
if(f_maybe_null(field_arg->pack_flag))
64
if(! (field_arg->flags & NOT_NULL_FLAG))
85
drizzled::message::Table::Field::FieldConstraints *constraints;
66
message::Table::Field::FieldConstraints *constraints;
87
68
constraints= attribute->mutable_constraints();
88
69
constraints->set_is_nullable(true);
91
72
switch (field_arg->sql_type) {
92
case DRIZZLE_TYPE_TINY:
93
attribute->set_type(drizzled::message::Table::Field::TINYINT);
95
73
case DRIZZLE_TYPE_LONG:
96
attribute->set_type(drizzled::message::Table::Field::INTEGER);
74
attribute->set_type(message::Table::Field::INTEGER);
98
76
case DRIZZLE_TYPE_DOUBLE:
99
attribute->set_type(drizzled::message::Table::Field::DOUBLE);
78
attribute->set_type(drizzled::message::Table::Field::DOUBLE);
81
* For DOUBLE, we only add a specific scale and precision iff
82
* the fixed decimal point has been specified...
84
if (field_arg->decimals != NOT_FIXED_DEC)
86
drizzled::message::Table::Field::NumericFieldOptions *numeric_field_options;
88
numeric_field_options= attribute->mutable_numeric_options();
90
* Precision and scale are specified like so:
94
* From the CreateField, we get the "length", which is the *total* length
95
* of the double storage space, including the decimal point if there is a
96
* scale argument and a 1 byte length header. We also get the "decimals",
97
* which is actually the scale (the number of numbers stored after the decimal point)
99
* Therefore, PRECISION= LENGTH - 1 - (SCALE ? SCALE + 1 : 0)
101
if (field_arg->decimals)
102
numeric_field_options->set_precision(field_arg->length - 2); /* One for the decimal, one for the header */
104
numeric_field_options->set_precision(field_arg->length - 1); /* for the header */
105
numeric_field_options->set_scale(field_arg->decimals);
101
109
case DRIZZLE_TYPE_NULL :
102
110
assert(1); /* Not a user definable type */
103
111
case DRIZZLE_TYPE_TIMESTAMP:
104
attribute->set_type(drizzled::message::Table::Field::TIMESTAMP);
112
attribute->set_type(message::Table::Field::TIMESTAMP);
106
114
case DRIZZLE_TYPE_LONGLONG:
107
attribute->set_type(drizzled::message::Table::Field::BIGINT);
115
attribute->set_type(message::Table::Field::BIGINT);
109
117
case DRIZZLE_TYPE_DATETIME:
110
attribute->set_type(drizzled::message::Table::Field::DATETIME);
118
attribute->set_type(message::Table::Field::DATETIME);
112
120
case DRIZZLE_TYPE_DATE:
113
attribute->set_type(drizzled::message::Table::Field::DATE);
121
attribute->set_type(message::Table::Field::DATE);
115
123
case DRIZZLE_TYPE_VARCHAR:
117
drizzled::message::Table::Field::StringFieldOptions *string_field_options;
125
message::Table::Field::StringFieldOptions *string_field_options;
119
127
string_field_options= attribute->mutable_string_options();
120
attribute->set_type(drizzled::message::Table::Field::VARCHAR);
128
attribute->set_type(message::Table::Field::VARCHAR);
121
129
string_field_options->set_length(field_arg->length
122
130
/ field_arg->charset->mbmaxlen);
123
131
string_field_options->set_collation_id(field_arg->charset->number);
182
190
case COLUMN_FORMAT_TYPE_NOT_USED:
184
192
case COLUMN_FORMAT_TYPE_DEFAULT:
185
attribute->set_format(drizzled::message::Table::Field::DefaultFormat);
193
attribute->set_format(message::Table::Field::DefaultFormat);
187
195
case COLUMN_FORMAT_TYPE_FIXED:
188
attribute->set_format(drizzled::message::Table::Field::FixedFormat);
196
attribute->set_format(message::Table::Field::FixedFormat);
190
198
case COLUMN_FORMAT_TYPE_DYNAMIC:
191
attribute->set_format(drizzled::message::Table::Field::DynamicFormat);
199
attribute->set_format(message::Table::Field::DynamicFormat);
194
202
assert(0); /* Tell us, since this shouldn't happend */
232
240
if(field_arg->unireg_check == Field::TIMESTAMP_UN_FIELD
233
241
|| field_arg->unireg_check == Field::TIMESTAMP_DNUN_FIELD)
235
drizzled::message::Table::Field::FieldOptions *field_options;
243
message::Table::Field::FieldOptions *field_options;
236
244
field_options= attribute->mutable_options();
237
245
field_options->set_update_value("NOW()");
240
248
if(field_arg->def)
242
drizzled::message::Table::Field::FieldOptions *field_options;
250
message::Table::Field::FieldOptions *field_options;
243
251
field_options= attribute->mutable_options();
245
253
if(field_arg->def->is_null())
297
if (create_info->used_fields & HA_CREATE_USED_PACK_KEYS)
299
if(create_info->table_options & HA_OPTION_PACK_KEYS)
300
table_options->set_pack_keys(true);
301
else if(create_info->table_options & HA_OPTION_NO_PACK_KEYS)
302
table_options->set_pack_keys(false);
305
if(create_info->table_options & HA_OPTION_PACK_KEYS)
306
table_options->set_pack_keys(true);
309
if (create_info->used_fields & HA_CREATE_USED_CHECKSUM)
311
assert(create_info->table_options & (HA_OPTION_CHECKSUM | HA_OPTION_NO_CHECKSUM));
313
if(create_info->table_options & HA_OPTION_CHECKSUM)
314
table_options->set_checksum(true);
316
table_options->set_checksum(false);
318
else if(create_info->table_options & HA_OPTION_CHECKSUM)
319
table_options->set_checksum(true);
322
if (create_info->used_fields & HA_CREATE_USED_PAGE_CHECKSUM)
324
if (create_info->page_checksum == HA_CHOICE_YES)
325
table_options->set_page_checksum(true);
326
else if (create_info->page_checksum == HA_CHOICE_NO)
327
table_options->set_page_checksum(false);
329
else if (create_info->page_checksum == HA_CHOICE_YES)
330
table_options->set_page_checksum(true);
333
if (create_info->used_fields & HA_CREATE_USED_DELAY_KEY_WRITE)
335
if(create_info->table_options & HA_OPTION_DELAY_KEY_WRITE)
336
table_options->set_delay_key_write(true);
337
else if(create_info->table_options & HA_OPTION_NO_DELAY_KEY_WRITE)
338
table_options->set_delay_key_write(false);
340
else if(create_info->table_options & HA_OPTION_DELAY_KEY_WRITE)
341
table_options->set_delay_key_write(true);
344
305
switch(create_info->row_type)
346
307
case ROW_TYPE_DEFAULT:
347
table_options->set_row_type(drizzled::message::Table::TableOptions::ROW_TYPE_DEFAULT);
308
table_options->set_row_type(message::Table::TableOptions::ROW_TYPE_DEFAULT);
349
310
case ROW_TYPE_FIXED:
350
table_options->set_row_type(drizzled::message::Table::TableOptions::ROW_TYPE_FIXED);
311
table_options->set_row_type(message::Table::TableOptions::ROW_TYPE_FIXED);
352
313
case ROW_TYPE_DYNAMIC:
353
table_options->set_row_type(drizzled::message::Table::TableOptions::ROW_TYPE_DYNAMIC);
314
table_options->set_row_type(message::Table::TableOptions::ROW_TYPE_DYNAMIC);
355
316
case ROW_TYPE_COMPRESSED:
356
table_options->set_row_type(drizzled::message::Table::TableOptions::ROW_TYPE_COMPRESSED);
317
table_options->set_row_type(message::Table::TableOptions::ROW_TYPE_COMPRESSED);
358
319
case ROW_TYPE_REDUNDANT:
359
table_options->set_row_type(drizzled::message::Table::TableOptions::ROW_TYPE_REDUNDANT);
320
table_options->set_row_type(message::Table::TableOptions::ROW_TYPE_REDUNDANT);
361
322
case ROW_TYPE_COMPACT:
362
table_options->set_row_type(drizzled::message::Table::TableOptions::ROW_TYPE_COMPACT);
323
table_options->set_row_type(message::Table::TableOptions::ROW_TYPE_COMPACT);
364
325
case ROW_TYPE_PAGE:
365
table_options->set_row_type(drizzled::message::Table::TableOptions::ROW_TYPE_PAGE);
326
table_options->set_row_type(message::Table::TableOptions::ROW_TYPE_PAGE);
371
332
table_options->set_pack_record(create_info->table_options
372
333
& HA_OPTION_PACK_RECORD);
374
if (create_info->comment.length)
335
if (table_options->has_comment())
376
337
uint32_t tmp_len;
377
338
tmp_len= system_charset_info->cset->charpos(system_charset_info,
378
create_info->comment.str,
379
create_info->comment.str +
380
create_info->comment.length,
381
TABLE_COMMENT_MAXLEN);
339
table_options->comment().c_str(),
340
table_options->comment().c_str() +
341
table_options->comment().length(),
342
TABLE_COMMENT_MAXLEN);
383
if (tmp_len < create_info->comment.length)
344
if (tmp_len < table_options->comment().length())
385
346
my_error(ER_WRONG_STRING_LENGTH, MYF(0),
386
create_info->comment.str,"Table COMMENT",
387
(uint32_t) TABLE_COMMENT_MAXLEN);
347
table_options->comment().c_str(),"Table COMMENT",
348
(uint32_t) TABLE_COMMENT_MAXLEN);
391
table_options->set_comment(create_info->comment.str);
393
353
if (create_info->default_table_charset)
395
355
table_options->set_collation_id(
397
357
table_options->set_collation(create_info->default_table_charset->name);
400
if (create_info->connect_string.length)
401
table_options->set_connect_string(create_info->connect_string.str);
403
if (create_info->data_file_name)
404
table_options->set_data_file_name(create_info->data_file_name);
406
if (create_info->index_file_name)
407
table_options->set_index_file_name(create_info->index_file_name);
409
if (create_info->max_rows)
410
table_options->set_max_rows(create_info->max_rows);
412
if (create_info->min_rows)
413
table_options->set_min_rows(create_info->min_rows);
415
360
if (create_info->auto_increment_value)
416
361
table_options->set_auto_increment_value(create_info->auto_increment_value);
418
if (create_info->avg_row_length)
419
table_options->set_avg_row_length(create_info->avg_row_length);
421
363
if (create_info->key_block_size)
422
364
table_options->set_key_block_size(create_info->key_block_size);
424
if (create_info->block_size)
425
table_options->set_block_size(create_info->block_size);
427
366
for (unsigned int i= 0; i < keys; i++)
429
drizzled::message::Table::Index *idx;
368
message::Table::Index *idx;
431
370
idx= table_proto->add_indexes();
445
384
switch(key_info[i].algorithm)
447
386
case HA_KEY_ALG_HASH:
448
idx->set_type(drizzled::message::Table::Index::HASH);
387
idx->set_type(message::Table::Index::HASH);
451
390
case HA_KEY_ALG_BTREE:
452
idx->set_type(drizzled::message::Table::Index::BTREE);
391
idx->set_type(message::Table::Index::BTREE);
455
394
case HA_KEY_ALG_RTREE:
456
idx->set_type(drizzled::message::Table::Index::RTREE);
395
idx->set_type(message::Table::Index::RTREE);
457
396
case HA_KEY_ALG_FULLTEXT:
458
idx->set_type(drizzled::message::Table::Index::FULLTEXT);
397
idx->set_type(message::Table::Index::FULLTEXT);
459
398
case HA_KEY_ALG_UNDEF:
460
idx->set_type(drizzled::message::Table::Index::UNKNOWN_INDEX);
399
idx->set_type(message::Table::Index::UNKNOWN_INDEX);
566
492
return my_delete(new_path.c_str(), MYF(0));
569
int table_proto_exists(const char *path)
571
string proto_path(path);
572
string file_ext(".dfe");
573
proto_path.append(file_ext);
575
int error= access(proto_path.c_str(), F_OK);
583
static int create_table_proto_file(const char *file_name,
585
const char *table_name,
586
drizzled::message::Table *table_proto,
587
HA_CREATE_INFO *create_info,
588
List<Create_field> &create_fields,
592
string new_path(file_name);
593
string file_ext = ".dfe";
595
if(fill_table_proto(table_proto, table_name, create_fields, create_info,
599
new_path.append(file_ext);
601
int fd= open(new_path.c_str(), O_RDWR|O_CREAT|O_TRUNC, my_umask);
606
my_error(ER_BAD_DB_ERROR,MYF(0),db);
608
my_error(ER_CANT_CREATE_TABLE,MYF(0),table_name,errno);
495
int drizzle_write_proto_file(const std::string file_name,
496
message::Table *table_proto)
498
int fd= open(file_name.c_str(), O_RDWR|O_CREAT|O_TRUNC, my_umask);
612
503
google::protobuf::io::ZeroCopyOutputStream* output=
613
504
new google::protobuf::io::FileOutputStream(fd);
615
if (!table_proto->SerializeToZeroCopyStream(output))
506
if (table_proto->SerializeToZeroCopyStream(output) == false)
648
539
int rea_create_table(Session *session, const char *path,
649
540
const char *db, const char *table_name,
650
drizzled::message::Table *table_proto,
541
message::Table *table_proto,
651
542
HA_CREATE_INFO *create_info,
652
List<Create_field> &create_fields,
653
uint32_t keys, KEY *key_info,
543
List<CreateField> &create_fields,
544
uint32_t keys, KEY *key_info)
656
546
/* Proto will blow up unless we give a name */
657
547
assert(table_name);
659
/* For is_like we return once the file has been created */
662
if (create_table_proto_file(path, db, table_name, table_proto,
664
create_fields, keys, key_info)!=0)
669
/* Here we need to build the full frm from the path */
672
if (create_table_proto_file(path, db, table_name, table_proto,
674
create_fields, keys, key_info))
678
// Make sure mysql_create_frm din't remove extension
679
if (session->variables.keep_files_on_create)
680
create_info->options|= HA_CREATE_KEEP_FILES;
682
if (ha_create_table(session, path, db, table_name,
549
if (fill_table_proto(table_proto, table_name, create_fields, create_info,
553
string new_path(path);
554
string file_ext = ".dfe";
556
new_path.append(file_ext);
560
plugin::StorageEngine* engine= plugin::StorageEngine::findByName(session,
561
table_proto->engine().name());
562
if (engine->check_flag(HTON_BIT_HAS_DATA_DICTIONARY) == false)
563
err= drizzle_write_proto_file(new_path, table_proto);
568
my_error(ER_BAD_DB_ERROR,MYF(0),db);
570
my_error(ER_CANT_CREATE_TABLE,MYF(0),table_name,err);
575
if (plugin::StorageEngine::createTable(session, path, db, table_name,
576
create_info, false, table_proto))
684
577
goto err_handler;
688
delete_table_proto_file(path);
581
if (engine->check_flag(HTON_BIT_HAS_DATA_DICTIONARY) == false)
582
delete_table_proto_file(path);
691
585
} /* rea_create_table */
587
} /* namespace drizzled */