tables_creator::tables_creator(insert_map_t &insert_statements, const field_masks &masks, const char *foreign_key_table, const char *foreign_key_name, const char *foreign_key_type) : insert_statements_(insert_statements), masks_(masks), primary_key_index_(-1), num_columns_(0), find_key_needed_(false) { assert(foreign_key_table); add_foreign_key(foreign_key_expression_, foreign_key_table, foreign_key_name, foreign_key_type); }
void tables_creator::visit(const sequence_field_instruction* inst, void*) { const template_instruction* ref_instruction = dynamic_cast<const template_instruction*>(inst->ref_instruction()); const template_instruction* element_instruction = dynamic_cast<const template_instruction*>(inst->element_instruction()); bool is_ordered = masks_.is_ordered(inst); if (ref_instruction == 0 && element_instruction == 0) { traverse_subinstructions(inst); if (is_ordered) { create_current_ << " ordering INT,\n"; num_columns_++; } return; } if (this->primary_key_name_.empty()) BOOST_THROW_EXCEPTION(std::runtime_error("Current implementation only allows " "primary key field appears before any " "sequence field in a template.")); if (element_instruction) { tables_creator nested_builder(insert_statements_, masks_, true); nested_builder.visit(element_instruction, 0); create_prefix_ << nested_builder.create_statements(); if (strcmp(nested_builder.primary_key_name(), "rowid") == 0) create_prefix_ << "CREATE UNIQUE INDEX " << nested_builder.table_name() << "_index " << "ON " << nested_builder.table_name() << "(" << nested_builder.parameter_list() << ");\n\n"; if (ref_instruction) { create_postfix_ << "CREATE TABLE " << inst->name() << "(\n"; add_foreign_key(create_postfix_, this->table_name(), this->primary_key_name(), this->primary_key_type()); add_foreign_key(create_postfix_, nested_builder.table_name(), nested_builder.primary_key_name(), nested_builder.primary_key_type()); if (is_ordered) { create_postfix_ << "ordering INT,\n"; } create_postfix_.seekp(-2, std::ios_base::cur); create_postfix_ << ");\n\n"; if (insert_statements_.count(ref_instruction->id())) { std::stringstream err_msg; err_msg << "Conflicted sequence id= "<< ref_instruction->id() << " for "<< inst->name(); BOOST_THROW_EXCEPTION(std::runtime_error(err_msg.str())); } insert_statements& stmts = insert_statements_[ref_instruction->id()]; stmts.insert_item_stmt = construct_insert_statement(inst->name(), 2+is_ordered); stmts.primary_key_index = this->primary_key_index_; } else { add_foreign_key(create_current_, nested_builder.table_name(), nested_builder.primary_key_name(), nested_builder.primary_key_type()); num_columns_++; if (is_ordered) { create_current_ << " ordering INT,\n"; num_columns_++; } } } else { tables_creator nested_builder(insert_statements_, masks_, this->table_name(), this->primary_key_name(), this->primary_key_type()); nested_builder.visit(ref_instruction, 0); create_postfix_ << nested_builder.create_statements(); } }