|
- #pragma once
-
- #include "create_update.h"
-
- #include "../classes/schema/schema.inl"
- #include "../helper/nullable_helper.inl"
- #include "../context/create_update_context.inl"
-
- namespace cpphibernate {
- namespace mariadb {
-
- /* create_update_impl_t - default (normal dataset) */
-
- template<typename T_dataset, typename>
- struct create_update_impl_t
- {
- using dataset_type = T_dataset;
-
- static inline value_t apply(const create_update_context& context, bool strict = true)
- {
- using namespace ::cppmariadb;
-
- value_t ret;
-
- auto dataset_id = get_type_id(hana::type_c<dataset_type>);
- auto& connection = context.connection;
- auto& schema = context.schema;
- auto& table = schema.table(dataset_id);
-
- assert(table.primary_key_field);
- transaction_lock trans(connection);
-
- /* if the value of primary key field does not match the operation of the context */
- if (table.primary_key_field->is_default(context) != context.is_create())
- {
- /* if we are not in strict mode, change the context to an update context */
- if (!strict)
- {
- static const filter_t dummy;
- ret = table.create_update(context.is_create()
- ? context.make_update_context(dummy)
- : context.make_create_context());
- }
-
- /* if we expect an update operation in strict mode throw an exception
- * because an update operation needs an primary key assigned */
- else if (context.is_update())
- {
- throw exception("can not update dataset with no primary key assigned!");
- }
-
- /* if we expect an create operation in strict mode throw an exception
- because an create operation expects the primary key to not be assigned */
- else
- {
- throw exception("can not create dataset with primary key assigned!");
- }
- }
- else
- {
- ret = table.create_update(context);
- }
- trans.commit();
- return ret;
- }
- };
-
- /* create_update_impl_t - nullable */
-
- template<typename T_dataset>
- struct create_update_impl_t<
- T_dataset,
- mp::enable_if_t<is_nullable_v<T_dataset>>>
- {
- using dataset_type = T_dataset;
- using nullable_helper_type = nullable_helper<dataset_type>;
-
- static inline value_t apply(const create_update_context& context, bool strict = true)
- {
- value_t ret;
- auto& dataset = context.get<dataset_type>();
- auto* value = nullable_helper_type::get(dataset);
-
- if (value)
- {
- using new_dataset_type = mp::decay_t<decltype(*value)>;
- using new_create_update_impl_type = create_update_impl_t<new_dataset_type>;
- ret = new_create_update_impl_type::apply(change_context(context, *value), strict);
- }
- else if (strict)
- {
- throw exception("can not create nullable type with no value!");
- }
- return ret;
- }
- };
-
- /* create_update_impl_t - container */
-
- template<typename T_dataset>
- struct create_update_impl_t<
- T_dataset,
- mp::enable_if_t<is_container_v<T_dataset>>>
- {
- using dataset_type = T_dataset;
-
- static inline value_t apply(const create_update_context& context, bool strict = true)
- {
- using namespace ::cppmariadb;
-
- value_t ret;
- auto& connection = context.connection;
- auto& dataset = context.get<dataset_type>();
-
- transaction_lock trans(connection);
- ssize_t index = 0;
- for (auto& x : dataset)
- {
- using new_dataset_type = mp::decay_t<decltype(x)>;
- using new_create_update_impl_type = create_update_impl_t<new_dataset_type>;
- auto new_context = change_context(context, x);
- new_context.index = index++;
- new_create_update_impl_type::apply(new_context, strict);
- }
- trans.commit();
- return ret;
- }
- };
-
- } }
|