~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table_proto_write.cc

  • Committer: Monty Taylor
  • Date: 2009-04-14 19:16:51 UTC
  • mto: (997.2.5 mordred)
  • mto: This revision was merged to the branch mainline in revision 994.
  • Revision ID: mordred@inaugust.com-20090414191651-ltbww6hpqks8k7qk
Clarified instructions in README.

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
   along with this program; if not, write to the Free Software
14
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
 
#include "config.h"
 
16
#include <drizzled/server_includes.h>
17
17
#include <drizzled/error.h>
 
18
#include <drizzled/virtual_column_info.h>
18
19
#include <drizzled/session.h>
19
20
#include <drizzled/unireg.h>
20
 
#include "drizzled/sql_table.h"
21
 
#include "drizzled/global_charset_info.h"
22
 
#include "drizzled/message/statement_transform.h"
23
 
 
24
 
#include "drizzled/internal/my_sys.h"
25
 
 
26
21
 
27
22
/* For proto */
28
23
#include <string>
29
24
#include <fstream>
30
 
#include <fcntl.h>
31
25
#include <drizzled/message/schema.pb.h>
32
26
#include <drizzled/message/table.pb.h>
33
27
#include <google/protobuf/io/zero_copy_stream.h>
34
28
#include <google/protobuf/io/zero_copy_stream_impl.h>
35
 
 
36
 
#include <drizzled/table_proto.h>
37
 
 
38
29
using namespace std;
39
30
 
40
 
namespace drizzled {
41
 
 
42
 
static int fill_table_proto(message::Table &table_proto,
43
 
                            const std::string &table_name,
44
 
                            List<CreateField> &create_fields,
45
 
                            HA_CREATE_INFO *create_info,
46
 
                            uint32_t keys,
47
 
                            KEY *key_info)
48
 
{
49
 
  CreateField *field_arg;
50
 
  List_iterator<CreateField> it(create_fields);
51
 
  message::Table::TableOptions *table_options= table_proto.mutable_options();
 
31
int drizzle_read_table_proto(const char* path, drizzled::message::Table* table)
 
32
{
 
33
  int fd= open(path, O_RDONLY);
 
34
 
 
35
  if(fd==-1)
 
36
    return errno;
 
37
 
 
38
  google::protobuf::io::ZeroCopyInputStream* input=
 
39
    new google::protobuf::io::FileInputStream(fd);
 
40
 
 
41
  if (!table->ParseFromZeroCopyStream(input))
 
42
  {
 
43
    delete input;
 
44
    close(fd);
 
45
    return -1;
 
46
  }
 
47
 
 
48
  delete input;
 
49
  close(fd);
 
50
  return 0;
 
51
}
 
52
 
 
53
static int fill_table_proto(drizzled::message::Table *table_proto,
 
54
                            const char *table_name,
 
55
                            List<Create_field> &create_fields,
 
56
                            HA_CREATE_INFO *create_info,
 
57
                            uint32_t keys,
 
58
                            KEY *key_info)
 
59
{
 
60
  Create_field *field_arg;
 
61
  List_iterator<Create_field> it(create_fields);
 
62
  drizzled::message::Table::StorageEngine *engine= table_proto->mutable_engine();
 
63
  drizzled::message::Table::TableOptions *table_options= table_proto->mutable_options();
52
64
 
53
65
  if (create_fields.elements > MAX_FIELDS)
54
66
  {
56
68
    return(1);
57
69
  }
58
70
 
59
 
  assert(strcmp(table_proto.engine().name().c_str(),
60
 
                create_info->db_type->getName().c_str())==0);
61
 
 
62
 
  assert(table_proto.name() == table_name);
63
 
 
64
 
  int field_number= 0;
65
 
  bool use_existing_fields= table_proto.field_size() > 0;
 
71
  engine->set_name(create_info->db_type->getName());
 
72
 
 
73
  table_proto->set_name(table_name);
 
74
  table_proto->set_type(drizzled::message::Table::STANDARD);
 
75
 
66
76
  while ((field_arg= it++))
67
77
  {
68
 
    message::Table::Field *attribute;
69
 
 
70
 
    /* some (one) code path for CREATE TABLE fills the proto
71
 
       out more than the others, so we already have partially
72
 
       filled out Field messages */
73
 
 
74
 
    if (use_existing_fields)
75
 
      attribute= table_proto.mutable_field(field_number++);
76
 
    else
 
78
    drizzled::message::Table::Field *attribute;
 
79
 
 
80
    attribute= table_proto->add_field();
 
81
    attribute->set_name(field_arg->field_name);
 
82
 
 
83
    attribute->set_pack_flag(field_arg->pack_flag); /* TODO: MUST DIE */
 
84
 
 
85
    if(f_maybe_null(field_arg->pack_flag))
77
86
    {
78
 
      /* Other code paths still have to fill out the proto */
79
 
      attribute= table_proto.add_field();
80
 
 
81
 
      if (field_arg->flags & NOT_NULL_FLAG)
82
 
      {
83
 
        message::Table::Field::FieldConstraints *constraints;
84
 
 
85
 
        constraints= attribute->mutable_constraints();
86
 
        constraints->set_is_nullable(false);
87
 
      }
88
 
 
89
 
      attribute->set_name(field_arg->field_name);
 
87
      drizzled::message::Table::Field::FieldConstraints *constraints;
 
88
 
 
89
      constraints= attribute->mutable_constraints();
 
90
      constraints->set_is_nullable(true);
90
91
    }
91
92
 
92
 
    assert((!(field_arg->flags & NOT_NULL_FLAG)) == attribute->constraints().is_nullable());
93
 
    assert(strcmp(attribute->name().c_str(), field_arg->field_name)==0);
94
 
 
95
 
 
96
 
    message::Table::Field::FieldType parser_type= attribute->type();
97
 
 
98
 
    attribute->set_type(message::internalFieldTypeToFieldProtoType(field_arg->sql_type));
99
 
 
100
 
    switch (attribute->type()) {
101
 
    default: /* Only deal with types that need extra information */
102
 
      break;
103
 
    case message::Table::Field::DOUBLE:
104
 
      {
105
 
        /*
106
 
         * For DOUBLE, we only add a specific scale and precision iff
107
 
         * the fixed decimal point has been specified...
108
 
         */
109
 
        if (field_arg->decimals != NOT_FIXED_DEC)
110
 
        {
111
 
          message::Table::Field::NumericFieldOptions *numeric_field_options;
112
 
 
113
 
          numeric_field_options= attribute->mutable_numeric_options();
114
 
 
115
 
          numeric_field_options->set_precision(field_arg->length);
116
 
          numeric_field_options->set_scale(field_arg->decimals);
117
 
        }
118
 
      }
119
 
      break;
120
 
    case message::Table::Field::VARCHAR:
121
 
      {
122
 
        message::Table::Field::StringFieldOptions *string_field_options;
 
93
    switch (field_arg->sql_type) {
 
94
    case DRIZZLE_TYPE_TINY:
 
95
      attribute->set_type(drizzled::message::Table::Field::TINYINT);
 
96
      break;
 
97
    case DRIZZLE_TYPE_LONG:
 
98
      attribute->set_type(drizzled::message::Table::Field::INTEGER);
 
99
      break;
 
100
    case DRIZZLE_TYPE_DOUBLE:
 
101
      attribute->set_type(drizzled::message::Table::Field::DOUBLE);
 
102
      break;
 
103
    case DRIZZLE_TYPE_NULL  :
 
104
      assert(1); /* Not a user definable type */
 
105
    case DRIZZLE_TYPE_TIMESTAMP:
 
106
      attribute->set_type(drizzled::message::Table::Field::TIMESTAMP);
 
107
      break;
 
108
    case DRIZZLE_TYPE_LONGLONG:
 
109
      attribute->set_type(drizzled::message::Table::Field::BIGINT);
 
110
      break;
 
111
    case DRIZZLE_TYPE_DATETIME:
 
112
      attribute->set_type(drizzled::message::Table::Field::DATETIME);
 
113
      break;
 
114
    case DRIZZLE_TYPE_DATE:
 
115
      attribute->set_type(drizzled::message::Table::Field::DATE);
 
116
      break;
 
117
    case DRIZZLE_TYPE_VARCHAR:
 
118
      {
 
119
        drizzled::message::Table::Field::StringFieldOptions *string_field_options;
123
120
 
124
121
        string_field_options= attribute->mutable_string_options();
125
 
 
126
 
        if (! use_existing_fields || string_field_options->length()==0)
127
 
          string_field_options->set_length(field_arg->length
128
 
                                           / field_arg->charset->mbmaxlen);
129
 
        else
130
 
          assert((uint32_t)string_field_options->length() == (uint32_t)(field_arg->length / field_arg->charset->mbmaxlen));
131
 
 
132
 
        if (! string_field_options->has_collation())
133
 
        {
134
 
          string_field_options->set_collation_id(field_arg->charset->number);
135
 
          string_field_options->set_collation(field_arg->charset->name);
136
 
        }
 
122
        attribute->set_type(drizzled::message::Table::Field::VARCHAR);
 
123
        string_field_options->set_length(field_arg->length
 
124
                                         / field_arg->charset->mbmaxlen);
 
125
        string_field_options->set_collation_id(field_arg->charset->number);
 
126
        string_field_options->set_collation(field_arg->charset->name);
 
127
 
137
128
        break;
138
129
      }
139
 
    case message::Table::Field::DECIMAL:
 
130
    case DRIZZLE_TYPE_NEWDECIMAL:
140
131
      {
141
 
        message::Table::Field::NumericFieldOptions *numeric_field_options;
 
132
        drizzled::message::Table::Field::NumericFieldOptions *numeric_field_options;
142
133
 
 
134
        attribute->set_type(drizzled::message::Table::Field::DECIMAL);
143
135
        numeric_field_options= attribute->mutable_numeric_options();
144
136
        /* This is magic, I hate magic numbers -Brian */
145
137
        numeric_field_options->set_precision(field_arg->length + ( field_arg->decimals ? -2 : -1));
146
138
        numeric_field_options->set_scale(field_arg->decimals);
147
139
        break;
148
140
      }
149
 
    case message::Table::Field::ENUM:
 
141
    case DRIZZLE_TYPE_ENUM:
150
142
      {
151
 
        message::Table::Field::EnumerationValues *enumeration_options;
 
143
        drizzled::message::Table::Field::SetFieldOptions *set_field_options;
152
144
 
153
145
        assert(field_arg->interval);
154
146
 
155
 
        enumeration_options= attribute->mutable_enumeration_values();
 
147
        attribute->set_type(drizzled::message::Table::Field::ENUM);
 
148
        set_field_options= attribute->mutable_set_options();
156
149
 
157
150
        for (uint32_t pos= 0; pos < field_arg->interval->count; pos++)
158
151
        {
159
152
          const char *src= field_arg->interval->type_names[pos];
160
153
 
161
 
          enumeration_options->add_field_value(src);
 
154
          set_field_options->add_field_value(src);
162
155
        }
163
 
        enumeration_options->set_collation_id(field_arg->charset->number);
164
 
        enumeration_options->set_collation(field_arg->charset->name);
 
156
        set_field_options->set_count_elements(set_field_options->field_value_size());
 
157
        set_field_options->set_collation_id(field_arg->charset->number);
 
158
        set_field_options->set_collation(field_arg->charset->name);
165
159
        break;
166
160
      }
167
 
    case message::Table::Field::BLOB:
 
161
    case DRIZZLE_TYPE_BLOB:
168
162
      {
169
 
        message::Table::Field::StringFieldOptions *string_field_options;
 
163
        attribute->set_type(drizzled::message::Table::Field::BLOB);
 
164
 
 
165
        drizzled::message::Table::Field::StringFieldOptions *string_field_options;
170
166
 
171
167
        string_field_options= attribute->mutable_string_options();
172
168
        string_field_options->set_collation_id(field_arg->charset->number);
174
170
      }
175
171
 
176
172
      break;
177
 
    }
178
 
 
179
 
    assert (!use_existing_fields || parser_type == attribute->type());
 
173
    default:
 
174
      assert(0); /* Tell us, since this shouldn't happend */
 
175
    }
 
176
 
 
177
    if(field_arg->vcol_info)
 
178
    {
 
179
      uint32_t tmp_len;
 
180
      tmp_len= system_charset_info->cset->charpos(system_charset_info,
 
181
                                          field_arg->vcol_info->expr_str.str,
 
182
                                          field_arg->vcol_info->expr_str.str +
 
183
                                          field_arg->vcol_info->expr_str.length,
 
184
                                          VIRTUAL_COLUMN_EXPRESSION_MAXLEN);
 
185
 
 
186
      if (tmp_len < field_arg->vcol_info->expr_str.length)
 
187
      {
 
188
        my_error(ER_WRONG_STRING_LENGTH, MYF(0),
 
189
                 field_arg->vcol_info->expr_str.str,"VIRTUAL COLUMN EXPRESSION",
 
190
                 (uint32_t) VIRTUAL_COLUMN_EXPRESSION_MAXLEN);
 
191
        return(1);
 
192
      }
 
193
 
 
194
      drizzled::message::Table::Field::VirtualFieldOptions *field_options;
 
195
 
 
196
      field_options= attribute->mutable_virtual_options();
 
197
 
 
198
      field_options->set_type(attribute->type());
 
199
      attribute->set_type(drizzled::message::Table::Field::VIRTUAL);
 
200
 
 
201
      string expr(field_arg->vcol_info->expr_str.str,
 
202
                  field_arg->vcol_info->expr_str.length);
 
203
 
 
204
      field_options->set_expression(expr);
 
205
      field_options->set_physically_stored(field_arg->is_stored);
 
206
    }
180
207
 
181
208
#ifdef NOTDONE
182
209
    field_constraints= attribute->mutable_constraints();
188
215
    case COLUMN_FORMAT_TYPE_NOT_USED:
189
216
      break;
190
217
    case COLUMN_FORMAT_TYPE_DEFAULT:
191
 
      attribute->set_format(message::Table::Field::DefaultFormat);
 
218
      attribute->set_format(drizzled::message::Table::Field::DefaultFormat);
192
219
      break;
193
220
    case COLUMN_FORMAT_TYPE_FIXED:
194
 
      attribute->set_format(message::Table::Field::FixedFormat);
 
221
      attribute->set_format(drizzled::message::Table::Field::FixedFormat);
195
222
      break;
196
223
    case COLUMN_FORMAT_TYPE_DYNAMIC:
197
 
      attribute->set_format(message::Table::Field::DynamicFormat);
 
224
      attribute->set_format(drizzled::message::Table::Field::DynamicFormat);
198
225
      break;
199
226
    default:
200
227
      assert(0); /* Tell us, since this shouldn't happend */
217
244
        return(1);
218
245
      }
219
246
 
220
 
      if (! use_existing_fields)
221
 
        attribute->set_comment(field_arg->comment.str);
222
 
 
223
 
      assert(strcmp(attribute->comment().c_str(), field_arg->comment.str)==0);
 
247
      attribute->set_comment(field_arg->comment.str);
224
248
    }
225
249
 
226
 
    if (field_arg->unireg_check == Field::NEXT_NUMBER)
 
250
    if(field_arg->unireg_check == Field::NEXT_NUMBER)
227
251
    {
228
 
      message::Table::Field::NumericFieldOptions *field_options;
 
252
      drizzled::message::Table::Field::NumericFieldOptions *field_options;
229
253
      field_options= attribute->mutable_numeric_options();
230
254
      field_options->set_is_autoincrement(true);
231
255
    }
232
256
 
233
 
    if (field_arg->unireg_check == Field::TIMESTAMP_DN_FIELD
 
257
    if(field_arg->unireg_check == Field::TIMESTAMP_DN_FIELD
234
258
       || field_arg->unireg_check == Field::TIMESTAMP_DNUN_FIELD)
235
259
    {
236
 
      message::Table::Field::FieldOptions *field_options;
 
260
      drizzled::message::Table::Field::FieldOptions *field_options;
237
261
      field_options= attribute->mutable_options();
238
262
      field_options->set_default_value("NOW()");
239
263
    }
240
264
 
241
 
    if (field_arg->unireg_check == Field::TIMESTAMP_UN_FIELD
 
265
    if(field_arg->unireg_check == Field::TIMESTAMP_UN_FIELD
242
266
       || field_arg->unireg_check == Field::TIMESTAMP_DNUN_FIELD)
243
267
    {
244
 
      message::Table::Field::FieldOptions *field_options;
 
268
      drizzled::message::Table::Field::FieldOptions *field_options;
245
269
      field_options= attribute->mutable_options();
246
270
      field_options->set_update_value("NOW()");
247
271
    }
248
272
 
249
 
    if (field_arg->def == NULL  && attribute->constraints().is_nullable())
 
273
    if(field_arg->def)
250
274
    {
251
 
      message::Table::Field::FieldOptions *field_options;
 
275
      drizzled::message::Table::Field::FieldOptions *field_options;
252
276
      field_options= attribute->mutable_options();
253
277
 
254
 
      field_options->set_default_null(true);
255
 
    }
256
 
    if (field_arg->def)
257
 
    {
258
 
      message::Table::Field::FieldOptions *field_options;
259
 
      field_options= attribute->mutable_options();
260
 
 
261
 
      if (field_arg->def->is_null())
 
278
      if(field_arg->def->is_null())
262
279
      {
263
280
        field_options->set_default_null(true);
264
281
      }
269
286
 
270
287
        assert(default_value);
271
288
 
272
 
        if ((field_arg->sql_type==DRIZZLE_TYPE_VARCHAR
 
289
        if((field_arg->sql_type==DRIZZLE_TYPE_VARCHAR
273
290
           || field_arg->sql_type==DRIZZLE_TYPE_BLOB)
274
291
           && ((field_arg->length / field_arg->charset->mbmaxlen)
275
292
           < default_value->length()))
278
295
          return 1;
279
296
        }
280
297
 
281
 
        if ((field_arg->sql_type==DRIZZLE_TYPE_VARCHAR
 
298
        if((field_arg->sql_type==DRIZZLE_TYPE_VARCHAR
282
299
            && field_arg->charset==&my_charset_bin)
283
300
           || (field_arg->sql_type==DRIZZLE_TYPE_BLOB
284
301
            && field_arg->charset==&my_charset_bin))
295
312
      }
296
313
    }
297
314
 
 
315
    {
 
316
      drizzled::message::Table::Field::FieldOptions *field_options;
 
317
      field_options= attribute->mutable_options();
 
318
 
 
319
      field_options->set_length(field_arg->length);
 
320
    }
 
321
 
298
322
    assert(field_arg->unireg_check == Field::NONE
299
323
           || field_arg->unireg_check == Field::NEXT_NUMBER
300
324
           || field_arg->unireg_check == Field::TIMESTAMP_DN_FIELD
303
327
 
304
328
  }
305
329
 
306
 
  assert(! use_existing_fields || (field_number == table_proto.field_size()));
307
 
 
308
 
  if (create_info->table_options & HA_OPTION_PACK_RECORD)
309
 
    table_options->set_pack_record(true);
310
 
 
311
 
  if (table_options->has_comment())
 
330
  if (create_info->used_fields & HA_CREATE_USED_PACK_KEYS)
 
331
  {
 
332
    if(create_info->table_options & HA_OPTION_PACK_KEYS)
 
333
      table_options->set_pack_keys(true);
 
334
    else if(create_info->table_options & HA_OPTION_NO_PACK_KEYS)
 
335
      table_options->set_pack_keys(false);
 
336
  }
 
337
  else
 
338
    if(create_info->table_options & HA_OPTION_PACK_KEYS)
 
339
      table_options->set_pack_keys(true);
 
340
 
 
341
 
 
342
  if (create_info->used_fields & HA_CREATE_USED_CHECKSUM)
 
343
  {
 
344
    assert(create_info->table_options & (HA_OPTION_CHECKSUM | HA_OPTION_NO_CHECKSUM));
 
345
 
 
346
    if(create_info->table_options & HA_OPTION_CHECKSUM)
 
347
      table_options->set_checksum(true);
 
348
    else
 
349
      table_options->set_checksum(false);
 
350
  }
 
351
  else if(create_info->table_options & HA_OPTION_CHECKSUM)
 
352
    table_options->set_checksum(true);
 
353
 
 
354
 
 
355
  if (create_info->used_fields & HA_CREATE_USED_PAGE_CHECKSUM)
 
356
  {
 
357
    if (create_info->page_checksum == HA_CHOICE_YES)
 
358
      table_options->set_page_checksum(true);
 
359
    else if (create_info->page_checksum == HA_CHOICE_NO)
 
360
      table_options->set_page_checksum(false);
 
361
  }
 
362
  else if (create_info->page_checksum == HA_CHOICE_YES)
 
363
    table_options->set_page_checksum(true);
 
364
 
 
365
 
 
366
  if (create_info->used_fields & HA_CREATE_USED_DELAY_KEY_WRITE)
 
367
  {
 
368
    if(create_info->table_options & HA_OPTION_DELAY_KEY_WRITE)
 
369
      table_options->set_delay_key_write(true);
 
370
    else if(create_info->table_options & HA_OPTION_NO_DELAY_KEY_WRITE)
 
371
      table_options->set_delay_key_write(false);
 
372
  }
 
373
  else if(create_info->table_options & HA_OPTION_DELAY_KEY_WRITE)
 
374
    table_options->set_delay_key_write(true);
 
375
 
 
376
 
 
377
  switch(create_info->row_type)
 
378
  {
 
379
  case ROW_TYPE_DEFAULT:
 
380
    table_options->set_row_type(drizzled::message::Table::TableOptions::ROW_TYPE_DEFAULT);
 
381
    break;
 
382
  case ROW_TYPE_FIXED:
 
383
    table_options->set_row_type(drizzled::message::Table::TableOptions::ROW_TYPE_FIXED);
 
384
    break;
 
385
  case ROW_TYPE_DYNAMIC:
 
386
    table_options->set_row_type(drizzled::message::Table::TableOptions::ROW_TYPE_DYNAMIC);
 
387
    break;
 
388
  case ROW_TYPE_COMPRESSED:
 
389
    table_options->set_row_type(drizzled::message::Table::TableOptions::ROW_TYPE_COMPRESSED);
 
390
    break;
 
391
  case ROW_TYPE_REDUNDANT:
 
392
    table_options->set_row_type(drizzled::message::Table::TableOptions::ROW_TYPE_REDUNDANT);
 
393
    break;
 
394
  case ROW_TYPE_COMPACT:
 
395
    table_options->set_row_type(drizzled::message::Table::TableOptions::ROW_TYPE_COMPACT);
 
396
    break;
 
397
  case ROW_TYPE_PAGE:
 
398
    table_options->set_row_type(drizzled::message::Table::TableOptions::ROW_TYPE_PAGE);
 
399
    break;
 
400
  default:
 
401
    abort();
 
402
  }
 
403
 
 
404
  table_options->set_pack_record(create_info->table_options
 
405
                                 & HA_OPTION_PACK_RECORD);
 
406
 
 
407
  if (create_info->comment.length)
312
408
  {
313
409
    uint32_t tmp_len;
314
410
    tmp_len= system_charset_info->cset->charpos(system_charset_info,
315
 
                                                table_options->comment().c_str(),
316
 
                                                table_options->comment().c_str() +
317
 
                                                table_options->comment().length(),
318
 
                                                TABLE_COMMENT_MAXLEN);
 
411
                                                create_info->comment.str,
 
412
                                                create_info->comment.str +
 
413
                                                create_info->comment.length,
 
414
                                                TABLE_COMMENT_MAXLEN);
319
415
 
320
 
    if (tmp_len < table_options->comment().length())
 
416
    if (tmp_len < create_info->comment.length)
321
417
    {
322
418
      my_error(ER_WRONG_STRING_LENGTH, MYF(0),
323
 
               table_options->comment().c_str(),"Table COMMENT",
324
 
               (uint32_t) TABLE_COMMENT_MAXLEN);
 
419
               create_info->comment.str,"Table COMMENT",
 
420
               (uint32_t) TABLE_COMMENT_MAXLEN);
325
421
      return(1);
326
422
    }
 
423
 
 
424
    table_options->set_comment(create_info->comment.str);
327
425
  }
328
 
 
329
426
  if (create_info->default_table_charset)
330
427
  {
331
428
    table_options->set_collation_id(
333
430
    table_options->set_collation(create_info->default_table_charset->name);
334
431
  }
335
432
 
 
433
  if (create_info->connect_string.length)
 
434
    table_options->set_connect_string(create_info->connect_string.str);
 
435
 
 
436
  if (create_info->data_file_name)
 
437
    table_options->set_data_file_name(create_info->data_file_name);
 
438
 
 
439
  if (create_info->index_file_name)
 
440
    table_options->set_index_file_name(create_info->index_file_name);
 
441
 
 
442
  if (create_info->max_rows)
 
443
    table_options->set_max_rows(create_info->max_rows);
 
444
 
 
445
  if (create_info->min_rows)
 
446
    table_options->set_min_rows(create_info->min_rows);
 
447
 
336
448
  if (create_info->auto_increment_value)
337
449
    table_options->set_auto_increment_value(create_info->auto_increment_value);
338
450
 
339
 
  for (uint32_t i= 0; i < keys; i++)
 
451
  if (create_info->avg_row_length)
 
452
    table_options->set_avg_row_length(create_info->avg_row_length);
 
453
 
 
454
  if (create_info->key_block_size)
 
455
    table_options->set_key_block_size(create_info->key_block_size);
 
456
 
 
457
  if (create_info->block_size)
 
458
    table_options->set_block_size(create_info->block_size);
 
459
 
 
460
  for (unsigned int i= 0; i < keys; i++)
340
461
  {
341
 
    message::Table::Index *idx;
 
462
    drizzled::message::Table::Index *idx;
342
463
 
343
 
    idx= table_proto.add_indexes();
 
464
    idx= table_proto->add_indexes();
344
465
 
345
466
    assert(test(key_info[i].flags & HA_USES_COMMENT) ==
346
467
           (key_info[i].comment.length > 0));
349
470
 
350
471
    idx->set_key_length(key_info[i].key_length);
351
472
 
352
 
    if (is_primary_key_name(key_info[i].name))
 
473
    if(is_primary_key_name(key_info[i].name))
353
474
      idx->set_is_primary(true);
354
475
    else
355
476
      idx->set_is_primary(false);
357
478
    switch(key_info[i].algorithm)
358
479
    {
359
480
    case HA_KEY_ALG_HASH:
360
 
      idx->set_type(message::Table::Index::HASH);
 
481
      idx->set_type(drizzled::message::Table::Index::HASH);
361
482
      break;
362
483
 
363
484
    case HA_KEY_ALG_BTREE:
364
 
      idx->set_type(message::Table::Index::BTREE);
 
485
      idx->set_type(drizzled::message::Table::Index::BTREE);
365
486
      break;
366
487
 
 
488
    case HA_KEY_ALG_RTREE:
 
489
      idx->set_type(drizzled::message::Table::Index::RTREE);
 
490
    case HA_KEY_ALG_FULLTEXT:
 
491
      idx->set_type(drizzled::message::Table::Index::FULLTEXT);
367
492
    case HA_KEY_ALG_UNDEF:
368
 
      idx->set_type(message::Table::Index::UNKNOWN_INDEX);
 
493
      idx->set_type(drizzled::message::Table::Index::UNKNOWN_INDEX);
369
494
      break;
370
495
 
371
496
    default:
377
502
    else
378
503
      idx->set_is_unique(false);
379
504
 
380
 
    message::Table::Index::IndexOptions *index_options= idx->mutable_options();
 
505
    drizzled::message::Table::Index::IndexOptions *index_options= idx->mutable_options();
381
506
 
382
 
    if (key_info[i].flags & HA_USES_BLOCK_SIZE)
 
507
    if(key_info[i].flags & HA_USES_BLOCK_SIZE)
383
508
      index_options->set_key_block_size(key_info[i].block_size);
384
509
 
385
 
    if (key_info[i].flags & HA_PACK_KEY)
 
510
    if(key_info[i].flags & HA_PACK_KEY)
386
511
      index_options->set_pack_key(true);
387
512
 
388
 
    if (key_info[i].flags & HA_BINARY_PACK_KEY)
 
513
    if(key_info[i].flags & HA_BINARY_PACK_KEY)
389
514
      index_options->set_binary_pack_key(true);
390
515
 
391
 
    if (key_info[i].flags & HA_VAR_LENGTH_PART)
 
516
    if(key_info[i].flags & HA_VAR_LENGTH_PART)
392
517
      index_options->set_var_length_key(true);
393
518
 
394
 
    if (key_info[i].flags & HA_NULL_PART_KEY)
 
519
    if(key_info[i].flags & HA_NULL_PART_KEY)
395
520
      index_options->set_null_part_key(true);
396
521
 
397
 
    if (key_info[i].flags & HA_KEY_HAS_PART_KEY_SEG)
 
522
    if(key_info[i].flags & HA_KEY_HAS_PART_KEY_SEG)
398
523
      index_options->set_has_partial_segments(true);
399
524
 
400
 
    if (key_info[i].flags & HA_GENERATED_KEY)
 
525
    if(key_info[i].flags & HA_GENERATED_KEY)
401
526
      index_options->set_auto_generated_key(true);
402
527
 
403
528
    if (key_info[i].flags & HA_USES_COMMENT)
419
544
 
420
545
      idx->set_comment(key_info[i].comment.str);
421
546
    }
422
 
    if (key_info[i].flags & 
423
 
        ~(HA_NOSAME | HA_PACK_KEY | HA_USES_BLOCK_SIZE | 
424
 
          HA_BINARY_PACK_KEY | HA_VAR_LENGTH_PART | HA_NULL_PART_KEY | 
425
 
          HA_KEY_HAS_PART_KEY_SEG | HA_GENERATED_KEY | HA_USES_COMMENT))
 
547
    if(key_info[i].flags & ~(HA_NOSAME | HA_PACK_KEY | HA_USES_BLOCK_SIZE | HA_BINARY_PACK_KEY | HA_VAR_LENGTH_PART | HA_NULL_PART_KEY | HA_KEY_HAS_PART_KEY_SEG | HA_GENERATED_KEY | HA_USES_COMMENT))
426
548
      abort(); // Invalid (unknown) index flag.
427
549
 
428
550
    for(unsigned int j=0; j< key_info[i].key_parts; j++)
429
551
    {
430
 
      message::Table::Index::IndexPart *idxpart;
 
552
      drizzled::message::Table::Index::IndexPart *idxpart;
431
553
 
432
554
      idxpart= idx->add_index_part();
433
555
 
443
565
  return 0;
444
566
}
445
567
 
 
568
int copy_table_proto_file(const char *from, const char* to)
 
569
{
 
570
  string dfesrc(from);
 
571
  string dfedst(to);
 
572
  string file_ext = ".dfe";
 
573
 
 
574
  dfesrc.append(file_ext);
 
575
  dfedst.append(file_ext);
 
576
 
 
577
  return my_copy(dfesrc.c_str(), dfedst.c_str(),
 
578
                 MYF(MY_DONT_OVERWRITE_FILE));
 
579
}
 
580
 
 
581
int rename_table_proto_file(const char *from, const char* to)
 
582
{
 
583
  string from_path(from);
 
584
  string to_path(to);
 
585
  string file_ext = ".dfe";
 
586
 
 
587
  from_path.append(file_ext);
 
588
  to_path.append(file_ext);
 
589
 
 
590
  return my_rename(from_path.c_str(),to_path.c_str(),MYF(MY_WME));
 
591
}
 
592
 
 
593
int delete_table_proto_file(const char *file_name)
 
594
{
 
595
  string new_path(file_name);
 
596
  string file_ext = ".dfe";
 
597
 
 
598
  new_path.append(file_ext);
 
599
  return my_delete(new_path.c_str(), MYF(0));
 
600
}
 
601
 
 
602
int table_proto_exists(const char *path)
 
603
{
 
604
  string proto_path(path);
 
605
  string file_ext(".dfe");
 
606
  proto_path.append(file_ext);
 
607
 
 
608
  int error= access(proto_path.c_str(), F_OK);
 
609
 
 
610
  if(error==0)
 
611
    return EEXIST;
 
612
  else
 
613
    return errno;
 
614
}
 
615
 
 
616
static int create_table_proto_file(const char *file_name,
 
617
                                   const char *db,
 
618
                                   const char *table_name,
 
619
                                   HA_CREATE_INFO *create_info,
 
620
                                   List<Create_field> &create_fields,
 
621
                                   uint32_t keys,
 
622
                                   KEY *key_info)
 
623
{
 
624
  drizzled::message::Table table_proto;
 
625
  string new_path(file_name);
 
626
  string file_ext = ".dfe";
 
627
 
 
628
  if(fill_table_proto(&table_proto, table_name, create_fields, create_info,
 
629
                      keys, key_info))
 
630
    return -1;
 
631
 
 
632
  new_path.append(file_ext);
 
633
 
 
634
  int fd= open(new_path.c_str(), O_RDWR|O_CREAT|O_TRUNC, my_umask);
 
635
 
 
636
  if(fd==-1)
 
637
  {
 
638
    if(errno==ENOENT)
 
639
      my_error(ER_BAD_DB_ERROR,MYF(0),db);
 
640
    else
 
641
      my_error(ER_CANT_CREATE_TABLE,MYF(0),table_name,errno);
 
642
    return errno;
 
643
  }
 
644
 
 
645
  google::protobuf::io::ZeroCopyOutputStream* output=
 
646
    new google::protobuf::io::FileOutputStream(fd);
 
647
 
 
648
  if (!table_proto.SerializeToZeroCopyStream(output))
 
649
  {
 
650
    delete output;
 
651
    close(fd);
 
652
    return errno;
 
653
  }
 
654
 
 
655
  delete output;
 
656
  close(fd);
 
657
  return 0;
 
658
}
 
659
 
446
660
/*
447
661
  Create a table definition proto file and the tables
448
662
 
456
670
    create_fields       Fields to create
457
671
    keys                number of keys to create
458
672
    key_info            Keys to create
 
673
    file                Handler to use
 
674
    is_like             is true for mysql_create_like_schema_frm
459
675
 
460
676
  RETURN
461
677
    0  ok
462
678
    1  error
463
679
*/
464
680
 
465
 
bool rea_create_table(Session *session,
466
 
                      TableIdentifier &identifier,
467
 
                      message::Table &table_proto,
468
 
                      HA_CREATE_INFO *create_info,
469
 
                      List<CreateField> &create_fields,
470
 
                      uint32_t keys, KEY *key_info)
 
681
int rea_create_table(Session *session, const char *path,
 
682
                     const char *db, const char *table_name,
 
683
                     HA_CREATE_INFO *create_info,
 
684
                     List<Create_field> &create_fields,
 
685
                     uint32_t keys, KEY *key_info, handler *file,
 
686
                     bool is_like)
471
687
{
472
 
  if (fill_table_proto(table_proto, identifier.getTableName(), create_fields, create_info,
473
 
                       keys, key_info))
474
 
    return false;
475
 
 
476
 
  if (plugin::StorageEngine::createTable(*session,
477
 
                                         identifier,
478
 
                                         false, table_proto))
479
 
  {
480
 
    return false;
481
 
  }
482
 
 
483
 
  return true;
484
 
 
 
688
  /* Proto will blow up unless we give a name */
 
689
  assert(table_name);
 
690
 
 
691
  /* For is_like we return once the file has been created */
 
692
  if (is_like)
 
693
  {
 
694
    if (create_table_proto_file(path, db, table_name, create_info,
 
695
                                create_fields, keys, key_info)!=0)
 
696
      return 1;
 
697
 
 
698
    return 0;
 
699
  }
 
700
  /* Here we need to build the full frm from the path */
 
701
  else
 
702
  {
 
703
    if (create_table_proto_file(path, db, table_name, create_info,
 
704
                                create_fields, keys, key_info))
 
705
      return 1;
 
706
  }
 
707
 
 
708
  // Make sure mysql_create_frm din't remove extension
 
709
  if (session->variables.keep_files_on_create)
 
710
    create_info->options|= HA_CREATE_KEEP_FILES;
 
711
  if (file->ha_create_handler_files(path, NULL, CHF_CREATE_FLAG, create_info))
 
712
    goto err_handler;
 
713
  if (ha_create_table(session, path, db, table_name,
 
714
                      create_info,0))
 
715
    goto err_handler;
 
716
  return 0;
 
717
 
 
718
err_handler:
 
719
  file->ha_create_handler_files(path, NULL, CHF_DELETE_FLAG, create_info);
 
720
 
 
721
  delete_table_proto_file(path);
 
722
 
 
723
  return 1;
485
724
} /* rea_create_table */
486
 
 
487
 
} /* namespace drizzled */
488