glom r1854 - in trunk: . glom glom/libglom/data_structure
- From: jhs svn gnome org
- To: svn-commits-list gnome org
- Subject: glom r1854 - in trunk: . glom glom/libglom/data_structure
- Date: Thu, 22 Jan 2009 09:18:15 +0000 (UTC)
Author: jhs
Date: Thu Jan 22 09:18:15 2009
New Revision: 1854
URL: http://svn.gnome.org/viewvc/glom?rev=1854&view=rev
Log:
2009-01-22 Johannes Schmid <jschmid openismus com>
* glom/base_db.cc (insert_example_data(), get_connection()):
* glom/base_db.h:
Fixed insertion of example data by using variables in the sql statement
instead of inserting the data directly in the statement (which confuses the
GdaSqlParser and is inefficient)
* glom/libglom/data_structure/field.cc (get_gda_type()):
* glom/libglom/data_structure/field.h:
Added a method to get the gda GType of the field. This is necessary to
prepare the sql statement so I would rather like to reuse get_sql_type().
Currntly investigating on gnome-db-list.
Modified:
trunk/ChangeLog
trunk/glom/base_db.cc
trunk/glom/base_db.h
trunk/glom/libglom/data_structure/field.cc
trunk/glom/libglom/data_structure/field.h
Modified: trunk/glom/base_db.cc
==============================================================================
--- trunk/glom/base_db.cc (original)
+++ trunk/glom/base_db.cc Thu Jan 22 09:18:15 2009
@@ -286,6 +286,11 @@
{
std::cout << "debug: Base_DB::query_execute(): ServerProviderError: exception from execute_non_select_command(): " << ex.what() << std::endl;
}
+ catch(const Gnome::Gda::SqlParserError& ex)
+ {
+ std::cout << "debug: Base_DB::query_execute(): SqlParserError:" << ex.what() << std::endl;
+ std::cout << "debug: query was: " << strQuery << std::endl;
+ }
#else
std::auto_ptr<Glib::Error> error;
execute_result = gda_connection->gda_connection->statement_execute_non_select(strQuery, error);
@@ -1435,6 +1440,29 @@
}
#endif
+Glib::RefPtr<Gnome::Gda::Connection> Base_DB::get_connection() const
+{
+#ifdef GLIBMM_EXCEPTIONS_ENABLED
+ sharedptr<SharedConnection> sharedconnection = connect_to_server();
+#else
+ std::auto_ptr<ExceptionConnection> error;
+ sharedptr<SharedConnection> sharedconnection = connect_to_server(0, error);
+ if(error.get())
+ {
+ g_warning("Base_DB::insert_example_data failed (query was: %s): %s", strQuery.c_str(), error->what());
+ // TODO: Rethrow?
+ }
+#endif
+ if(!sharedconnection)
+ {
+ std::cerr << "Base_DB::insert_example_data: No connection yet." << std::endl;
+ return Glib::RefPtr<Gnome::Gda::Connection>(0);
+ }
+ Glib::RefPtr<Gnome::Gda::Connection> gda_connection = sharedconnection->get_gda_connection();
+
+ return gda_connection;
+}
+
bool Base_DB::insert_example_data(const Glib::ustring& table_name) const
{
const Glib::ustring example_rows = get_document()->get_table_example_data(table_name);
@@ -1444,6 +1472,11 @@
return true;
}
+ Glib::RefPtr<Gnome::Gda::Connection> gda_connection = get_connection();
+ if (!gda_connection)
+ return false;
+
+
//std::cout << "debug: inserting example_rows for table: " << table_name << std::endl;
bool insert_succeeded = true;
@@ -1452,109 +1485,108 @@
//Get field names:
Document_Glom::type_vecFields vec_fields = get_document()->get_table_fields(table_name);
- Glib::ustring strNames;
- unsigned int fields_count = 0;
- for(Document_Glom::type_vecFields::const_iterator iter = vec_fields.begin(); iter != vec_fields.end(); ++iter)
- {
- //Append it:
- if(!strNames.empty())
- {
- strNames += ", ";
- ++fields_count;
- }
-
- strNames += "\"" + (*iter)->get_name() + "\"";
- }
-
- const ConnectionPool* connection_pool = ConnectionPool::get_instance();
-
- if(strNames.empty())
- {
- g_warning("Base_DB::insert_example_data(): strNames is empty.");
- }
-
//Actually insert the data:
const type_vecStrings vec_rows = Utils::string_separate(example_rows, "\n", false /* ignore \n inside quotes. */);
//std::cout << " debug: Base_DB::insert_example_data(): number of rows of data: " << vec_rows.size() << std::endl;
-
+
for(type_vecStrings::const_iterator iter = vec_rows.begin(); iter != vec_rows.end(); ++iter)
{
+ //Check that the row contains the correct number of columns.
+ //This check will slow this down, but it seems useful:
+ //TODO: This can only work if we can distinguish , inside "" and , outside "":
+ const Glib::ustring& row_data = *iter;
+ Glib::ustring strNames;
+ Glib::ustring strVals;
+ if(!row_data.empty())
+ {
+ const type_vecStrings vec_values = Utils::string_separate(row_data, ",", true /* ignore , inside quotes */);
+ //Do not allow any unescaped newlines in the row data.
+ //Note that this is checking for newlines ("\n"), not escaped newlines ("\\n").
+ if(row_data.find("\n") == Glib::ustring::npos)
+ {
+ for(unsigned int i = 0; i < vec_values.size(); ++i)
+ {
+ if (i > 0)
+ {
+ strVals += ", ";
+ strNames += ", ";
+ }
+ strNames += vec_fields[i]->get_name();
+ strVals += "##" + vec_fields[i]->get_name() + "::" + vec_fields[i]->get_gda_type();
+ }
+ const Glib::ustring strQuery = "INSERT INTO \"" + table_name + "\" (" + strNames + ") VALUES (" + strVals + ")";
+ //std::cout << "debug: BaseDB::insert_exampledata: " << strQuery << std::endl;
+ Glib::RefPtr<Gnome::Gda::SqlParser> parser = gda_connection->create_parser();
+ Glib::RefPtr<Gnome::Gda::Statement> stmt;
#ifdef GLIBMM_EXCEPTIONS_ENABLED
- try
-#endif // GLIBMM_EXCEPTIONS_ENABLED
- {
- //Check that the row contains the correct number of columns.
- //This check will slow this down, but it seems useful:
- //TODO: This can only work if we can distinguish , inside "" and , outside "":
- const Glib::ustring& row_data = *iter;
- if(!row_data.empty())
- {
- const type_vecStrings vec_values = Utils::string_separate(row_data, ",", true /* ignore , inside quotes */);
- if(true) //vec_values.size() == fields_count)
- {
- //Do not allow any unescaped newlines in the row data.
- //Note that this is checking for newlines ("\n"), not escaped newlines ("\\n").
- Glib::ustring converted_row_data;
- const Glib::ustring* actual_row_data = &row_data;
- if(row_data.find("\n") == Glib::ustring::npos)
+ try
+ {
+ stmt = parser->parse_string(strQuery);
+ }
+ catch (Gnome::Gda::SqlParserError& error)
+ {
+ std::cout << "BaseDB::insert_exampledata: " << error.what() << std::endl;
+ insert_succeeded = false;
+ break;
+ }
+#else
+ std::auto_ptr<Glib::Error> sql_error;
+ stmt = parser->parse_string(strQuery, sql_error);
+ if (sql_error)
+ {
+ std::cout << "BaseDB::insert_exampledata: " << error.what() << std::endl;
+ insert_succeeded = false;
+ break;
+ }
+#endif
+ Glib::RefPtr<Gnome::Gda::Set> params;
+ stmt->get_parameters(params);
+ for (unsigned int i = 0; i < vec_values.size(); ++i)
+ {
+ Glib::RefPtr<Gnome::Gda::Holder> holder = params->get_holder(vec_fields[i]->get_name());
+ if (holder)
{
- // All data is stored in postgres format in the examples file
- // (for historical reasons). Convert to the format the backend
- // requires, if necessary.
- if(connection_pool->get_sql_format() != Field::SQL_FORMAT_POSTGRES)
+ bool success;
+ Gnome::Gda::Value value = vec_fields[i]->from_sql(vec_values[i], Field::SQL_FORMAT_POSTGRES, success);
+ if (!success)
{
- for(unsigned int i = 0; i < vec_values.size(); ++i)
- {
- if(i > 0)
- converted_row_data += ", ";
- // If there are more fields than data values, then simply
- // omit the excess values.
- if(i >= vec_fields.size())
- break;
-
- bool success;
- const Gnome::Gda::Value value = vec_fields[i]->from_sql(vec_values[i], Field::SQL_FORMAT_POSTGRES, success);
-
- if(success)
- converted_row_data += vec_fields[i]->sql(value, connection_pool->get_sql_format());
- else
- converted_row_data += "''";
- }
-
- actual_row_data = &converted_row_data;
- }
-
- const Glib::ustring strQuery = "INSERT INTO \"" + table_name + "\" (" + strNames + ") VALUES (" + *actual_row_data + ")";
- //std::cout << "debug: before query: " << strQuery << std::endl;
- if(query_execute(strQuery))
- //std::cout << "debug: after query: " << strQuery << std::endl;
- insert_succeeded = true;
- else
- {
- insert_succeeded = false;
- break;
+ std::cout << "Base_DB::insert_example_data: could not convert example data" << std::endl;
+ continue;
}
+ holder->set_not_null(false); // some values might be null */
+ holder->set_value(value);
}
else
- {
- std::cerr << "Glom: Base_DB::insert_example_data(): nested newline found in row data: " << row_data << std::endl;
- }
+ std::cout << "Base_DB::insert_example_data: Missing holder: " << vec_fields[i]->get_name() << std::endl;
}
- else
+#ifdef GLIBMM_EXCEPTIONS_ENABLED
+ try
+ {
+ gda_connection->statement_execute_non_select (stmt, params);
+ }
+ catch (Glib::Error& error)
{
- std::cerr << "Glom: Base_DB::insert_example_data(): vec_values.size()=" << vec_values.size() << " != fields_count="<< fields_count << std::endl;
+ std::cout << "BaseDB::insert_exampledata: " << error.what() << std::endl;
+ insert_succeeded = false;
+ break;
}
+#else
+ std_autoptr<Glib::Error> exec_error;
+ gda_connection->statement_execute_non_select (stmt, params, exec_error);
+ if (exec_error)
+ {
+ std::cout << "BaseDB::insert_exampledata: " << error.what() << std::endl;
+ insert_succeeded = false;
+ break;
+ }
+#endif
+ }
+ else
+ {
+ std::cerr << "Glom: Base_DB::insert_example_data(): nested newline found in row data: " << row_data << std::endl;
}
}
-#ifdef GLIBMM_EXCEPTIONS_ENABLED
- catch(const ExceptionConnection& ex)
- {
- std::cerr << "debug: Base_DB::insert_example_data(): query_execute() failed: " << ex.what() << std::endl;
-
- insert_succeeded = false;
- break;
- }
-#endif
+ insert_succeeded = true;
}
for(Document_Glom::type_vecFields::const_iterator iter = vec_fields.begin(); iter != vec_fields.end(); ++iter)
@@ -1562,7 +1594,6 @@
if((*iter)->get_auto_increment())
recalculate_next_auto_increment_value(table_name, (*iter)->get_name());
}
-
return insert_succeeded;
}
Modified: trunk/glom/base_db.h
==============================================================================
--- trunk/glom/base_db.h (original)
+++ trunk/glom/base_db.h Thu Jan 22 09:18:15 2009
@@ -367,7 +367,8 @@
* This may take a few seconds to return.
*/
void update_gda_metastore_for_table(const Glib::ustring& table_name) const;
-
+
+ Glib::RefPtr<Gnome::Gda::Connection> get_connection() const;
static bool get_field_primary_key_index_for_fields(const type_vecFields& fields, guint& field_column);
static bool get_field_primary_key_index_for_fields(const type_vecLayoutFields& fields, guint& field_column);
Modified: trunk/glom/libglom/data_structure/field.cc
==============================================================================
--- trunk/glom/libglom/data_structure/field.cc (original)
+++ trunk/glom/libglom/data_structure/field.cc Thu Jan 22 09:18:15 2009
@@ -716,6 +716,27 @@
}
}
+Glib::ustring Field::get_gda_type() const
+{
+ switch (m_glom_type)
+ {
+ case TYPE_NUMERIC:
+ return g_type_name(GDA_TYPE_NUMERIC);
+ case TYPE_TEXT:
+ return g_type_name(G_TYPE_STRING);
+ case TYPE_DATE:
+ return g_type_name(G_TYPE_DATE);
+ case TYPE_TIME:
+ return g_type_name(GDA_TYPE_TIME);
+ case TYPE_BOOLEAN:
+ return g_type_name(G_TYPE_BOOLEAN);
+ case TYPE_IMAGE:
+ return g_type_name(GDA_TYPE_BINARY);
+ default:
+ g_assert_not_reached();
+ }
+}
+
/// Ignores any part of FieldAttributes that libgda does not properly fill.
bool Field::field_info_from_database_is_equal(const Glib::RefPtr<const Gnome::Gda::Column>& field)
{
Modified: trunk/glom/libglom/data_structure/field.h
==============================================================================
--- trunk/glom/libglom/data_structure/field.h (original)
+++ trunk/glom/libglom/data_structure/field.h Thu Jan 22 09:18:15 2009
@@ -159,6 +159,7 @@
void set_lookup_field(const Glib::ustring& strField);
Glib::ustring get_sql_type() const;
+ Glib::ustring get_gda_type() const;
/** Escape the value so that it can be used in a SQL command.
*/
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]