[glom/modification: 21/33] in progress
- From: Murray Cumming <murrayc src gnome org>
- To: svn-commits-list gnome org
- Subject: [glom/modification: 21/33] in progress
- Date: Thu, 4 Jun 2009 17:01:05 -0400 (EDT)
commit ba2ca0a037e9d72311ca709e3cde5306815ab65c
Author: Murray Cumming <murrayc murrayc com>
Date: Thu May 7 19:02:09 2009 +0200
in progress
---
glom/base_db.cc | 305 +++++++++++++++++++++-------
glom/base_db.h | 11 +
glom/libglom/connectionpool.cc | 2 +-
glom/libglom/data_structure/field.cc | 10 +-
glom/libglom/data_structure/field.h | 5 +
glom/libglom/standard_table_prefs_fields.h | 7 +
glom/libglom/utils.cc | 21 ++
glom/libglom/utils.h | 3 +
8 files changed, 288 insertions(+), 76 deletions(-)
diff --git a/glom/base_db.cc b/glom/base_db.cc
index 3c76544..8ed76fd 100644
--- a/glom/base_db.cc
+++ b/glom/base_db.cc
@@ -62,7 +62,7 @@
namespace Glom
{
-
+
template<class T_Element>
class predicate_LayoutItemIsEqual
{
@@ -91,6 +91,9 @@ private:
sharedptr<const T_Element> m_layout_item;
};
+//Intializing static members:
+Base_DB::type_extra_field_values Base_DB::m_extra_field_values;
+
Base_DB::Base_DB()
{
@@ -1021,22 +1024,22 @@ bool Base_DB::add_standard_tables() const
Document::type_vec_fields fields;
- sharedptr<Field> primary_key(new Field()); //It's not used, because there's only one record, but we must have one.
+ sharedptr<Field> primary_key = sharedptr<Field>::create(); //It's not used, because there's only one record, but we must have one.
primary_key->set_name(GLOM_STANDARD_TABLE_AUTOINCREMENTS_FIELD_ID);
primary_key->set_glom_type(Field::TYPE_NUMERIC);
fields.push_back(primary_key);
- sharedptr<Field> field_table_name(new Field());
+ sharedptr<Field> field_table_name = sharedptr<Field>::create();
field_table_name->set_name(GLOM_STANDARD_TABLE_AUTOINCREMENTS_FIELD_TABLE_NAME);
field_table_name->set_glom_type(Field::TYPE_TEXT);
fields.push_back(field_table_name);
- sharedptr<Field> field_field_name(new Field());
+ sharedptr<Field> field_field_name = sharedptr<Field>::create();
field_field_name->set_name(GLOM_STANDARD_TABLE_AUTOINCREMENTS_FIELD_FIELD_NAME);
field_field_name->set_glom_type(Field::TYPE_TEXT);
fields.push_back(field_field_name);
- sharedptr<Field> field_next_value(new Field());
+ sharedptr<Field> field_next_value = sharedptr<Field>::create();
field_next_value->set_name(GLOM_STANDARD_TABLE_AUTOINCREMENTS_FIELD_NEXT_VALUE);
field_next_value->set_glom_type(Field::TYPE_TEXT);
fields.push_back(field_next_value);
@@ -1169,18 +1172,18 @@ void Base_DB::set_database_preferences(const SystemPrefs& prefs)
if(get_field_exists_in_database(GLOM_STANDARD_TABLE_PREFS_TABLE_NAME, GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_LOGO))
{
params->add_holder("org_logo", prefs.m_org_logo);
- optional_part_logo = "\"" GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_LOGO "\" = ##org_logo::GDA_TYPE_BINARY, ";
+ optional_part_logo = "\"" GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_LOGO "\" = " + Field::get_gda_holder_string_generic(GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_LOGO, GDA_TYPE_BINARY) + ", ";
}
const Glib::ustring sql_query = "UPDATE \"" GLOM_STANDARD_TABLE_PREFS_TABLE_NAME "\" SET "
- "\"" GLOM_STANDARD_TABLE_PREFS_FIELD_NAME "\" = ##name::gchararray, "
- + optional_part_logo +
- "\"" GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_STREET "\" = ##street::gchararray, "
- "\"" GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_STREET2 "\" = ##street2::gchararray, "
- "\"" GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_TOWN "\" = ##town::gchararray, "
- "\"" GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_COUNTY "\" = ##county::gchararray, "
- "\"" GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_COUNTRY "\" = ##country::gchararray, "
- "\"" GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_POSTCODE "\" = ##postcode::gchararray"
- " WHERE \"" GLOM_STANDARD_TABLE_PREFS_FIELD_ID "\" = 1";
+ "\"" GLOM_STANDARD_TABLE_PREFS_FIELD_NAME "\" = " + Field::get_gda_holder_string_generic(GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_STREET, G_TYPE_STRING) + ", "
+ + optional_part_logo
+ + "\"" GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_STREET "\"" = Field::get_gda_holder_string_generic(GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_STREET, G_TYPE_STRING) + ", "
+ + "\"" GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_STREET2 "\"" = Field::get_gda_holder_string_generic(GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_STREET2, G_TYPE_STRING) + ", "
+ + "\"" GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_TOWN "\"" = Field::get_gda_holder_string_generic(GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_TOWN, G_TYPE_STRING) + ", "
+ + "\"" GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_COUNTY "\"" = Field::get_gda_holder_string_generic(GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_COUNTY, G_TYPE_STRING) + ", "
+ + "\"" GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_COUNTRY "\"" = Field::get_gda_holder_string_generic(GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_COUNTRY, G_TYPE_STRING) + ", "
+ + "\"" GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_POSTCODE "\"" = Field::get_gda_holder_string_generic(GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_ADDRESS_POSTCODE, G_TYPE_STRING)
+ + " WHERE \"" GLOM_STANDARD_TABLE_PREFS_FIELD_ID "\" = 1";
bool test = false;
test = query_execute(sql_query, params);
@@ -1192,6 +1195,48 @@ void Base_DB::set_database_preferences(const SystemPrefs& prefs)
get_document()->set_database_title(prefs.m_name);
}
+
+static sharedptr<Field> create_field(const Glib::ustring& name, const Glib::ustring& description, Field::glom_field_type field_type)
+{
+ sharedptr<Field> field = sharedptr<Field>::create();
+ field->set_name(name);
+ field->set_title(description);
+ field->set_glom_type(field_type);
+
+ return field;
+}
+
+///Adds the field to the vector if it is not already there.
+static void add_field(Base_DB::type_vec_fields& vec, const Glib::ustring& name, const Glib::ustring& description, Field::glom_field_type field_type)
+{
+ if(std::find_if(vec.begin(), vec.end(), predicate_FieldHasName<Field>(name)) != vec.end())
+ return;
+
+ sharedptr<Field> field = create_field(name, description, field_type);
+ vec.push_back(field);
+}
+
+
+static sharedptr<Field> create_field(const Glib::ustring& name, const Glib::ustring& description, Field::glom_field_type field_type)
+{
+ sharedptr<Field> field = sharedptr<Field>::create();
+ field->set_name(name);
+ field->set_title(description);
+ field->set_glom_type(field_type);
+
+ return field;
+}
+
+///Adds the field to the vector if it is not already there.
+static void add_field(Base_DB::type_vec_fields& vec, const Glib::ustring& name, const Glib::ustring& description, Field::glom_field_type field_type)
+{
+ if(std::find_if(vec.begin(), vec.end(), predicate_FieldHasName<Field>(name)) != vec.end())
+ return;
+
+ sharedptr<Field> field = create_field(name, description, field_type);
+ vec.push_back(field);
+}
+
bool Base_DB::create_table_with_default_fields(const Glib::ustring& table_name)
{
if(table_name.empty())
@@ -1213,9 +1258,8 @@ bool Base_DB::create_table_with_default_fields(const Glib::ustring& table_name)
bool created = false;
//Primary key:
- sharedptr<Field> field_primary_key(new Field());
- field_primary_key->set_name(table_name + "_id");
- field_primary_key->set_title(table_name + " ID");
+ sharedptr<Field> field_primary_key =
+ create_field(table_name + "_id", table_name + " ID", Field::TYPE_NUMERIC);
field_primary_key->set_primary_key();
field_primary_key->set_auto_increment();
@@ -1230,17 +1274,12 @@ bool Base_DB::create_table_with_default_fields(const Glib::ustring& table_name)
fields.push_back(field_primary_key);
//Description:
- sharedptr<Field> field_description(new Field());
- field_description->set_name("description");
- field_description->set_title(_("Description")); //Use a translation, because the original locale will be marked as non-English if the current locale is non-English.
- field_description->set_glom_type(Field::TYPE_TEXT);
- fields.push_back(field_description);
+ //Use a translation for the title, because the original locale will be marked as non-English if the current locale is non-English.
+ add_field(fields, "description", _("Description"), Field::TYPE_TEXT);
//Comments:
- sharedptr<Field> field_comments(new Field());
- field_comments->set_name("comments");
- field_comments->set_title(_("Comments"));
- field_comments->set_glom_type(Field::TYPE_TEXT);
+ sharedptr<Field> field_comments =
+ create_field("comments", _("Comments"), Field::TYPE_TEXT);
field_comments->m_default_formatting.set_text_format_multiline();
fields.push_back(field_comments);
@@ -1287,15 +1326,22 @@ bool Base_DB::create_table(const sharedptr<const TableInfo>& table_info, const D
Document::type_vec_fields fields = fields_in;
- //Create the standard field too:
+ //Create the standard fields too:
+ //We do this here instead of in create_table_with_default_fields() so they
+ //are added even when creating from examples that don't mention them.
+
//(We don't actually use this yet)
- if(std::find_if(fields.begin(), fields.end(), predicate_FieldHasName<Field>(GLOM_STANDARD_FIELD_LOCK)) == fields.end())
- {
- sharedptr<Field> field = sharedptr<Field>::create();
- field->set_name(GLOM_STANDARD_FIELD_LOCK);
- field->set_glom_type(Field::TYPE_TEXT);
- fields.push_back(field);
- }
+ add_field(fields, GLOM_STANDARD_FIELD_LOCK, _("Record Lock (Internal)"), Field::TYPE_TEXT);
+
+ //Creation/Modification Date/Time:
+ //These are filled with appropriate values by Glom at appropriate times.
+ //TODO: The titles are not used.
+ add_field(fields, GLOM_STANDARD_DEFAULT_FIELD_CREATION_DATE, _("Creation Date"), Field::TYPE_DATE);
+ add_field(fields, GLOM_STANDARD_DEFAULT_FIELD_CREATION_TIME, _("Creation Time"), Field::TYPE_TIME);
+ add_field(fields, GLOM_STANDARD_DEFAULT_FIELD_CREATION_USER, _("Creation User"), Field::TYPE_TEXT);
+ add_field(fields, GLOM_STANDARD_DEFAULT_FIELD_MODIFICATION_DATE, _("Modification Date"), Field::TYPE_DATE);
+ add_field(fields, GLOM_STANDARD_DEFAULT_FIELD_MODIFICATION_TIME, _("Modification Time"), Field::TYPE_TIME);
+ add_field(fields, GLOM_STANDARD_DEFAULT_FIELD_MODIFICATION_USER, _("Modification User"), Field::TYPE_TEXT);
//Create SQL to describe all fields in this table:
Glib::ustring sql_fields;
@@ -2468,7 +2514,8 @@ bool Base_DB::set_field_value_in_database(const LayoutFieldInRecord& field_in_re
return set_field_value_in_database(field_in_record, Gtk::TreeModel::iterator(), field_value, use_current_calculations, parent_window);
}
-bool Base_DB::set_field_value_in_database(const LayoutFieldInRecord& layoutfield_in_record, const Gtk::TreeModel::iterator& row, const Gnome::Gda::Value& field_value, bool use_current_calculations, Gtk::Window* /* parent_window */)
+
+bool Base_DB::set_field_value_in_database(const LayoutFieldInRecord& layoutfield_in_record, const Gtk::TreeModel::iterator& row, const Gnome::Gda::Value& field_value, bool use_current_calculations, Gtk::Window* parent_window)
{
Document* document = get_document();
g_assert(document);
@@ -2489,60 +2536,172 @@ bool Base_DB::set_field_value_in_database(const LayoutFieldInRecord& layoutfield
}
const Glib::ustring field_name = field_in_record.m_field->get_name();
- if(!field_name.empty()) //This should not happen.
- {
- Glib::RefPtr<Gnome::Gda::Set> params = Gnome::Gda::Set::create();
- params->add_holder(field_in_record.m_field->get_holder(field_value));
- params->add_holder(field_in_record.m_key->get_holder(field_in_record.m_key_value));
+ if(field_name.empty()) //This should not happen.
+ return false;
- Glib::ustring strQuery = "UPDATE \"" + field_in_record.m_table_name + "\"";
- strQuery += " SET \"" + field_in_record.m_field->get_name() + "\" = " + field_in_record.m_field->get_gda_holder_string();
- strQuery += " WHERE \"" + field_in_record.m_key->get_name() + "\" = " + field_in_record.m_key->get_gda_holder_string();
+
+ Glib::RefPtr<Gnome::Gda::Set> params = Gnome::Gda::Set::create();
+ params->add_holder(field_in_record.m_field->get_holder(field_value));
+ params->add_holder(field_in_record.m_key->get_holder(field_in_record.m_key_value));
+
+ const Glib::ustring table_name = field_in_record.m_table_name;
+ Glib::ustring strQuery = "UPDATE \"" + field_in_record.m_table_name + "\"";
+ strQuery += " SET \"" + field_in_record.m_field->get_name() + "\" = " + field_in_record.m_field->get_gda_holder_string();
+
+ //Set these too, each time we change a value:
+ //We check for existence because the user may delete these fields:
+ //TODO: Only do this if not using Postgres?
+ // And use the Postgres cleverness to do it instead? Maybe like this:
+ // http://blog.revsys.com/2006/08/automatically_u.html
+ ConnectionPool* connection_pool = ConnectionPool::get_instance();
-#ifdef GLIBMM_EXCEPTIONS_ENABLED
- try //TODO: The exceptions are probably already handled by query_execute(0.
-#endif
+ if(m_extra_field_values.empty())
+ {
+ //Fill the field information:
+ m_extra_field_values[GLOM_STANDARD_DEFAULT_FIELD_MODIFICATION_DATE] =
+ FieldTypeValue(G_TYPE_DATE, Utils::get_current_date_utc_as_value());
+ m_extra_field_values[GLOM_STANDARD_DEFAULT_FIELD_MODIFICATION_TIME] =
+ FieldTypeValue(GDA_TYPE_TIME, Utils::get_current_time_utc_as_value());
+ m_extra_field_values[GLOM_STANDARD_DEFAULT_FIELD_MODIFICATION_USER] =
+ FieldTypeValue(G_TYPE_STRING, Gnome::Gda::Value(connection_pool->get_user()));
+ }
+ else
+ {
+ //Just fill the values:
+ m_extra_field_values[GLOM_STANDARD_DEFAULT_FIELD_MODIFICATION_DATE].second =
+ Utils::get_current_date_utc_as_value();
+ m_extra_field_values[GLOM_STANDARD_DEFAULT_FIELD_MODIFICATION_TIME].second =
+ Utils::get_current_time_utc_as_value();
+ m_extra_field_values[GLOM_STANDARD_DEFAULT_FIELD_MODIFICATION_USER].second =
+ Gnome::Gda::Value(connection_pool->get_user());
+ }
+
+ for(type_extra_field_values::const_iterator iter = m_extra_field_values.begin(); iter != m_extra_field_values.end(); ++iter)
+ {
+ const FieldTypeValue& item = iter->second;
+ if(get_field_exists_in_database(table_name, iter->first))
{
- const bool test = query_execute(strQuery, params); //TODO: Respond to failure.
- if(!test)
- {
- std::cerr << "Box_Data::set_field_value_in_database(): UPDATE failed." << std::endl;
- return false; //failed.
- }
+ strQuery += ", \"" + Glib::ustring(iter->first) /* name */ + "\" = " +
+ Field::get_gda_holder_string_generic(iter->first /* name */, item.first /* gtype */);
+ params->add_holder_as_value(iter->first /* name */, item.second /* value */);
}
+ }
+
+ strQuery += " WHERE \"" + field_in_record.m_key->get_name() + "\" = " + field_in_record.m_key->get_gda_holder_string();
+
#ifdef GLIBMM_EXCEPTIONS_ENABLED
- catch(const Glib::Exception& ex)
- {
- handle_error(ex);
- return false;
- }
- catch(const std::exception& ex)
+ try //TODO: The exceptions are probably already handled by query_execute(0.
+#endif
+ {
+ const bool test = query_execute(strQuery, params); //TODO: Respond to failure.
+ if(!test)
{
- handle_error(ex);
- return false;
+ std::cerr << "Box_Data::set_field_value_in_database(): UPDATE failed." << std::endl;
+ return false; //failed.
}
+ }
+#ifdef GLIBMM_EXCEPTIONS_ENABLED
+ catch(const Glib::Exception& ex)
+ {
+ handle_error(ex);
+ return false;
+ }
+ catch(const std::exception& ex)
+ {
+ handle_error(ex);
+ return false;
+ }
#endif
- //Get-and-set values for lookup fields, if this field triggers those relationships:
- do_lookups(layoutfield_in_record, row, field_value);
+ //Get-and-set values for lookup fields, if this field triggers those relationships:
+ do_lookups(layoutfield_in_record, row, field_value);
- //Update related fields, if this field is used in the relationship:
- refresh_related_fields(layoutfield_in_record, row, field_value);
+ //Update related fields, if this field is used in the relationship:
+ refresh_related_fields(layoutfield_in_record, row, field_value);
- //Calculate any dependent fields.
- //TODO: Make lookups part of this?
- //Prevent circular calculations during the recursive do_calculations:
- {
- //Recalculate any calculated fields that depend on this calculated field.
- //g_warning("Box_Data::set_field_value_in_database(): calling do_calculations");
+ //Calculate any dependent fields.
+ //TODO: Make lookups part of this?
+ //Prevent circular calculations during the recursive do_calculations:
+ {
+ //Recalculate any calculated fields that depend on this calculated field.
+ //g_warning("Box_Data::set_field_value_in_database(): calling do_calculations");
- do_calculations(layoutfield_in_record, !use_current_calculations);
- }
+ do_calculations(layoutfield_in_record, !use_current_calculations);
}
+ //For the extra fields,
+ //show the new database values in the UI, if the fields are on the layout:
+ for(type_extra_field_values::const_iterator iter = m_extra_field_values.begin(); iter != m_extra_field_values.end(); ++iter)
+ {
+ const FieldTypeValue& item = iter->second;
+
+ sharedptr<LayoutItem_Field> layout_item = glom_sharedptr_clone(layoutfield_in_record.m_field);
+ layout_item->set_full_field_details(
+ get_fields_for_table_one_field(table_name, iter->first /* name */) );
+ set_entered_field_data(row, layout_item, item.second /* value */);
+ }
+
return true;
}
+bool Base_DB::set_record_creation_fields(const LayoutFieldInRecord& layoutfield_in_record, const Gtk::TreeModel::iterator& row, Gtk::Window* parent_window)
+{
+ const Glib::ustring table_name = layoutfield_in_record.m_field ?
+ layoutfield_in_record.m_field->get_table_used(layoutfield_in_record.m_table_name) :
+ layoutfield_in_record.m_table_name;
+
+ //Set the values in the database:
+ const Gnome::Gda::Value value_date = Utils::get_current_date_utc_as_value();
+ const Gnome::Gda::Value value_time = Utils::get_current_time_utc_as_value();
+ ConnectionPool* connection_pool = ConnectionPool::get_instance();
+ const Gnome::Gda::Value value_user(connection_pool->get_user());
+
+
+
+ //Show the new database values in the UI, if the fields are on the layout:
+ sharedptr<LayoutItem_Field> layout_item = glom_sharedptr_clone(layoutfield_in_record.m_field);
+ layout_item->set_full_field_details(
+ get_fields_for_table_one_field(table_name, GLOM_STANDARD_DEFAULT_FIELD_CREATION_DATE) );
+ set_entered_field_data(row, layout_item, value_date);
+ layout_item->set_full_field_details(
+ get_fields_for_table_one_field(table_name, GLOM_STANDARD_DEFAULT_FIELD_CREATION_TIME) );
+ set_entered_field_data(row, layout_item, value_time);
+ layout_item->set_full_field_details(
+ get_fields_for_table_one_field(table_name, GLOM_STANDARD_DEFAULT_FIELD_CREATION_USER) );
+ set_entered_field_data(row, layout_item, value_user);
+
+ return true;
+}
+
+bool Base_DB::set_record_modification_fields(const LayoutFieldInRecord& layoutfield_in_record, const Gtk::TreeModel::iterator& row, Gtk::Window* parent_window)
+{
+ const Glib::ustring table_name = layoutfield_in_record.m_field ?
+ layoutfield_in_record.m_field->get_table_used(layoutfield_in_record.m_table_name) :
+ layoutfield_in_record.m_table_name;
+
+ //Set the values in the database:
+ const Gnome::Gda::Value value_date = Utils::get_current_date_utc_as_value();
+ const Gnome::Gda::Value value_time = Utils::get_current_time_utc_as_value();
+ ConnectionPool* connection_pool = ConnectionPool::get_instance();
+ const Gnome::Gda::Value value_user(connection_pool->get_user());
+
+
+
+ //Show the new database values in the UI, if the fields are on the layout:
+ sharedptr<LayoutItem_Field> layout_item = glom_sharedptr_clone(layoutfield_in_record.m_field);
+ layout_item->set_full_field_details(
+ get_fields_for_table_one_field(table_name, GLOM_STANDARD_DEFAULT_FIELD_MODIFICATION_DATE) );
+ set_entered_field_data(row, layout_item, value_date);
+ layout_item->set_full_field_details(
+ get_fields_for_table_one_field(table_name, GLOM_STANDARD_DEFAULT_FIELD_MODIFICATION_TIME) );
+ set_entered_field_data(row, layout_item, value_time);
+ layout_item->set_full_field_details(
+ get_fields_for_table_one_field(table_name, GLOM_STANDARD_DEFAULT_FIELD_MODIFICATION_USER) );
+ set_entered_field_data(row, layout_item, value_user);
+
+ return true;
+}
+
Gnome::Gda::Value Base_DB::get_field_value_in_database(const LayoutFieldInRecord& field_in_record, Gtk::Window* /* parent_window */)
{
Gnome::Gda::Value result; //TODO: Return suitable empty value for the field when failing?
diff --git a/glom/base_db.h b/glom/base_db.h
index ec8c061..0279bed 100644
--- a/glom/base_db.h
+++ b/glom/base_db.h
@@ -166,6 +166,8 @@ protected:
virtual void set_entered_field_data(const Gtk::TreeModel::iterator& row, const sharedptr<const LayoutItem_Field>& field, const Gnome::Gda::Value& value);
+ /** This identifies a specific field in specific row of a table.
+ */
class FieldInRecord
{
public:
@@ -304,6 +306,9 @@ protected:
bool set_field_value_in_database(const LayoutFieldInRecord& field_in_record, const Gnome::Gda::Value& field_value, bool use_current_calculations = false, Gtk::Window* parent_window = 0);
bool set_field_value_in_database(const LayoutFieldInRecord& field_in_record, const Gtk::TreeModel::iterator& row, const Gnome::Gda::Value& field_value, bool use_current_calculations = false, Gtk::Window* parent_window = 0);
+ bool set_record_creation_fields(const LayoutFieldInRecord& layoutfield_in_record, const Gtk::TreeModel::iterator& row, Gtk::Window* parent_window);
+ bool set_record_modification_fields(const LayoutFieldInRecord& layoutfield_in_record, const Gtk::TreeModel::iterator& row, Gtk::Window* parent_window);
+
///Get a single field value from the database.
Gnome::Gda::Value get_field_value_in_database(const LayoutFieldInRecord& field_in_record, Gtk::Window* parent_window);
@@ -404,6 +409,12 @@ protected:
static bool handle_error();
type_field_calcs m_FieldsCalculationInProgress; //Prevent circular calculations and recalculations.
+
+ //Extra creation/modification fields to set:
+ typedef std::pair<GType, Gnome::Gda::Value> FieldTypeValue;
+ typedef std::map<const gchar*, FieldTypeValue> type_extra_field_values;
+ static type_extra_field_values m_extra_field_values;
+
};
} //namespace Glom
diff --git a/glom/libglom/connectionpool.cc b/glom/libglom/connectionpool.cc
index 7455639..f0f5916 100644
--- a/glom/libglom/connectionpool.cc
+++ b/glom/libglom/connectionpool.cc
@@ -640,7 +640,7 @@ bool ConnectionPool::startup(const SlotProgress& slot_progress, bool network_sha
//If we crash while running (unlikely, hopefully), then try to cleanup.
//Comment this out if you want to see the backtrace in a debugger.
- previous_sig_handler = signal(SIGSEGV, &on_linux_signal);
+ //previous_sig_handler = signal(SIGSEGV, &on_linux_signal);
return true;
}
diff --git a/glom/libglom/data_structure/field.cc b/glom/libglom/data_structure/field.cc
index 3f0cefc..e983af0 100644
--- a/glom/libglom/data_structure/field.cc
+++ b/glom/libglom/data_structure/field.cc
@@ -158,7 +158,7 @@ void Field::set_field_info(const Glib::RefPtr<Gnome::Gda::Column>& fieldinfo)
}
}
- if(cur_type == G_TYPE_NONE)
+ if( (cur_type == G_TYPE_NONE) && (fieldinfo->get_g_type() != G_TYPE_NONE) )
set_glom_type( get_glom_type_for_gda_type(fieldinfo->get_g_type()) );
Gnome::Gda::Value value = get_default_value();
@@ -529,7 +529,13 @@ Glib::RefPtr<Gnome::Gda::Holder> Field::get_holder(const Gnome::Gda::Value& valu
Glib::ustring Field::get_gda_holder_string(const Glib::ustring& name) const
{
const Glib::ustring real_name = name.empty() ? get_name() : name;
- return "##" + real_name + "::" + get_gda_type_name();
+ return get_gda_holder_string_generic(real_name, m_field_info->get_g_type());
+}
+
+Glib::ustring Field::get_gda_holder_string_generic(const Glib::ustring& name, GType type)
+{
+ //This is the libgda syntax for SQL placeholder values:
+ return "##" + name + "::" + g_type_name(type);
}
/// Ignores any part of FieldAttributes that libgda does not properly fill.
diff --git a/glom/libglom/data_structure/field.h b/glom/libglom/data_structure/field.h
index 21af625..b1ef2fa 100644
--- a/glom/libglom/data_structure/field.h
+++ b/glom/libglom/data_structure/field.h
@@ -165,6 +165,11 @@ public:
*/
Glib::ustring get_gda_holder_string(const Glib::ustring& name = Glib::ustring()) const;
+ /** TODO: Documentation.
+ */
+ static Glib::ustring get_gda_holder_string_generic(const Glib::ustring& name, GType type);
+
+
/** Escape and quote the value so that it can be used in a SQL command.
*/
Glib::ustring sql(const Gnome::Gda::Value& value, const Glib::RefPtr<Gnome::Gda::Connection>& connection) const;
diff --git a/glom/libglom/standard_table_prefs_fields.h b/glom/libglom/standard_table_prefs_fields.h
index 82f67bf..9d96420 100644
--- a/glom/libglom/standard_table_prefs_fields.h
+++ b/glom/libglom/standard_table_prefs_fields.h
@@ -46,6 +46,13 @@ namespace Glom
#define GLOM_STANDARD_FIELD_LOCK "glom_lock" //Text. In every table. Not used yet.
+#define GLOM_STANDARD_DEFAULT_FIELD_CREATION_DATE "creation_date" //Date. In every table. Not used yet.
+#define GLOM_STANDARD_DEFAULT_FIELD_CREATION_TIME "creation_time" //Time. In every table. Not used yet.
+#define GLOM_STANDARD_DEFAULT_FIELD_CREATION_USER "creation_user" //Text. In every table. Not used yet.
+#define GLOM_STANDARD_DEFAULT_FIELD_MODIFICATION_DATE "modification_date" //Text. In every table. Not used yet.
+#define GLOM_STANDARD_DEFAULT_FIELD_MODIFICATION_TIME "modification_time" //Time. In every table. Not used yet.
+#define GLOM_STANDARD_DEFAULT_FIELD_MODIFICATION_USER "modification_user" //Text. In every table. Not used yet.
+
} //namespace Glom
#endif //GLOM_STANDARD_TABLE_PREFS_FIELDS_H
diff --git a/glom/libglom/utils.cc b/glom/libglom/utils.cc
index 6ec0f6a..776e7b6 100644
--- a/glom/libglom/utils.cc
+++ b/glom/libglom/utils.cc
@@ -799,5 +799,26 @@ bool Utils::file_exists(const Glib::ustring& uri)
}
}
+Gnome::Gda::Value Utils::get_current_time_utc_as_value()
+{
+ time_t t = time(0); //Gets the current unix time.
+ tm the_c_time = {0, };
+ gmtime_r(&t, &the_c_time); //gmtime_r gets the UTC time. (UTC-like),
+
+ Gnome::Gda::Time gda_time = {0, 0, 0, 0, 0};
+ gda_time.hour = the_c_time.tm_hour;
+ gda_time.minute = the_c_time.tm_min;
+ gda_time.second = the_c_time.tm_sec;
+ return Gnome::Gda::Value(gda_time);
+}
+
+Gnome::Gda::Value Utils::get_current_date_utc_as_value()
+{
+ Glib::TimeVal now;
+ now.assign_current_time(); //This is current unix time (UTC-like), I think.
+ Glib::Date date_now;
+ date_now.set_time(now);
+ return Gnome::Gda::Value(date_now);
+}
} //namespace Glom
diff --git a/glom/libglom/utils.h b/glom/libglom/utils.h
index 9c83e41..84961f9 100644
--- a/glom/libglom/utils.h
+++ b/glom/libglom/utils.h
@@ -90,6 +90,9 @@ Glib::ustring string_remove_suffix(const Glib::ustring& str, const Glib::ustring
bool file_exists(const Glib::ustring& uri);
+Gnome::Gda::Value get_current_date_utc_as_value();
+Gnome::Gda::Value get_current_time_utc_as_value();
+
} //namespace Utils
} //namespace Glom
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]