glom r1617 - in trunk: . glom glom/libglom/data_structure
- From: arminb svn gnome org
- To: svn-commits-list gnome org
- Subject: glom r1617 - in trunk: . glom glom/libglom/data_structure
- Date: Fri, 23 May 2008 14:43:24 +0000 (UTC)
Author: arminb
Date: Fri May 23 14:43:23 2008
New Revision: 1617
URL: http://svn.gnome.org/viewvc/glom?rev=1617&view=rev
Log:
2008-05-23 Armin Burgmeier <armin arbur net>
* glom/libglom/data_structure/field.h:
* glom/libglom/data_structure/field.cc: Added from_sql() to convert a
SQL representation to a Gnome::Gda::Value. This is the reverse to the
sql() function.
* glom/dialog_import_csv.cc (field_data_func): Remove own unescaping
code, use Field::from_sql() for preview instead.
* glom/dialog_import_csv_progress.cc (on_idle_import): Use
Field::from_sql() to do the actual import. This allows to correctly
import files that the Export functionality produces, escpecially
dates and images.
Modified:
trunk/ChangeLog
trunk/glom/dialog_import_csv.cc
trunk/glom/dialog_import_csv_progress.cc
trunk/glom/libglom/data_structure/field.cc
trunk/glom/libglom/data_structure/field.h
Modified: trunk/glom/dialog_import_csv.cc
==============================================================================
--- trunk/glom/dialog_import_csv.cc (original)
+++ trunk/glom/dialog_import_csv.cc Fri May 23 14:43:23 2008
@@ -33,6 +33,7 @@
const gunichar DELIMITER = ',';
+#if 0
// TODO: Perhaps we should change this to std::string to allow binary data, such
// as images.
// TODO: What escaping system is this? Can't we reuse some standard escaping function from somewhere? murrayc
@@ -112,48 +113,38 @@
return walk;
}
}
+#endif
Glib::ustring::const_iterator advance_field(const Glib::ustring::const_iterator& iter, const Glib::ustring::const_iterator& end, Glib::ustring& field)
{
Glib::ustring::const_iterator walk = iter;
+
gunichar quote_char = 0;
+ bool escaped = false;
field.clear();
- while(walk != end)
+ for(; walk != end; ++ walk)
{
gunichar c = *walk;
+ // Skip escape sequences
+ if(escaped) { field += c; escaped = false; continue; }
+
// Escaped stuff in quoted strings:
if(quote_char && c == '\\')
- {
- ++ walk;
- walk = advance_escape(walk, end, c);
- field.append(1, c);
- }
+ escaped = true;
// End of quoted string
else if(quote_char && c == quote_char)
- {
quote_char = 0;
- ++ walk;
- }
- // Begin of quoted string. This allows stuff such as "foo"'bar'baz in a field here,
- // but it can easily be avoided if it's a problem, by checking walk against iter.
+ // Begin of quoted string.
else if(!quote_char && (c == '\'' || c == '\"'))
- {
quote_char = c;
- ++ walk;
- }
// End of field:
else if(!quote_char && c == DELIMITER)
- {
break;
- }
- else
- {
- field.append(1, c);
- ++ walk;
- }
+
+ field += c; // Just so that we don't need to iterate through the field again, since there is no Glib::ustring::substr(iter, iter)
}
// TODO: Throw error if still inside a quoted string?
@@ -861,13 +852,39 @@
// Convert to currently chosen field, if any, and back, too see how it
// looks like when imported
sharedptr<Field> field = m_fields[column_number];
- Glib::ustring text = m_rows[row][column_number];
+ const Glib::ustring& orig_text = m_rows[row][column_number];
+
+ Glib::ustring text;
if(field)
{
bool success;
- Gnome::Gda::Value value = Glom::Conversions::parse_value(field->get_glom_type(), text, success);
- if(!success) text = _("<Import failure>");
- else text = Glom::Conversions::get_text_for_gda_value(field->get_glom_type(), value);
+
+ if(field->get_glom_type() != Field::TYPE_IMAGE)
+ {
+ Gnome::Gda::Value value = field->from_sql(orig_text, success);
+
+ if(!success) text = _("<Import Failure>");
+ else text = Glom::Conversions::get_text_for_gda_value(field->get_glom_type(), value);
+ }
+ else
+ {
+ // TODO: It is too slow to create the picture here. Maybe we should
+ // create it once and cache it. We could also think about using a
+ // GtkCellRendererPixbuf to show it, then.
+ if(!orig_text.empty() && orig_text != "NULL")
+ text = _("<Picture>");
+ }
+ }
+ else
+ {
+ // TODO: Should we unescape the field's content?
+ text = orig_text;
+ }
+
+ if(text.length() > 32)
+ {
+ text.erase(32);
+ text.append("â");
}
renderer_combo->set_property("text", text);
Modified: trunk/glom/dialog_import_csv_progress.cc
==============================================================================
--- trunk/glom/dialog_import_csv_progress.cc (original)
+++ trunk/glom/dialog_import_csv_progress.cc Fri May 23 14:43:23 2008
@@ -143,7 +143,8 @@
if(field)
{
bool success;
- Gnome::Gda::Value value = Glom::Conversions::parse_value(field->get_glom_type(), m_data_source->get_data(m_current_row, i), success);
+ Gnome::Gda::Value value = field->from_sql(m_data_source->get_data(m_current_row, i), success);
+
if(success)
{
// Make the value empty if the value is not unique.
Modified: trunk/glom/libglom/data_structure/field.cc
==============================================================================
--- trunk/glom/libglom/data_structure/field.cc (original)
+++ trunk/glom/libglom/data_structure/field.cc Fri May 23 14:43:23 2008
@@ -242,6 +242,83 @@
}
}
+#define ISFIRSTOCTDIGIT(CH) ((CH) >= '0' && (CH) <= '3')
+#define ISOCTDIGIT(CH) ((CH) >= '0' && (CH) <= '7')
+#define OCTVAL(CH) ((CH) - '0')
+
+/// Unescape text that was escaped by the above function. Only unescapes
+/// quoted strings. Nonquoted strings are returned without being modified.
+static std::string glom_unescape_text(const std::string& str)
+{
+ std::string::const_iterator iter = str.begin();
+ if(iter == str.end()) return str; // Empty string
+ if(*iter != '\'') return str; // Non-quoted
+ ++ iter;
+
+ std::string result;
+
+ while(iter != str.end())
+ {
+ // End here if this is the terminating quotation character, or unescape
+ // '' to '.
+ if(*iter == '\'')
+ {
+ ++ iter;
+ if(iter == str.end() || *iter != '\'') break;
+ result += '\'';
+ ++ iter;
+ }
+ // Unescape "" to ".
+ else if(*iter == '\"')
+ {
+ ++ iter;
+ if(iter == str.end()) break;
+ result += '\"';
+ ++ iter;
+ }
+ // Escape sequence beginning with backslash.
+ else if(*iter == '\\')
+ {
+ ++ iter;
+ if(iter == str.end()) break;
+
+ // Escaped backslash
+ if(*iter == '\\')
+ {
+ result += '\\';
+ ++ iter;
+ }
+ // Some octal representation
+ else if(ISFIRSTOCTDIGIT(*iter))
+ {
+ unsigned char byte = OCTVAL(*iter);
+
+ ++ iter;
+ if(iter != str.end() && ISOCTDIGIT(*iter))
+ {
+ byte = (byte << 3) | OCTVAL(*iter);
+ ++ iter;
+ if(iter != str.end() && ISOCTDIGIT(*iter))
+ {
+ byte = (byte << 3) | OCTVAL(*iter);
+ ++ iter;
+ }
+ }
+
+ result += byte;
+ }
+ }
+ else
+ {
+ // Take char as is
+ result += *iter;
+ ++ iter;
+ }
+ }
+
+ return result;
+}
+
Glib::ustring Field::sql(const Gnome::Gda::Value& value) const
{
//g_warning("Field::sql: glom_type=%d", get_glom_type());
@@ -351,6 +428,64 @@
return str;
}
+Gnome::Gda::Value Field::from_sql(const Glib::ustring& str, bool& success) const
+{
+ success = true;
+ switch(m_glom_type)
+ {
+ case TYPE_TEXT:
+ {
+ return Gnome::Gda::Value(glom_unescape_text(str));
+ }
+ case TYPE_DATE:
+ case TYPE_TIME:
+ {
+ if(str == "NULL") return Gnome::Gda::Value();
+ Glib::ustring unescaped = glom_unescape_text(str);
+
+ NumericFormat format_ignored; //Because we use ISO format.
+ return Conversions::parse_value(m_glom_type, unescaped, format_ignored, success, true);
+ }
+ case TYPE_NUMERIC:
+ {
+ //No quotes for numbers.
+ NumericFormat format_ignored; //Because we use ISO format.
+ return Conversions::parse_value(m_glom_type, str, format_ignored, success, true);
+ }
+ case TYPE_BOOLEAN:
+ {
+ if(str.lowercase() == "true")
+ return Gnome::Gda::Value(true);
+ return Gnome::Gda::Value(false);
+ }
+ case TYPE_IMAGE:
+ {
+ if(str == "NULL") return Gnome::Gda::Value();
+
+ // We store the data into the format E'some escaped data'::bytea, and we
+ // now expect it in exactly that format now.
+ // We operate on the raw std::string since access into the Glib::ustring
+ // is expensive, and we only check for ASCII stuff anyway.
+ const std::string& raw = str.raw();
+ if(raw.length() >= 10 &&
+ raw.compare(0, 2, "E'") == 0 && raw.compare(raw.length() - 8, 8, "'::bytea") == 0)
+ {
+ std::string unescaped = glom_unescape_text(raw.substr(1, raw.length() - 8));
+ NumericFormat format_ignored; //Because we use ISO format.
+ return Conversions::parse_value(m_glom_type, unescaped, format_ignored, success, true);
+ }
+ else
+ {
+ success = false;
+ return Gnome::Gda::Value();
+ }
+ }
+ default:
+ g_assert_not_reached();
+ break;
+ }
+}
+
Glib::ustring Field::sql_find(const Gnome::Gda::Value& value) const
{
switch(get_glom_type())
Modified: trunk/glom/libglom/data_structure/field.h
==============================================================================
--- trunk/glom/libglom/data_structure/field.h (original)
+++ trunk/glom/libglom/data_structure/field.h Fri May 23 14:43:23 2008
@@ -159,6 +159,10 @@
*/
Glib::ustring sql(const Gnome::Gda::Value& value) const;
+ /** Unescape the value again.
+ */
+ Gnome::Gda::Value from_sql(const Glib::ustring& str, bool& success) const;
+
/** Escape the value so that it can be used in a SQL command for a find.
*/
Glib::ustring sql_find(const Gnome::Gda::Value& value) const;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]