|
- #pragma once
-
- #include <cppmariadb.h>
-
- #include "../../types.h"
- #include "../attributes/attributes.h"
-
- namespace cpphibernate {
- namespace mariadb {
-
- struct table_t;
- struct data_context;
- struct create_update_context;
- struct read_context;
-
- using read_context_ptr_u = std::unique_ptr<read_context>;
-
- /**
- * @brief Abstract field class.
- */
- struct field_t
- {
- public:
- size_t id { 0 }; //!< unique id of the field
- size_t value_id { 0 }; //!< unique id of the value type
- size_t real_value_id { 0 }; //!< unique id of the real/unwrapped value type
-
- bool value_is_nullable { false }; //!< value is stored in a nullable container
- bool value_is_pointer { false }; //!< value is stored in a pointer container
- bool value_is_container { false }; //!< value is stored in a container
- bool value_is_ordered { false }; //!< value is stored in a ordered container (vector, list, ...)
- bool value_is_auto_incremented { false }; //!< value is a auto incremented field
-
- const table_t& table; //!< table this field belongs to
- const table_t* referenced_table { nullptr }; //!< table that belongs to the value (if exists)
-
- std::string name; //!< name of the SQL field
- std::string type; //!< SQL type name
- std::string create_arguments; //!< additional arguments for CREATE TABLE command
-
- std::string convert_to_open; //!< SQL code to open the "convert to" operation
- std::string convert_to_close; //!< SQL code to close the "convert to" operation
- std::string convert_from_open; //!< SQL code to open the "convert from" operation
- std::string convert_from_close; //!< SQL code to close the "convert from" operation
-
- attributes_t attributes; //!< attributes for the field
-
- public:
- /**
- * @brief Value constructor. Creates a mariadb field from the cpphibernate field.
- *
- * @param[in] p_owner Owner of the field.
- * @param[in] p_schema Cpphibernate schema the mariadb field belongs to.
- * @param[in] p_table Cpphibernate table the mariadb field belongs to.
- * @param[in] p_field Cpphibernate field to create mariadb field for.
- */
- template<
- typename T_schema,
- typename T_table,
- typename T_field>
- inline field_t(
- const table_t& p_owner,
- const T_schema& p_schema,
- const T_table& p_table,
- const T_field& p_field);
-
- /**
- * @brief Move constructor.
- */
- inline field_t(field_t&& other) = delete;
-
- /**
- * @brief Copy constructor.
- */
- inline field_t(const field_t&) = delete;
-
- /**
- * @brief Destructor.
- */
- virtual ~field_t() = 0;
-
- /**
- * @brief Print the field values to the passed stream.
- */
- std::ostream& print(std::ostream& os) const;
-
- public:
- /**
- * @brief Get the value of this field from the current dataset.
- *
- * @param[in] context Data context to get the dataset from.
- *
- * @return Value of the field from the current dataset.
- */
- virtual value_t get(const data_context& context) const;
-
- /**
- * @brief Set a new value of this field in the current dataset.
- *
- * @param[in] context Data context to get the dataset from.
- * @param[in] value Value of the field to assign to the dataset.
- */
- virtual void set(const data_context& context, const value_t& value) const;
-
- /**
- * @brief Check if the value that is represented by this field has the default value.
- *
- * @param[in] context Data context to receive the value of the assigned dataset.
- *
- * @retval true If the dataset in the context is the default value for this field.
- * @retval false If the dataset in the context is not the default value for this field.
- */
- virtual bool is_default(const data_context& context) const;
-
- /**
- * @brief Create a new value that is represented by this field.
- *
- * @param[in] connection Connection to use to create the value.
- *
- * @return New created value for this field.
- */
- virtual std::string generate_value(::cppmariadb::connection& connection) const;
-
- public:
- /**
- * @brief Execute a create/update operation on the foreign table this field represents (if it is a foreign field)
- *
- * @param[in] context Create/Update context with the needed data for the operation.
- *
- * @return Key of the created/updated foreign dataset.
- */
- virtual value_t foreign_create_update(const create_update_context& context) const;
-
- /**
- * @brief Create a read context for the foreign key field.
- *
- * @param[in] context Read context to inherit new context from.
- * @param[in] create_fake Create a fake context (not data will be written).
- *
- * @return The created read context.
- */
- virtual read_context_ptr_u foreign_read(const read_context& context, bool create_fake) const;
-
- /**
- * @brief Delete all old datasets from the foreign table.
- *
- * If we update an exsisting foreign field with a new foreign dataset, the key of this dataset
- * changes. So we need to delete the old/exsisting foreign dataset from the database.
- *
- * @param[in] context Create/Update context with the needed data for the operation.
- * @param[in] primary_key Primary key of the current database.
- * @param[in] foreign_key Primary kes of the new foreign dataset.
- */
- void foreign_one_delete(
- const create_update_context& context,
- const std::string& primary_key,
- const value_t& foreign_key) const;
-
- /**
- * @brief Update the foreign dataset. Set the foreign key field to NULL if it matches the passed
- * primary key of the owner dataset.
- */
- void foreign_many_update(
- const create_update_context& context,
- const std::string& primary_key) const;
-
- private:
- /**
- * @brief Initialize the field.
- */
- void init();
-
- private:
- using statement_ptr_u = std::unique_ptr<::cppmariadb::statement>;
-
- mutable statement_ptr_u _statement_foreign_one_delete_key_known; //!< Statement to delete foreign datasets within an update operation (for known foreign keys)
- mutable statement_ptr_u _statement_foreign_one_delete_key_unknown; //!< Statement to delete foreign datasets within an update operation (for unknown foreign keys)
- mutable statement_ptr_u _statement_foreign_many_update; //!< Statement to update foreign many dataset (set foreign key to NULL if primary key of the owner matches)
-
- /**
- * @brief Get the statement to delete foreign datasets within an update operation (for known foreign keys).
- */
- ::cppmariadb::statement& get_statement_foreign_one_delete_key_known() const;
-
- /**
- * @brief Get the statement to delete foreign datasets within an update operation (for unknown foreign keys).
- */
- ::cppmariadb::statement& get_statement_foreign_one_delete_key_unknown() const;
-
- /**
- * @brief Get the statement to update foreign many dataset (set foreign key to NULL if primary key of the owner matches).
- */
- ::cppmariadb::statement& get_statement_foreign_many_update() const;
- };
-
- using field_ptr_u = std::unique_ptr<const field_t>;
-
- namespace __impl
- {
-
- /**
- * @brief Helper type to build table.
- */
- template<typename X, typename = void>
- struct field_builder;
-
- }
-
- /**
- * @brief Predicate to create mariadb table class.
- */
- constexpr decltype(auto) make_field = mp::generic_predicate<__impl::field_builder> { };
-
- } }
|