Commit cd91632e authored by Murray Cumming's avatar Murray Cumming
Browse files

utils: Move some functions into sql_utils.

parent 18fdb0a4
......@@ -254,6 +254,8 @@ set(SOURCE_FILES
glom/libglom/translations_po.h
glom/libglom/file_utils.cc
glom/libglom/file_utils.h
glom/libglom/sql_utils.cc
glom/libglom/sql_utils.h
glom/libglom/string_utils.cc
glom/libglom/string_utils.h
glom/libglom/utils.cc
......
......@@ -27,6 +27,7 @@
#include <libglom/document/document.h>
#include <libglom/data_structure/glomconversions.h>
#include <libglom/utils.h>
#include <libglom/sql_utils.h>
#include <glom/mode_design/layout/dialog_choose_field.h>
//#ifndef GLOM_ENABLE_CLIENT_ONLY
......
......@@ -25,6 +25,7 @@
#include <glom/python_embed/glom_python.h>
#include <glom/utils_ui.h>
#include <libglom/db_utils.h>
#include <libglom/sql_utils.h>
#include <libglom/utils.h>
#include <sstream>
#include <iostream>
......
......@@ -28,7 +28,7 @@
#include <libglom/appstate.h>
#include <libglom/db_utils_export.h>
#include <libglom/string_utils.h>
#include <libglom/sql_utils.h>
#include <libglom/connectionpool.h>
#ifdef GLOM_ENABLE_POSTGRESQL
......
......@@ -20,6 +20,7 @@
#include <libglom/algorithms_utils.h>
#include <libglom/db_utils.h>
#include <libglom/sql_utils.h>
#include <libglom/connectionpool.h>
#include <libglom/data_structure/glomconversions.h>
#include <libglom/connectionpool_backends/postgres_central.h>
......@@ -2373,6 +2374,133 @@ type_map_fields get_record_field_values(const std::shared_ptr<const Document>& d
return field_values;
}
type_list_values_with_second get_choice_values_all(const std::shared_ptr<const Document>& document, const std::shared_ptr<const LayoutItem_Field>& field)
{
return get_choice_values(document, field,
Gnome::Gda::Value() /* means get all with no WHERE clause */);
}
type_list_values_with_second get_choice_values(const std::shared_ptr<const Document>& document, const std::shared_ptr<const LayoutItem_Field>& field, const Gnome::Gda::Value& foreign_key_value)
{
//TODO: Reduce duplication between this and get_choice_values(field).
type_list_values_with_second result;
//We allows this, so this method can be used to get all records in a related table:
/*
if(Conversions::value_is_empty(foreign_key_value))
{
std::cout << G_STRFUNC << "debug: foreign_key_value is empty.\n";
return result;
}
*/
const Formatting& format = field->get_formatting_used();
std::shared_ptr<const Relationship> choice_relationship;
std::shared_ptr<const LayoutItem_Field> layout_choice_first;
std::shared_ptr<const LayoutGroup> layout_choice_extra;
Formatting::type_list_sort_fields choice_sort_fields;
bool choice_show_all = false;
format.get_choices_related(choice_relationship, layout_choice_first, layout_choice_extra, choice_sort_fields, choice_show_all);
if(!choice_relationship)
{
std::cerr << G_STRFUNC << ": !choice_relationship.\n";
return result;
}
Utils::type_vecConstLayoutFields fields;
fields.emplace_back(layout_choice_first);
if(layout_choice_extra)
{
for(const auto& item : layout_choice_extra->get_items_recursive())
{
const auto& item_field = std::dynamic_pointer_cast<const LayoutItem_Field>(item);
if(item_field)
fields.emplace_back(item_field); //TODO: Don't ignore other usable items such as static text.
}
}
const Glib::ustring to_table = choice_relationship->get_to_table();
const auto to_field = document->get_field(to_table, choice_relationship->get_to_field());
if(!to_field)
{
std::cerr << G_STRFUNC << ": to_field is null.\n";
}
//Default to some sort order rather than none:
if(choice_sort_fields.empty())
{
choice_sort_fields.emplace_back( Formatting::type_pair_sort_field(layout_choice_first, true /* ascending */));
}
//TODO: Support related relationships (in the UI too):
auto builder = Utils::build_sql_select_with_key(
to_table,
fields,
to_field,
foreign_key_value,
choice_sort_fields);
if(!builder)
{
std::cerr << G_STRFUNC << ": builder is null.\n";
return result;
}
//TODO: builder->select_order_by(choice_field_id);
//Connect to database and get the related values:
auto connection = ConnectionPool::get_instance()->connect();
if(!connection)
{
std::cerr << G_STRFUNC << ": connection is null.\n";
return result;
}
const std::string sql_query =
Utils::sqlbuilder_get_full_query(builder);
//std::cout << "debug: sql_query=" << sql_query << std::endl;
auto datamodel = connection->get_gda_connection()->statement_execute_select(sql_query);
if(datamodel)
{
const guint count = datamodel->get_n_rows();
const guint cols_count = datamodel->get_n_columns();
for(guint row = 0; row < count; ++row)
{
std::pair<Gnome::Gda::Value, type_list_values> itempair;
itempair.first = datamodel->get_value_at(0, row);
if(layout_choice_extra && (cols_count > 1))
{
type_list_values list_values;
for(guint i = 1; i < cols_count; ++i)
{
list_values.emplace_back(datamodel->get_value_at(i, row));
}
itempair.second = list_values;
}
result.emplace_back(itempair);
}
}
else
{
std::cerr << G_STRFUNC << ": Error while executing SQL\n" <<
" " << sql_query << std::endl;
return result;
}
return result;
}
} //namespace DbUtils
} //namespace Glom
......@@ -228,6 +228,12 @@ type_map_fields get_record_field_values(const std::shared_ptr<const Document>& d
*/
void set_fake_connection();
typedef std::vector<Gnome::Gda::Value> type_list_values;
typedef std::vector< std::pair<Gnome::Gda::Value, type_list_values> > type_list_values_with_second; //TODO: Rename this now that we have more than just 1 extra field.
type_list_values_with_second get_choice_values_all(const std::shared_ptr<const Document>& document, const std::shared_ptr<const LayoutItem_Field>& field);
type_list_values_with_second get_choice_values(const std::shared_ptr<const Document>& document, const std::shared_ptr<const LayoutItem_Field>& field, const Gnome::Gda::Value& foreign_key_value);
} //namespace DbUtils
} //namespace Glom
......
......@@ -22,6 +22,7 @@
#include <libglom/db_utils_export.h>
#include <libglom/db_utils.h>
#include <libglom/utils.h>
#include <libglom/sql_utils.h>
#include <libglom/algorithms_utils.h>
#include <libgdamm/metastore.h>
#include <iostream>
......
......@@ -27,6 +27,7 @@ libglom_toplevel_headers = \
glom/libglom/utils.h \
glom/libglom/db_utils.h \
glom/libglom/db_utils_export.h \
glom/libglom/sql_utils.h \
glom/libglom/report_builder.h \
glom/libglom/translations_po.h
......@@ -123,6 +124,8 @@ libglom_sources = \
glom/libglom/string_utils.h \
glom/libglom/translations_po.cc \
glom/libglom/translations_po.h \
glom/libglom/sql_utils.cc \
glom/libglom/sql_utils.h \
glom/libglom/utils.cc \
glom/libglom/utils.h \
glom/libglom/xsl_utils.cc \
......
......@@ -23,6 +23,7 @@
#include <libglom/data_structure/glomconversions.h>
#include <libglom/db_utils.h>
#include <libglom/file_utils.h>
#include <libglom/sql_utils.h>
#include <libglom/xsl_utils.h>
#include <libglom/xml_utils.h>
#include <iostream>
......
This diff is collapsed.
/* Glom
*
* Copyright (C) 2001-2016 Murray Cumming
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*/
#ifndef GLOM_SQL_UTILS_H
#define GLOM_SQL_UTILS_H
#include <libglom/document/document.h>
#include <libglom/data_structure/layout/layoutitem_field.h>
#include <libgdamm/sqlbuilder.h>
#include <libgdamm/sqlexpr.h>
namespace Glom
{
///field, ascending
typedef std::pair< std::shared_ptr<const LayoutItem_Field>, bool> type_pair_sort_field;
typedef std::vector<type_pair_sort_field> type_sort_clause;
namespace Utils
{
typedef std::vector< std::shared_ptr<const LayoutItem_Field> > type_vecConstLayoutFields;
//typedef Base_DB::type_vecLayoutFields type_vecLayoutFields;
typedef std::vector< std::shared_ptr<LayoutItem_Field> > type_vecLayoutFields;
// Create a Gnome::Gda::SqlExpr.
Gnome::Gda::SqlExpr build_simple_where_expression(const Glib::ustring& table_name, const std::shared_ptr<const Field>& key_field, const Gnome::Gda::Value& key_value);
// Create a where clause that is two other conditions combined together.
Gnome::Gda::SqlExpr build_combined_where_expression(const Gnome::Gda::SqlExpr& a, const Gnome::Gda::SqlExpr& b, Gnome::Gda::SqlOperatorType op);
/** Generate a SQL statement to SELECT field values,
* even if the fields are in related (or doubly related) records.
*/
void build_sql_select_add_fields_to_get(
const Glib::RefPtr<Gnome::Gda::SqlBuilder>& builder,
const Glib::ustring& table_name,
const type_vecConstLayoutFields& fieldsToGet,
const type_sort_clause& sort_clause,
bool extra_join);
/** Generate a SQL statement to SELECT field values,
* even if the fields are in related (or doubly related) records,
* narrowing the records down with a WHERE clause.
*/
Glib::RefPtr<Gnome::Gda::SqlBuilder> build_sql_select_with_where_clause(
const Glib::ustring& table_name,
const type_vecLayoutFields& fieldsToGet,
const Gnome::Gda::SqlExpr& where_clause = Gnome::Gda::SqlExpr(),
const std::shared_ptr<const Relationship>& extra_join = std::shared_ptr<const Relationship>(),
const type_sort_clause& sort_clause = type_sort_clause(),
guint limit = 0);
/** Just a version of build_sql_select_with_where_clause() that takes a list of const fields.
*/
Glib::RefPtr<Gnome::Gda::SqlBuilder> build_sql_select_with_where_clause(
const Glib::ustring& table_name,
const type_vecConstLayoutFields& fieldsToGet,
const Gnome::Gda::SqlExpr& where_clause = Gnome::Gda::SqlExpr(),
const std::shared_ptr<const Relationship>& extra_join = std::shared_ptr<const Relationship>(),
const type_sort_clause& sort_clause = type_sort_clause(),
guint limit = 0);
/**
* @param key_value If this is empty then all records in the tables will be retrieved.
*/
Glib::RefPtr<Gnome::Gda::SqlBuilder> build_sql_select_with_key(
const Glib::ustring& table_name,
const type_vecLayoutFields& fieldsToGet,
const std::shared_ptr<const Field>& key_field,
const Gnome::Gda::Value& key_value,
const type_sort_clause& sort_clause = type_sort_clause(),
guint limit = 0);
/** Just a version of build_sql_select_with_key() that takes a list of const fields.
*/
Glib::RefPtr<Gnome::Gda::SqlBuilder> build_sql_select_with_key(
const Glib::ustring& table_name,
const type_vecConstLayoutFields& fieldsToGet,
const std::shared_ptr<const Field>& key_field,
const Gnome::Gda::Value& key_value,
const type_sort_clause& sort_clause = type_sort_clause(),
guint limit = 0);
//Note: This is not used by glom itself, but it is used by java-libglom.
/** Build a SQL query to discover how many rows a SQL query would return if it was run.
*
* This uses a COUNT * on a the @a sql_query as a sub-statement.
* Be careful not to include ORDER BY clauses in the supplied SQL query, because that would make it unnecessarily slow.
*
* @param sql_query A SQL query.
* @result The number of rows.
*/
Glib::RefPtr<Gnome::Gda::SqlBuilder> build_sql_select_count_rows(const Glib::RefPtr<const Gnome::Gda::SqlBuilder>& sql_query);
Gnome::Gda::SqlExpr get_find_where_clause_quick(const std::shared_ptr<const Document>& document, const Glib::ustring& table_name, const Gnome::Gda::Value& quick_search);
/** Generate a SQL statement to UPDATE field values,
*/
Glib::RefPtr<Gnome::Gda::SqlBuilder> build_sql_update_with_where_clause(
const Glib::ustring& table_name,
const std::shared_ptr<const Field>& field, const Gnome::Gda::Value& value,
const Gnome::Gda::SqlExpr& where_clause);
/// Get the full query string suitable for use with std::cout.
std::string sqlbuilder_get_full_query(
const Glib::RefPtr<const Gnome::Gda::SqlBuilder>& builder);
} //namespace Utils
} //namespace Glom
#endif //GLOM_SQL_UTILS_H
This diff is collapsed.
......@@ -27,114 +27,17 @@
#include <libglom/data_structure/layout/layoutitem_field.h>
#include <libglom/algorithms_utils.h>
#include <libgdamm/sqlexpr.h>
#include <giomm/file.h>
namespace Glom
{
///field, ascending
typedef std::pair< std::shared_ptr<const LayoutItem_Field>, bool> type_pair_sort_field;
typedef std::vector<type_pair_sort_field> type_sort_clause;
namespace Utils
{
//typedef Base_DB::type_vecLayoutFields type_vecLayoutFields;
typedef std::vector< std::shared_ptr<LayoutItem_Field> > type_vecLayoutFields;
typedef std::vector< std::shared_ptr<const LayoutItem_Field> > type_vecConstLayoutFields;
typedef std::vector< std::shared_ptr<Field> > type_vec_fields;
//TODO: Move these to their own file:
// Create a Gnome::Gda::SqlExpr.
Gnome::Gda::SqlExpr build_simple_where_expression(const Glib::ustring& table_name, const std::shared_ptr<const Field>& key_field, const Gnome::Gda::Value& key_value);
// Create a where clause that is two other conditions combined together.
Gnome::Gda::SqlExpr build_combined_where_expression(const Gnome::Gda::SqlExpr& a, const Gnome::Gda::SqlExpr& b, Gnome::Gda::SqlOperatorType op);
/** Generate a SQL statement to SELECT field values,
* even if the fields are in related (or doubly related) records.
*/
void build_sql_select_add_fields_to_get(
const Glib::RefPtr<Gnome::Gda::SqlBuilder>& builder,
const Glib::ustring& table_name,
const type_vecConstLayoutFields& fieldsToGet,
const type_sort_clause& sort_clause,
bool extra_join);
/** Generate a SQL statement to SELECT field values,
* even if the fields are in related (or doubly related) records,
* narrowing the records down with a WHERE clause.
*/
Glib::RefPtr<Gnome::Gda::SqlBuilder> build_sql_select_with_where_clause(
const Glib::ustring& table_name,
const type_vecLayoutFields& fieldsToGet,
const Gnome::Gda::SqlExpr& where_clause = Gnome::Gda::SqlExpr(),
const std::shared_ptr<const Relationship>& extra_join = std::shared_ptr<const Relationship>(),
const type_sort_clause& sort_clause = type_sort_clause(),
guint limit = 0);
/** Just a version of build_sql_select_with_where_clause() that takes a list of const fields.
*/
Glib::RefPtr<Gnome::Gda::SqlBuilder> build_sql_select_with_where_clause(
const Glib::ustring& table_name,
const type_vecConstLayoutFields& fieldsToGet,
const Gnome::Gda::SqlExpr& where_clause = Gnome::Gda::SqlExpr(),
const std::shared_ptr<const Relationship>& extra_join = std::shared_ptr<const Relationship>(),
const type_sort_clause& sort_clause = type_sort_clause(),
guint limit = 0);
/**
* @param key_value If this is empty then all records in the tables will be retrieved.
*/
Glib::RefPtr<Gnome::Gda::SqlBuilder> build_sql_select_with_key(
const Glib::ustring& table_name,
const type_vecLayoutFields& fieldsToGet,
const std::shared_ptr<const Field>& key_field,
const Gnome::Gda::Value& key_value,
const type_sort_clause& sort_clause = type_sort_clause(),
guint limit = 0);
/** Just a version of build_sql_select_with_key() that takes a list of const fields.
*/
Glib::RefPtr<Gnome::Gda::SqlBuilder> build_sql_select_with_key(
const Glib::ustring& table_name,
const type_vecConstLayoutFields& fieldsToGet,
const std::shared_ptr<const Field>& key_field,
const Gnome::Gda::Value& key_value,
const type_sort_clause& sort_clause = type_sort_clause(),
guint limit = 0);
//Note: This is not used by glom itself, but it is used by java-libglom.
/** Build a SQL query to discover how many rows a SQL query would return if it was run.
*
* This uses a COUNT * on a the @a sql_query as a sub-statement.
* Be careful not to include ORDER BY clauses in the supplied SQL query, because that would make it unnecessarily slow.
*
* @param sql_query A SQL query.
* @result The number of rows.
*/
Glib::RefPtr<Gnome::Gda::SqlBuilder> build_sql_select_count_rows(const Glib::RefPtr<const Gnome::Gda::SqlBuilder>& sql_query);
Gnome::Gda::SqlExpr get_find_where_clause_quick(const std::shared_ptr<const Document>& document, const Glib::ustring& table_name, const Gnome::Gda::Value& quick_search);
/** Generate a SQL statement to UPDATE field values,
*/
Glib::RefPtr<Gnome::Gda::SqlBuilder> build_sql_update_with_where_clause(
const Glib::ustring& table_name,
const std::shared_ptr<const Field>& field, const Gnome::Gda::Value& value,
const Gnome::Gda::SqlExpr& where_clause);
typedef std::vector<Gnome::Gda::Value> type_list_values;
typedef std::vector< std::pair<Gnome::Gda::Value, type_list_values> > type_list_values_with_second; //TODO: Rename this now that we have more than just 1 extra field.
type_list_values_with_second get_choice_values_all(const std::shared_ptr<const Document>& document, const std::shared_ptr<const LayoutItem_Field>& field);
type_list_values_with_second get_choice_values(const std::shared_ptr<const Document>& document, const std::shared_ptr<const LayoutItem_Field>& field, const Gnome::Gda::Value& foreign_key_value);
/// Get the full query string suitable for use with std::cout.
std::string sqlbuilder_get_full_query(
const Glib::RefPtr<const Gnome::Gda::SqlBuilder>& builder);
/** Get just the first part of a locale, such as de_DE,
* ignoring, for instance, .UTF-8 or \@euro at the end.
......
......@@ -31,10 +31,6 @@
namespace Glom
{
///field, ascending
typedef std::pair< std::shared_ptr<const LayoutItem_Field>, bool> type_pair_sort_field;
typedef std::vector<type_pair_sort_field> type_sort_clause;
namespace GlomXslUtils
{
......
......@@ -23,8 +23,9 @@
#include <glom/utils_ui.h>
#include <glom/appwindow.h>
#include <libglom/data_structure/glomconversions.h>
#include <libglom/utils.h>
#include <libglom/sql_utils.h>
#include <libglom/db_utils.h>
#include <libglom/utils.h>
#include <glom/frame_glom.h> //For show_ok_dialog()
#include <glom/glade_utils.h>
#include <giomm/menu.h>
......
......@@ -26,6 +26,7 @@
#include <libglom/data_structure/relationship.h>
#include <libglom/data_structure/glomconversions.h>
#include <libglom/db_utils.h>
#include <libglom/sql_utils.h>
#include <libglom/utils.h>
#include <glom/mode_design/layout/dialog_layout_details.h>
#include <glom/glade_utils.h>
......
......@@ -21,6 +21,7 @@
#include <glom/mode_data/box_data_portal.h>
#include <libglom/data_structure/glomconversions.h>
#include <libglom/db_utils.h>
#include <libglom/sql_utils.h>
#include <libglom/utils.h>
#include <glom/glade_utils.h>
#include <glom/frame_glom.h> //For show_ok_dialog()
......
......@@ -24,7 +24,7 @@
#include <glom/dialog_invalid_data.h>
#include <libglom/data_structure/glomconversions.h>
#include <glom/appwindow.h>
#include <libglom/utils.h>
#include <libglom/db_utils.h>
#include <glibmm/i18n.h>
//#include <sstream> //For stringstream
......@@ -148,8 +148,8 @@ void ComboAsRadioButtons::set_choices_fixed(const Formatting::type_list_values&
void ComboAsRadioButtons::set_choices_related(const std::shared_ptr<const Document>& document, const std::shared_ptr<const LayoutItem_Field>& layout_field, const Gnome::Gda::Value& foreign_key_value)
{
const Utils::type_list_values_with_second list_values =
Utils::get_choice_values(document, layout_field, foreign_key_value);
const auto list_values =
DbUtils::get_choice_values(document, layout_field, foreign_key_value);
set_choices_with_second(list_values);
}
......
......@@ -22,6 +22,7 @@
#include <glom/mode_data/datawidget/treemodel_db_withextratext.h>
#include <libglom/data_structure/glomconversions.h>
#include <libglom/privs.h>
#include <libglom/sql_utils.h>
#include <libglom/utils.h>
#include <glom/utils_ui.h>
#include <glom/appwindow.h>
......
......@@ -21,7 +21,7 @@
#include "dialog_choose_id.h"
#include <glom/utils_ui.h> //For bold_message()).
#include <glom/appwindow.h>
#include <libglom/utils.h>
#include <libglom/sql_utils.h>
//#include <libgnome/gnome-i18n.h>
#include <glibmm/i18n.h>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment