|
- #include <cpphibernate/misc/print_container.h>
- #include <cpphibernate/driver/mariadb/classes/tables/table.h>
-
- #include <cppcore/misc/indent.h>
-
- #include <cpphibernate/types.inl>
- #include <cpphibernate/driver/mariadb/context/data_context.inl>
-
- using namespace ::cpphibernate;
- using namespace ::cpphibernate::mariadb;
-
- /* table_t */
-
- table_t::~table_t()
- { }
-
- std::ostream& table_t::print(std::ostream& os) const
- {
- using namespace ::cppcore;
-
- os << indent << '{'
- << incindent
- << indent << "\"id\": " << id << ","
- << indent << "\"dataset_id\": " << dataset_id << ","
- << indent << "\"base_dataset_id\": " << base_dataset_id << ","
- << indent << "\"derived_dataset_ids\": " << make_print_container(derived_dataset_ids, false) << ","
- << indent << "\"name\": \"" << name << "\","
- << indent << "\"base_table\": " << (base_table ? std::string("\"") + base_table->name + "\"" : "null") << ","
- << indent << "\"derived_tables\":" << make_print_container(derived_tables, true, [](auto& s, auto& ptr){
- s << indent << '"' << ptr->name << '"';
- }) << ","
- << indent << "\"primary_key_field\": " << (primary_key_field ? std::string("\"") + primary_key_field->name + "\"" : "null") << ","
- << indent << "\"foreign_key_fields\": " << make_print_container(foreign_key_fields, true, [](auto& s, auto& ptr){
- s << indent << '"' << ptr->name << '.' << ptr->name << '"';
- }) << ","
- << indent << "\"foreign_table_fields\": " << make_print_container(foreign_table_fields, true, [](auto& s, auto& ptr){
- s << indent << '"' << ptr->name << '"';
- }) << ","
- << indent << "\"foreign_table_one_fields\": " << make_print_container(foreign_table_one_fields, true, [](auto& s, auto& ptr){
- s << indent << '"' << ptr->name << '"';
- }) << ","
- << indent << "\"foreign_table_many_fields\": " << make_print_container(foreign_table_many_fields, true, [](auto& s, auto& ptr){
- s << indent << '"' << ptr->name << '"';
- }) << ","
- << indent << "\"data_fields\": " << make_print_container(data_fields, true, [](auto& s, auto& ptr){
- s << indent << '"' << ptr->name << '"';
- }) << ","
- << indent << "\"fields\":" << make_print_container(fields, true, [](auto& s, auto& field) {
- field->print(s);
- })
- << decindent
- << indent << '}';
-
- return os;
- }
-
- std::string table_t::get_primary_key(const data_context& context) const
- {
- assert(primary_key_field);
- if ( primary_key_field->is_default(context)
- && base_table)
- {
- auto key = get_key_from_base(context);
- primary_key_field->set(context, key);
- return key;
- }
- else
- {
- return *primary_key_field->get(context);
- }
- }
-
- std::string table_t::get_key_from_base(const data_context& context) const
- {
- if (!base_table)
- {
- throw exception(std::string("table has no base table: ") + name);
- }
- auto& statement = get_statement_key_from_base();
- auto base_key = base_table->get_primary_key(context);
- statement.set(0, base_key);
- auto result = context.connection.execute_stored(statement);
- if (!result)
- throw exception("unable to fetch key from database: unable to execute query!");
- auto row = result->next();
- if (!row)
- throw exception("unable to fetch key from database: result set is empty!");
- return row->at(0).get<std::string>();
- }
-
- ::cppmariadb::statement& table_t::get_statement_key_from_base() const
- {
- if (!_statement_key_from_base)
- {
- if (!base_table)
- throw exception(std::string("table has no base table: ") + name);
- assert(primary_key_field);
- assert(base_table);
- assert(base_table->primary_key_field);
- auto& key_info = *primary_key_field;
- auto& base_key = *base_table->primary_key_field;
- std::ostringstream os;
- os << "SELECT `"
- << key_info.name
- << "` FROM `"
- << key_info.table.name
- << "` WHERE `"
- << base_key.table.name
- << "_id`=?\?";
- _statement_key_from_base.reset(new ::cppmariadb::statement(os.str()));
- }
- return *_statement_key_from_base;
- }
|