Fix date corruption in SQL load.

Four date elements were affected: GncEntry::date, GncEntry::date_entered,
GncInvoice::opened, and GncInvoice::posted. The problem arose during the
cleansing of Timespec from the reports; the setter functions for those
elements were converted to time64 but no provision was made to the SQL
backend to pass them time64 instead of Timespec*.

This commit adds a new column type, CT_TIME64, and changes the column
types for those elements to CT_TIME64.
This commit is contained in:
John Ralls 2018-03-16 16:47:11 -07:00
parent e5561bd7ab
commit 8fe2cb6fa8
4 changed files with 66 additions and 4 deletions

View File

@ -70,9 +70,9 @@ static void entry_set_bill (gpointer pObject, gpointer val);
static EntryVec col_table
({
gnc_sql_make_table_entry<CT_GUID>("guid", 0, COL_NNUL | COL_PKEY, "guid"),
gnc_sql_make_table_entry<CT_TIMESPEC>("date", 0, COL_NNUL, ENTRY_DATE,
gnc_sql_make_table_entry<CT_TIME64>("date", 0, COL_NNUL, ENTRY_DATE,
true),
gnc_sql_make_table_entry<CT_TIMESPEC>("date_entered", 0, 0,
gnc_sql_make_table_entry<CT_TIME64>("date_entered", 0, 0,
ENTRY_DATE_ENTERED, true),
gnc_sql_make_table_entry<CT_STRING>(
"description", MAX_DESCRIPTION_LEN, 0, "description"),

View File

@ -67,9 +67,9 @@ static EntryVec col_table
gnc_sql_make_table_entry<CT_GUID>("guid", 0, COL_NNUL | COL_PKEY, "guid"),
gnc_sql_make_table_entry<CT_STRING>("id", MAX_ID_LEN, COL_NNUL, INVOICE_ID,
true),
gnc_sql_make_table_entry<CT_TIMESPEC>("date_opened", 0, 0, INVOICE_OPENED,
gnc_sql_make_table_entry<CT_TIME64>("date_opened", 0, 0, INVOICE_OPENED,
true),
gnc_sql_make_table_entry<CT_TIMESPEC>("date_posted", 0, 0, INVOICE_POSTED,
gnc_sql_make_table_entry<CT_TIME64>("date_posted", 0, 0, INVOICE_POSTED,
true),
gnc_sql_make_table_entry<CT_STRING>("notes", MAX_NOTES_LEN, COL_NNUL,
"notes"),

View File

@ -454,6 +454,67 @@ GncSqlColumnTableEntryImpl<CT_TIMESPEC>::add_to_query(QofIdTypeConst obj_name,
"NULL"));
}
}
/* ----------------------------------------------------------------- */
typedef time64 (*Time64AccessFunc) (const gpointer);
typedef void (*Time64SetterFunc) (const gpointer, time64);
template<> void
GncSqlColumnTableEntryImpl<CT_TIME64>::load (const GncSqlBackend* sql_be,
GncSqlRow& row,
QofIdTypeConst obj_name,
gpointer pObject)
const noexcept
{
time64 t;
g_return_if_fail (m_gobj_param_name != nullptr || get_setter(obj_name) != nullptr);
try
{
t = row.get_time64_at_col (m_col_name);
}
catch (std::invalid_argument)
{
try
{
auto val = row.get_string_at_col(m_col_name);
GncDateTime time(val);
t = static_cast<time64>(time);
}
catch (std::invalid_argument)
{
return;
}
}
set_parameter(pObject, t,
reinterpret_cast<Time64SetterFunc>(get_setter(obj_name)),
m_gobj_param_name);
}
template<> void
GncSqlColumnTableEntryImpl<CT_TIME64>::add_to_table(ColVec& vec) const noexcept
{
GncSqlColumnInfo info{*this, BCT_DATETIME, TIMESPEC_COL_SIZE, FALSE};
vec.emplace_back(std::move(info));
}
template<> void
GncSqlColumnTableEntryImpl<CT_TIME64>::add_to_query(QofIdTypeConst obj_name,
const gpointer pObject,
PairVec& vec) const noexcept
{
auto t = get_row_value_from_object<time64>(obj_name, pObject);
if (t > MINTIME && t < MAXTIME)
{
GncDateTime time(t);
vec.emplace_back (std::make_pair (std::string{m_col_name},
time.format_zulu ("'%Y-%m-%d %H:%M:%S'")));
}
else
{
vec.emplace_back (std::make_pair (std::string{m_col_name},
"NULL"));
}
}
/* ----------------------------------------------------------------- */
#define DATE_COL_SIZE 8

View File

@ -70,6 +70,7 @@ enum GncSqlObjectType
CT_INT,
CT_INT64,
CT_TIMESPEC,
CT_TIME64,
CT_GDATE,
CT_NUMERIC,
CT_DOUBLE,