void tables_creator::visit(const template_instruction *inst, void *) { table_name_ = inst->name(); primary_key_name_ = "rowid"; // The default primary key of SQLite3 create_current_ << "CREATE TABLE " << inst->name() << "(\n"; std::string expression = foreign_key_expression_.str(); create_current_ << expression; if (expression.size()) num_columns_++; traverse_subinstructions(inst); // remove last inserted ",\n" create_current_.seekp(-2, std::ios_base::cur); create_current_ << ");\n\n"; if (insert_statements_.count(inst->id())) { std::stringstream err_msg; err_msg << "Duplicated template id= " << inst->id() << " for " << inst->name(); BOOST_THROW_EXCEPTION(std::runtime_error(err_msg.str())); } insert_statements &stmts = insert_statements_[inst->id()]; stmts.insert_item_stmt = construct_insert_statement(inst->name(), num_columns_); stmts.primary_key_index = primary_key_index_; if (find_key_needed_ && primary_key_name_ == "rowid") { stmts.find_key_stmt = construct_find_key_statement(inst->name(), parameters_); stmts.primary_key_index = -1; } }
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(); } }