added: to Model: virtual void set_parent_key_in_childs()
for setting a parent key id in child models, it is called after after_insert() method added: SetFieldValueHelper class used for storing primary key values from a parent model git-svn-id: svn://ttmath.org/publicrep/morm/trunk@1204 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
161
src/model.h
161
src/model.h
@@ -132,6 +132,27 @@ public:
|
||||
// set object to default values
|
||||
virtual void clear();
|
||||
|
||||
// IMPROVE ME this will be protected
|
||||
// add set_field_value() functions for each POD type
|
||||
template<typename FieldValue>
|
||||
void set_field_value_generic(const wchar_t * db_field_name, const wchar_t * flat_field_name, const FieldValue & field_value)
|
||||
{
|
||||
ModelEnv model_env_local;
|
||||
model_env = &model_env_local;
|
||||
model_env->model_connector_mode = MORM_MODEL_CONNECTOR_MODE_SET_FIELD_VALUE;
|
||||
model_env->field_index = 0;
|
||||
|
||||
SetFieldValueHelper set_field_value_helper;
|
||||
FieldValueContainer<FieldValue> helper_object(field_value);
|
||||
|
||||
set_field_value_helper.add(db_field_name, flat_field_name, &helper_object, false);
|
||||
model_env->set_field_value_helper = &set_field_value_helper;
|
||||
|
||||
map_fields();
|
||||
|
||||
// what if an exception was thrown?
|
||||
model_env = nullptr;
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
@@ -272,9 +293,9 @@ protected:
|
||||
field_generic(field_name, field_name, field_value, insertable, updatable, is_primary_key);
|
||||
}
|
||||
|
||||
void field(const wchar_t * field_name, Model & field_value, bool insertable = true, bool updatable = true)
|
||||
void field(const wchar_t * field_name, Model & field_value, bool insertable = true, bool updatable = true, bool has_foreign_key = true)
|
||||
{
|
||||
field_model(field_name, field_name, field_value, insertable, updatable, true);
|
||||
field_model(field_name, field_name, field_value, insertable, updatable, has_foreign_key);
|
||||
}
|
||||
|
||||
template<typename ModelClass>
|
||||
@@ -394,9 +415,9 @@ protected:
|
||||
}
|
||||
|
||||
|
||||
void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, Model & field_value, bool insertable = true, bool updatable = true)
|
||||
void field(const wchar_t * db_field_name, const wchar_t * flat_field_name, Model & field_value, bool insertable = true, bool updatable = true, bool has_foreign_key = true)
|
||||
{
|
||||
field_model(db_field_name, flat_field_name, field_value, insertable, updatable, true);
|
||||
field_model(db_field_name, flat_field_name, field_value, insertable, updatable, has_foreign_key);
|
||||
}
|
||||
|
||||
template<typename ModelClass>
|
||||
@@ -651,6 +672,47 @@ protected:
|
||||
{
|
||||
if( model_connector && model_env )
|
||||
{
|
||||
if( model_env->model_connector_mode == MORM_MODEL_CONNECTOR_MODE_SET_FIELD_VALUE )
|
||||
{
|
||||
if( model_env->set_field_value_helper )
|
||||
{
|
||||
if( model_env->field_index >= 0 && (size_t)model_env->field_index < model_env->set_field_value_helper->size() )
|
||||
{
|
||||
if( is_the_same_field(db_field_name, model_env->set_field_value_helper->get_db_field_name(model_env->field_index)) &&
|
||||
is_the_same_field(flat_field_name, model_env->set_field_value_helper->get_flat_field_name(model_env->field_index)) )
|
||||
{
|
||||
model_env->set_field_value_helper->set_value(model_env->field_index, field_value);
|
||||
model_env->field_index += 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// IMPROVE ME
|
||||
// put some log here
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( model_env->model_connector_mode == MORM_MODEL_CONNECTOR_MODE_ITERATE_PRIMARY_KEY_VALUES && is_primary_key )
|
||||
{
|
||||
if( model_env->set_field_value_helper )
|
||||
{
|
||||
if( model_env->field_index >= 0 && (size_t)model_env->field_index < model_env->set_field_value_helper->size() )
|
||||
{
|
||||
FieldValueBase * helper_object = new FieldValueContainer<FieldValue>(field_value);
|
||||
model_env->set_field_value_helper->add_field_value_container(model_env->field_index, helper_object, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// IMPROVE ME
|
||||
// put some log here
|
||||
}
|
||||
}
|
||||
|
||||
model_env->field_index += 1;
|
||||
}
|
||||
|
||||
|
||||
if( model_env->model_connector_mode == MORM_MODEL_CONNECTOR_MODE_GENERATING_FLAT_STRING )
|
||||
{
|
||||
FlatConnector * flat_connector = model_connector->get_flat_connector();
|
||||
@@ -827,13 +889,13 @@ protected:
|
||||
field_model_left_join(db_field_name, flat_field_name, field_model, insertable, updatable, has_foreign_key, db_expression);
|
||||
}
|
||||
|
||||
if( db_expression->get_work_mode() == MORM_WORK_MODE_MODEL_FIELDS && db_expression->get_output_type() == MORM_OUTPUT_TYPE_DB_INSERT )
|
||||
if( db_expression->get_work_mode() == MORM_WORK_MODE_MODEL_FIELDS && db_expression->get_output_type() == MORM_OUTPUT_TYPE_DB_INSERT && has_foreign_key )
|
||||
{
|
||||
int not_used_object = 0;
|
||||
db_expression->field(db_field_name, not_used_object, insertable, updatable, false, model_env);
|
||||
}
|
||||
|
||||
if( db_expression->get_work_mode() == MORM_WORK_MODE_MODEL_VALUES && db_expression->get_output_type() == MORM_OUTPUT_TYPE_DB_INSERT )
|
||||
if( db_expression->get_work_mode() == MORM_WORK_MODE_MODEL_VALUES && db_expression->get_output_type() == MORM_OUTPUT_TYPE_DB_INSERT && has_foreign_key )
|
||||
{
|
||||
db_expression->set_output_type(MORM_OUTPUT_TYPE_DB_INSERT_PRIMARY_KEY);
|
||||
field_model.map_fields();
|
||||
@@ -902,6 +964,56 @@ protected:
|
||||
}
|
||||
}
|
||||
|
||||
void field_model_set_parent_key(const wchar_t * db_field_name, const wchar_t * flat_field_name, Model & field_model)
|
||||
{
|
||||
DbConnector * db_connector = model_connector->get_db_connector();
|
||||
|
||||
if( db_connector )
|
||||
{
|
||||
DbExpression * db_expression = db_connector->get_expression();
|
||||
|
||||
if( db_expression && !is_empty_field(db_field_name) )
|
||||
{
|
||||
int old_connector_mode = model_env->model_connector_mode;
|
||||
model_env->model_connector_mode = MORM_MODEL_CONNECTOR_MODE_ITERATE_PRIMARY_KEY_VALUES;
|
||||
|
||||
SetFieldValueHelper set_field_value_helper;
|
||||
set_field_value_helper.add(db_field_name, flat_field_name); // in the future we can have a primary key from more than one column
|
||||
model_env->set_field_value_helper = &set_field_value_helper;
|
||||
model_env->field_index = 0;
|
||||
|
||||
map_fields();
|
||||
|
||||
if( set_field_value_helper.empty() )
|
||||
{
|
||||
// IMPROVE ME
|
||||
// put some log: there is no a primary key in this model
|
||||
}
|
||||
else
|
||||
if( set_field_value_helper.size() == 1 )
|
||||
{
|
||||
ModelEnv model_env_local;
|
||||
model_env_local.copy_global_objects(*model_env);
|
||||
model_env_local.model_connector_mode = MORM_MODEL_CONNECTOR_MODE_SET_FIELD_VALUE;
|
||||
model_env_local.set_field_value_helper = &set_field_value_helper;
|
||||
model_env_local.field_index = 0;
|
||||
field_model.model_env = &model_env_local;
|
||||
|
||||
field_model.map_fields();
|
||||
field_model.model_env = nullptr;
|
||||
|
||||
model_env->set_field_value_helper = nullptr;
|
||||
model_env->model_connector_mode = old_connector_mode;
|
||||
}
|
||||
else
|
||||
{
|
||||
// IMPROVE ME
|
||||
// put some log: at the moment we only support a primary key from only one column
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void field_model(const wchar_t * db_field_name, const wchar_t * flat_field_name, Model & field_model, bool insertable, bool updatable, bool has_foreign_key)
|
||||
{
|
||||
@@ -913,11 +1025,27 @@ protected:
|
||||
field_model.model_env = &model_env_local;
|
||||
field_model.set_connector(model_connector);
|
||||
|
||||
if( model_env->model_connector_mode == MORM_MODEL_CONNECTOR_MODE_ITERATE_THROUGH_CHILDS_AND_INSERT )
|
||||
if( model_env->model_connector_mode == MORM_MODEL_CONNECTOR_MODE_SET_PARENT_ID && !has_foreign_key )
|
||||
{
|
||||
// IMPROVE ME what about if db_field_name is empty? not iterate in such a case?
|
||||
field_model.map_fields();
|
||||
field_model.insert_tree(true);
|
||||
field_model_set_parent_key(db_field_name, flat_field_name, field_model);
|
||||
}
|
||||
|
||||
if( model_env->model_connector_mode == MORM_MODEL_CONNECTOR_MODE_ITERATE_THROUGH_CHILDS_AND_INSERT && has_foreign_key )
|
||||
{
|
||||
if( !is_empty_field(db_field_name) )
|
||||
{
|
||||
field_model.map_fields();
|
||||
field_model.insert_tree(true);
|
||||
}
|
||||
}
|
||||
|
||||
if( model_env->model_connector_mode == MORM_MODEL_CONNECTOR_MODE_ITERATE_THROUGH_CHILDS_AND_INSERT_XXX && !has_foreign_key )
|
||||
{
|
||||
if( !is_empty_field(db_field_name) )
|
||||
{
|
||||
field_model.map_fields();
|
||||
field_model.insert_tree(true);
|
||||
}
|
||||
}
|
||||
|
||||
if( model_env->model_connector_mode == MORM_MODEL_CONNECTOR_MODE_ITERATE_THROUGH_CHILDS_AND_UPDATE )
|
||||
@@ -1155,6 +1283,17 @@ protected:
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
virtual void set_parent_key_in_childs()
|
||||
{
|
||||
if( model_env )
|
||||
{
|
||||
model_env->model_connector_mode = MORM_MODEL_CONNECTOR_MODE_SET_PARENT_ID;
|
||||
map_fields();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
|
||||
@@ -1217,9 +1356,11 @@ public:
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
virtual bool is_empty_field(const wchar_t * value);
|
||||
virtual bool is_the_same_field(const wchar_t * field1, const wchar_t * field2);
|
||||
|
||||
template<typename ModelClass> friend class Finder;
|
||||
template<typename ModelClass> friend class Cursor;
|
||||
|
Reference in New Issue
Block a user