65
FoundSet::FoundSet(const FoundSet& src)
66
: m_table_name(src.m_table_name),
67
m_extra_join(src.m_extra_join),
68
m_where_clause(src.m_where_clause),
69
m_extra_group_by(src.m_extra_group_by),
70
m_sort_clause(src.m_sort_clause)
74
FoundSet& FoundSet::operator=(const FoundSet& src)
76
m_table_name = src.m_table_name;
77
m_extra_join = src.m_extra_join;
78
m_where_clause = src.m_where_clause;
79
m_extra_group_by = src.m_extra_group_by;
80
m_sort_clause = src.m_sort_clause;
85
bool FoundSet::operator==(const FoundSet& src) const
87
return (m_table_name == src.m_table_name)
88
&& (m_extra_join == src.m_extra_join)
89
&& (m_where_clause == src.m_where_clause)
90
&& (m_extra_group_by == src.m_extra_group_by)
91
&& (m_sort_clause == src.m_sort_clause);
96
63
template<class T_Element>
97
64
class predicate_LayoutItemIsEqual
249
207
if(strQuery.compare(0, 6, "SELECT") == 0)
251
209
#ifdef GLIBMM_EXCEPTIONS_ENABLED
252
result = gda_connection->execute_select_command(strQuery);
212
result = gda_connection->execute_select_command(strQuery);
214
catch(const Gnome::Gda::ConnectionError& ex)
216
std::cout << "debug: Base_DB::query_execute(): exception from execute_select_command(): " << ex.what() << std::endl;
254
219
std::auto_ptr<Glib::Error> error;
255
220
result = gda_connection->execute_select_command(strQuery, error);
256
221
// Ignore error, empty datamodel is handled below
222
#endif //GLIBMM_EXCEPTIONS_ENABLED
261
std::auto_ptr<Glib::Error> error;
262
227
#ifdef GLIBMM_EXCEPTIONS_ENABLED
263
if(gda_connection->execute_non_select_command(strQuery) != -1)
228
int execute_result = -1;
231
execute_result = gda_connection->execute_non_select_command(strQuery);
233
catch(const Gnome::Gda::ConnectionError& ex)
235
std::cout << "debug: Base_DB::query_execute(): exception from execute_non_select_command(): " << ex.what() << std::endl;
265
if(gda_connection->execute_non_select_command(strQuery, error) != -1)
266
if(error.get() == NULL)
268
result = Gnome::Gda::DataModelArray::create(1);
238
std::auto_ptr<Glib::Error> error;
239
execute_result = gda_connection->execute_non_select_command(strQuery, error);
240
#endif //GLIBMM_EXCEPTIONS_ENABLED
242
if(execute_result != -1)
243
result = Gnome::Gda::DataModelArray::create(1);
949
923
+ Glib::ustring(optional_org_logo ? ", \"" GLOM_STANDARD_TABLE_PREFS_TABLE_NAME "\".\"" GLOM_STANDARD_TABLE_PREFS_FIELD_ORG_LOGO "\"" : "") +
950
924
" FROM \"" GLOM_STANDARD_TABLE_PREFS_TABLE_NAME "\"";
952
#ifdef GLIBMM_EXCEPTIONS_ENABLED
956
Glib::RefPtr<Gnome::Gda::DataModel> datamodel = query_execute(sql_query);
957
if(datamodel && (datamodel->get_n_rows() != 0))
959
result.m_name = Conversions::get_text_for_gda_value(Field::TYPE_TEXT, datamodel->get_value_at(0, 0));
960
result.m_org_name = Conversions::get_text_for_gda_value(Field::TYPE_TEXT, datamodel->get_value_at(1, 0));
961
result.m_org_address_street = Conversions::get_text_for_gda_value(Field::TYPE_TEXT, datamodel->get_value_at(2, 0));
962
result.m_org_address_street2 = Conversions::get_text_for_gda_value(Field::TYPE_TEXT, datamodel->get_value_at(3, 0));
963
result.m_org_address_town = Conversions::get_text_for_gda_value(Field::TYPE_TEXT, datamodel->get_value_at(4, 0));
964
result.m_org_address_county = Conversions::get_text_for_gda_value(Field::TYPE_TEXT, datamodel->get_value_at(5, 0));
965
result.m_org_address_country = Conversions::get_text_for_gda_value(Field::TYPE_TEXT, datamodel->get_value_at(6, 0));
966
result.m_org_address_postcode = Conversions::get_text_for_gda_value(Field::TYPE_TEXT, datamodel->get_value_at(7, 0));
968
//We need to be more clever about these column indexes if we add more new fields:
969
if(optional_org_logo)
970
result.m_org_logo = datamodel->get_value_at(8, 0);
974
#ifdef GLIBMM_EXCEPTIONS_ENABLED
975
catch(const Glib::Exception& ex)
977
std::cerr << "Base_DB::get_database_preferences(): exception: " << ex.what() << std::endl;
979
catch(const std::exception& ex)
981
std::cerr << "Base_DB::get_database_preferences(): exception: " << ex.what() << std::endl;
983
#endif // GLIBMM_EXCEPTIONS_ENABLED
929
bool succeeded = true;
930
#ifdef GLIBMM_EXCEPTIONS_ENABLED
934
Glib::RefPtr<Gnome::Gda::DataModel> datamodel = query_execute(sql_query);
935
if(datamodel && (datamodel->get_n_rows() != 0))
937
result.m_name = Conversions::get_text_for_gda_value(Field::TYPE_TEXT, datamodel->get_value_at(0, 0));
938
result.m_org_name = Conversions::get_text_for_gda_value(Field::TYPE_TEXT, datamodel->get_value_at(1, 0));
939
result.m_org_address_street = Conversions::get_text_for_gda_value(Field::TYPE_TEXT, datamodel->get_value_at(2, 0));
940
result.m_org_address_street2 = Conversions::get_text_for_gda_value(Field::TYPE_TEXT, datamodel->get_value_at(3, 0));
941
result.m_org_address_town = Conversions::get_text_for_gda_value(Field::TYPE_TEXT, datamodel->get_value_at(4, 0));
942
result.m_org_address_county = Conversions::get_text_for_gda_value(Field::TYPE_TEXT, datamodel->get_value_at(5, 0));
943
result.m_org_address_country = Conversions::get_text_for_gda_value(Field::TYPE_TEXT, datamodel->get_value_at(6, 0));
944
result.m_org_address_postcode = Conversions::get_text_for_gda_value(Field::TYPE_TEXT, datamodel->get_value_at(7, 0));
946
//We need to be more clever about these column indexes if we add more new fields:
947
if(optional_org_logo)
948
result.m_org_logo = datamodel->get_value_at(8, 0);
953
#ifdef GLIBMM_EXCEPTIONS_ENABLED
954
catch(const Glib::Exception& ex)
956
std::cerr << "Base_DB::get_database_preferences(): exception: " << ex.what() << std::endl;
959
catch(const std::exception& ex)
961
std::cerr << "Base_DB::get_database_preferences(): exception: " << ex.what() << std::endl;
964
#endif // GLIBMM_EXCEPTIONS_ENABLED
966
//Return the result, or try again:
971
add_standard_tables();
972
++attempts; //Try again now that we have tried to create the table.
1389
sharedptr<LayoutItem_Text> Base_DB::offer_textobject(const sharedptr<LayoutItem_Text>& start_textobject, Gtk::Window* transient_for)
1384
sharedptr<LayoutItem_Text> Base_DB::offer_textobject(const sharedptr<LayoutItem_Text>& start_textobject, Gtk::Window* transient_for, bool show_title)
1391
sharedptr<LayoutItem_Text> result;
1386
sharedptr<LayoutItem_Text> result = start_textobject;
1395
Glib::RefPtr<Gnome::Glade::Xml> refXml = Gnome::Glade::Xml::create(GLOM_GLADEDIR "glom.glade", "window_textobject");
1390
Glib::RefPtr<Gnome::Glade::Xml> refXml = Gnome::Glade::Xml::create(Utils::get_glade_file_path("glom_developer.glade"), "window_textobject");
1397
1392
Dialog_TextObject* dialog = 0;
1398
1393
refXml->get_widget_derived("window_textobject", dialog);
1424
sharedptr<LayoutItem_Image> Base_DB::offer_imageobject(const sharedptr<LayoutItem_Image>& start_imageobject, Gtk::Window* transient_for)
1419
sharedptr<LayoutItem_Image> Base_DB::offer_imageobject(const sharedptr<LayoutItem_Image>& start_imageobject, Gtk::Window* transient_for, bool show_title)
1426
sharedptr<LayoutItem_Image> result;
1421
sharedptr<LayoutItem_Image> result = start_imageobject;
1430
Glib::RefPtr<Gnome::Glade::Xml> refXml = Gnome::Glade::Xml::create(GLOM_GLADEDIR "glom.glade", "window_imageobject");
1425
Glib::RefPtr<Gnome::Glade::Xml> refXml = Gnome::Glade::Xml::create(Utils::get_glade_file_path("glom_developer.glade"), "window_imageobject");
1432
1427
Dialog_ImageObject* dialog = 0;
1433
1428
refXml->get_widget_derived("window_imageobject", dialog);
1654
1649
//g_warning("Box_Data::get_table_fields_to_show_for_sequence_add_group(): table_name=%s, all_db_fields.size()=%d, group->name=%s", table_name.c_str(), all_db_fields.size(), group->get_name().c_str());
1656
LayoutGroup::type_map_items items = group->get_items();
1657
for(LayoutGroup::type_map_items::iterator iterItems = items.begin(); iterItems != items.end(); ++iterItems)
1651
LayoutGroup::type_list_items items = group->get_items();
1652
for(LayoutGroup::type_list_items::iterator iterItems = items.begin(); iterItems != items.end(); ++iterItems)
1659
sharedptr<LayoutItem> item = iterItems->second;
1654
sharedptr<LayoutItem> item = *iterItems;
1661
1656
sharedptr<LayoutItem_Field> item_field = sharedptr<LayoutItem_Field>::cast_dynamic(item);
2171
2166
type_vecConstLayoutFields list_fields;
2172
2167
sharedptr<const LayoutItem_Field> layout_item = field_in_record.m_field;
2173
2168
list_fields.push_back(layout_item);
2174
const Glib::ustring sql_query = Utils::build_sql_select_with_key(field_in_record.m_table_name,
2169
Glib::ustring sql_query = Utils::build_sql_select_with_key(field_in_record.m_table_name,
2175
2170
list_fields, field_in_record.m_key, field_in_record.m_key_value);
2177
Glib::RefPtr<Gnome::Gda::DataModel> data_model = query_execute(sql_query);
2180
if(data_model->get_n_rows())
2182
result = data_model->get_value_at(0, 0);
2172
if(!sql_query.empty())
2173
sql_query += " LIMIT 1";
2175
Glib::RefPtr<Gnome::Gda::DataModel> data_model = query_execute(sql_query);
2178
if(data_model->get_n_rows())
2180
result = data_model->get_value_at(0, 0);
2191
Gnome::Gda::Value Base_DB::get_field_value_in_database(const sharedptr<Field>& field, const FoundSet& found_set, Gtk::Window* parent_window)
2193
Gnome::Gda::Value result; //TODO: Return suitable empty value for the field when failing?
2195
//row is invalid, and ignored, for Box_Data_Details.
2198
std::cerr << "Base_DB:gset_field_value_in_database(): field is empty." << std::endl;
2202
if(found_set.m_where_clause.empty())
2204
std::cerr << "Base_DB::get_field_value_in_database(): where_clause is empty." << std::endl;
2208
type_vecConstLayoutFields list_fields;
2209
sharedptr<LayoutItem_Field> layout_item = sharedptr<LayoutItem_Field>::create();
2210
layout_item->set_full_field_details(field);
2211
list_fields.push_back(layout_item);
2212
Glib::ustring sql_query = Utils::build_sql_select_with_where_clause(found_set.m_table_name,
2214
found_set.m_where_clause);
2216
if(!sql_query.empty())
2217
sql_query += " LIMIT 1";
2219
Glib::RefPtr<Gnome::Gda::DataModel> data_model = query_execute(sql_query);
2222
if(data_model->get_n_rows())
2224
result = data_model->get_value_at(0, 0);
2193
2236
void Base_DB::do_calculations(const LayoutFieldInRecord& field_changed, bool first_calc_field)
2567
2610
const Glib::ustring parent_table_name = portal->get_table_used(Glib::ustring() /* parent table - not relevant */);
2569
LayoutItem_Portal::type_map_const_items items = portal->get_items();
2570
for(LayoutItem_Portal::type_map_const_items::const_iterator iter = items.begin(); iter != items.end(); ++iter)
2612
LayoutItem_Portal::type_list_const_items items = portal->get_items();
2613
for(LayoutItem_Portal::type_list_const_items::const_iterator iter = items.begin(); iter != items.end(); ++iter)
2572
sharedptr<const LayoutItem_Field> field = sharedptr<const LayoutItem_Field>::cast_dynamic(iter->second);
2615
sharedptr<const LayoutItem_Field> field = sharedptr<const LayoutItem_Field>::cast_dynamic(*iter);
2573
2616
if(field && !(field->get_has_relationship_name()))
2575
2618
sharedptr<Relationship> relationship = document->get_field_used_in_relationship_to_one(parent_table_name, field->get_name());
2718
int Base_DB::count_rows_returned_by(const Glib::ustring& sql_query)
2722
//TODO: Is this inefficient?
2723
//Note that the alias is just because the SQL syntax requires it - we get an error if we don't use it.
2724
//Be careful not to include ORDER BY clauses in this, because that would make it unnecessarily slow:
2725
const Glib::ustring query_count = "SELECT COUNT (*) FROM (" + sql_query + ") AS glomarbitraryalias";
2727
const App_Glom* app = App_Glom::get_application();
2728
if(app && app->get_show_sql_debug())
2732
std::cout << "Debug: count_rows_returned_by(): " << query_count << std::endl;
2734
catch(const Glib::Exception& ex)
2736
std::cout << "Debug: query string could not be converted to std::cout: " << ex.what() << std::endl;
2740
#ifdef GLIBMM_EXCEPTIONS_ENABLED
2741
sharedptr<SharedConnection> sharedconnection = connect_to_server();
2743
std::auto_ptr<ExceptionConnection> error;
2744
sharedptr<SharedConnection> sharedconnection = connect_to_server(0, error);
2748
if(!sharedconnection)
2750
g_warning("Base_DB::count_rows_returned_by(): connection failed.");
2756
Glib::RefPtr<Gnome::Gda::DataModel> datamodel = sharedconnection->get_gda_connection()->execute_select_command(query_count);
2757
if(datamodel && datamodel->get_n_rows() && datamodel->get_n_columns())
2759
Gnome::Gda::Value value = datamodel->get_value_at(0, 0);
2760
//This showed me that this contains a gint64: std::cerr << "DEBUG: value type=" << G_VALUE_TYPE_NAME(value.gobj()) << std::endl;
2761
result = (int)value.get_int64();
2764
catch(const Glib::Exception& ex)
2766
std::cerr << "count_rows_returned_by(): exception caught: " << ex.what() << std::endl;
2768
catch(const std::exception& ex)
2770
std::cerr << "count_rows_returned_by(): exception caught: " << ex.what() << std::endl;
2773
//std::cout << "DEBUG: count_rows_returned_by(): Returning " << result << std::endl;
2778
void Base_DB::set_found_set_where_clause_for_portal(FoundSet& found_set, const sharedptr<LayoutItem_Portal>& portal, const Gnome::Gda::Value& foreign_key_value)
2780
found_set.m_table_name = Glib::ustring();
2781
found_set.m_where_clause = Glib::ustring();
2782
found_set.m_extra_join = Glib::ustring();
2783
found_set.m_extra_group_by = Glib::ustring();
2786
|| Conversions::value_is_empty(foreign_key_value) )
2792
sharedptr<Relationship> relationship = portal->get_relationship();
2794
// Notice that, in the case that this is a portal to doubly-related records,
2795
// The WHERE clause mentions the first-related table (though by the alias defined in extra_join)
2796
// and we add an extra JOIN to mention the second-related table.
2798
Glib::ustring where_clause_to_table_name = relationship->get_to_table();
2799
sharedptr<Field> where_clause_to_key_field = get_fields_for_table_one_field(relationship->get_to_table(), relationship->get_to_field());
2801
found_set.m_table_name = portal->get_table_used(Glib::ustring() /* parent table - not relevant */);
2803
sharedptr<const Relationship> relationship_related = portal->get_related_relationship();
2804
if(relationship_related)
2806
//Add the extra JOIN:
2807
sharedptr<UsesRelationship> uses_rel_temp = sharedptr<UsesRelationship>::create();
2808
uses_rel_temp->set_relationship(relationship);
2809
//found_set.m_extra_join = uses_rel_temp->get_sql_join_alias_definition();
2810
found_set.m_extra_join = "LEFT OUTER JOIN \"" + relationship->get_to_table() + "\" AS \"" + uses_rel_temp->get_sql_join_alias_name() + "\" ON (\"" + uses_rel_temp->get_sql_join_alias_name() + "\".\"" + relationship_related->get_from_field() + "\" = \"" + relationship_related->get_to_table() + "\".\"" + relationship_related->get_to_field() + "\")";
2812
//Add an extra GROUP BY to ensure that we get no repeated records from the doubly-related table:
2813
sharedptr<Field> to_table_primary_key = get_field_primary_key_for_table( relationship->get_to_table() );
2814
if(to_table_primary_key)
2815
found_set.m_extra_group_by = "GROUP BY \"" + found_set.m_table_name + "\".\"" + to_table_primary_key->get_name() + "\"";
2817
//Adjust the WHERE clause appropriately for the extra JOIN:
2818
where_clause_to_table_name = uses_rel_temp->get_sql_join_alias_name();
2820
const Glib::ustring to_field_name = uses_rel_temp->get_to_field_used();
2821
where_clause_to_key_field = get_fields_for_table_one_field(relationship->get_to_table(), to_field_name);
2822
//std::cout << "extra_join=" << found_set.m_extra_join << std::endl;
2824
//std::cout << "extra_join where_clause_to_key_field=" << where_clause_to_key_field->get_name() << std::endl;
2827
if(where_clause_to_key_field)
2828
found_set.m_where_clause = "\"" + where_clause_to_table_name + "\".\"" + relationship->get_to_field() + "\" = " + where_clause_to_key_field->sql(foreign_key_value);
2675
2832
} //namespace Glom