Convert GNC_TYPE_TIMESPEC to GNC_TYPE_TIME64, Kvp::Type::Timespec to Kvp::Type::Time64

They have to go together because of using gvalues to hide KVP from most of
GnuCash.
This commit is contained in:
John Ralls 2018-08-02 13:29:47 -07:00
parent b60aef9d2a
commit c8b372e390
21 changed files with 96 additions and 96 deletions

View File

@ -98,20 +98,20 @@ gnc_ab_set_account_uid(Account *a, guint32 uid)
time64
gnc_ab_get_account_trans_retrieval(const Account *a)
{
Timespec *t = NULL;
Time64 *t = NULL;
qof_instance_get (QOF_INSTANCE (a),
"ab-trans-retrieval", &t,
NULL);
return t ? t->tv_sec : 0;
return t ? t->t : 0;
}
void
gnc_ab_set_account_trans_retrieval(Account *a, time64 time)
{
Timespec ts = {time, 0};
Time64 t = {time};
xaccAccountBeginEdit(a);
qof_instance_set (QOF_INSTANCE (a),
"ab-trans-retrieval", &ts,
"ab-trans-retrieval", &t,
NULL);
xaccAccountCommitEdit(a);
}

View File

@ -138,7 +138,7 @@ setup_memory (Fixture* fixture, gconstpointer pData)
frame->set ({"int64-val"}, new KvpValue (INT64_C (100)));
frame->set ({"double-val"}, new KvpValue (3.14159));
frame->set ({"numeric-val"}, new KvpValue (gnc_numeric_zero ()));
frame->set ({"timespec-val"}, new KvpValue (timespec_now ()));
frame->set ({"timespec-val"}, new KvpValue (gnc_time(nullptr)));
frame->set ({"string-val"}, new KvpValue ("abcdefghijklmnop"));
auto guid = qof_instance_get_guid (QOF_INSTANCE (acct1));
frame->set ({"guid-val"}, new KvpValue (const_cast<GncGUID*> (guid_copy (

View File

@ -397,8 +397,9 @@ get_timespec_val (gpointer pObject)
g_return_val_if_fail (pObject != NULL, gnc_dmy2timespec (1, 1, 1970));
//if( kvp_value_get_type( pInfo->pKvpValue ) == KvpValue::Type::TIMESPEC ) {
return pInfo->pKvpValue->get<Timespec> ();
//if( kvp_value_get_type( pInfo->pKvpValue ) == KvpValue::Type::TIME64 ) {
auto t = pInfo->pKvpValue->get<Time64> ();
return {t.t, 0};
}
static void
@ -406,11 +407,11 @@ set_timespec_val (gpointer pObject, Timespec *ts)
{
slot_info_t* pInfo = (slot_info_t*)pObject;
KvpValue* value = NULL;
Time64 t{ts->tv_sec};
g_return_if_fail (pObject != NULL);
if (pInfo->value_type != KvpValue::Type::TIMESPEC) return;
value = new KvpValue {*ts};
if (pInfo->value_type != KvpValue::Type::TIME64) return;
value = new KvpValue {t};
set_slot_from_value (pInfo, value);
}

View File

@ -237,7 +237,7 @@ add_kvp_value_node (xmlNodePtr node, const gchar* tag, KvpValue* val)
g_free (newstr);
break;
}
case KvpValue::Type::TIMESPEC:
case KvpValue::Type::TIME64:
val_node = NULL;
break;
case KvpValue::Type::GDATE:
@ -277,10 +277,10 @@ add_kvp_value_node (xmlNodePtr node, const gchar* tag, KvpValue* val)
add_text_to_node (val_node, "guid", guidstr);
break;
}
case KvpValue::Type::TIMESPEC:
case KvpValue::Type::TIME64:
{
auto ts = val->get<Timespec> ();
val_node = time64_to_dom_tree (tag, ts.tv_sec);
auto t = val->get<Time64> ();
val_node = time64_to_dom_tree (tag, t.t);
xmlSetProp (val_node, BAD_CAST "type", BAD_CAST "timespec");
xmlAddChild (node, val_node);
break;

View File

@ -235,7 +235,8 @@ dom_tree_to_guid_kvp_value (xmlNodePtr node)
static KvpValue*
dom_tree_to_time64_kvp_value (xmlNodePtr node)
{
return new KvpValue {Timespec {dom_tree_to_time64 (node), 0}};
Time64 t{dom_tree_to_time64 (node)};
return new KvpValue {t};
}
static KvpValue*

View File

@ -995,7 +995,7 @@ gnc_account_class_init (AccountClass *klass)
"AQBanking Last Transaction Retrieval",
"The time of the last transaction retrieval for this "
"account.",
GNC_TYPE_TIMESPEC,
GNC_TYPE_TIME64,
static_cast<GParamFlags>(G_PARAM_READWRITE)));
}

View File

@ -170,7 +170,7 @@ gnc_split_get_property(GObject *object,
g_value_set_boxed(value, &split->amount);
break;
case PROP_RECONCILE_DATE:
g_value_set_boxed(value, &split->date_reconciled);
g_value_set_boxed(value, &split->date_reconciled.tv_sec);
break;
case PROP_TX:
g_value_take_object(value, split->parent);
@ -223,7 +223,7 @@ gnc_split_set_property(GObject *object,
Split *split;
gnc_numeric* number;
gchar *key;
Time64 *t;
g_return_if_fail(GNC_IS_SPLIT(object));
split = GNC_SPLIT(object);
@ -247,7 +247,8 @@ gnc_split_set_property(GObject *object,
xaccSplitSetAmount(split, *number);
break;
case PROP_RECONCILE_DATE:
xaccSplitSetDateReconciledTS(split, g_value_get_boxed(value));
t = g_value_get_boxed(value);
xaccSplitSetDateReconciledSecs(split, t->t);
break;
case PROP_TX:
xaccSplitSetParent(split, g_value_get_object(value));
@ -353,7 +354,7 @@ gnc_split_class_init(SplitClass* klass)
g_param_spec_boxed("reconcile-date",
"Reconcile Date",
"The date this split was reconciled.",
GNC_TYPE_TIMESPEC,
GNC_TYPE_TIME64,
G_PARAM_READWRITE));
g_object_class_install_property

View File

@ -310,7 +310,6 @@ gnc_transaction_get_property(GObject* object,
{
Transaction* tx;
gchar *key;
Timespec ts = {0,0};
g_return_if_fail(GNC_IS_TRANSACTION(object));
@ -327,12 +326,10 @@ gnc_transaction_get_property(GObject* object,
g_value_take_object(value, tx->common_currency);
break;
case PROP_POST_DATE:
ts.tv_sec = tx->date_posted;
g_value_set_boxed(value, &ts);
g_value_set_boxed(value, &tx->date_posted);
break;
case PROP_ENTER_DATE:
ts.tv_sec = tx->date_entered;
g_value_set_boxed(value, &ts);
g_value_set_boxed(value, &tx->date_entered);
break;
case PROP_INVOICE:
qof_instance_get_kvp (QOF_INSTANCE (tx), value, 2, GNC_INVOICE_ID, GNC_INVOICE_GUID);
@ -357,6 +354,7 @@ gnc_transaction_set_property(GObject* object,
{
Transaction* tx;
gchar *key;
Time64 *t;
g_return_if_fail(GNC_IS_TRANSACTION(object));
@ -375,10 +373,12 @@ gnc_transaction_set_property(GObject* object,
xaccTransSetCurrency(tx, g_value_get_object(value));
break;
case PROP_POST_DATE:
xaccTransSetDatePostedSecs(tx, ((Timespec*)g_value_get_boxed(value))->tv_sec);
t = (Time64*)g_value_get_boxed(value);
xaccTransSetDatePostedSecs(tx, t->t);
break;
case PROP_ENTER_DATE:
xaccTransSetDateEnteredSecs(tx, ((Timespec*)g_value_get_boxed(value))->tv_sec);
t = (Time64*)g_value_get_boxed(value);
xaccTransSetDateEnteredSecs(tx, t->t);
break;
case PROP_INVOICE:
qof_instance_set_kvp (QOF_INSTANCE (tx), value, 2, GNC_INVOICE_ID, GNC_INVOICE_GUID);
@ -446,7 +446,7 @@ gnc_transaction_class_init(TransactionClass* klass)
g_param_spec_boxed("post-date",
"Post Date",
"The date the transaction occurred.",
GNC_TYPE_TIMESPEC,
GNC_TYPE_TIME64,
G_PARAM_READWRITE));
g_object_class_install_property
@ -455,7 +455,7 @@ gnc_transaction_class_init(TransactionClass* klass)
g_param_spec_boxed("enter-date",
"Enter Date",
"The date the transaction was entered.",
GNC_TYPE_TIMESPEC,
GNC_TYPE_TIME64,
G_PARAM_READWRITE));
g_object_class_install_property(
@ -2035,10 +2035,9 @@ void
xaccTransSetDateDue (Transaction * trans, time64 time)
{
GValue v = G_VALUE_INIT;
Timespec send_ts = {time, 0};
if (!trans) return;
g_value_init (&v, GNC_TYPE_TIMESPEC);
g_value_set_boxed (&v, &send_ts);
g_value_init (&v, GNC_TYPE_TIME64);
g_value_set_boxed (&v, &time);
xaccTransBeginEdit(trans);
qof_instance_set_kvp (QOF_INSTANCE (trans), &v, 1, TRANS_DATE_DUE_KVP);
qof_instance_set_dirty(QOF_INSTANCE(trans));

View File

@ -1262,18 +1262,6 @@ gnc_timespec_to_iso8601_buff (Timespec ts, char * buff)
}
}
void
gnc_timespec2dmy (Timespec t, int *day, int *month, int *year)
{
struct tm result;
time64 t_secs = t.tv_sec + (t.tv_nsec / NANOS_PER_SECOND);
gnc_localtime_r(&t_secs, &result);
if (day) *day = result.tm_mday;
if (month) *month = result.tm_mon + 1;
if (year) *year = result.tm_year + 1900;
}
#define THIRTY_TWO_YEARS 0x3c30fc00LL
static Timespec
@ -1518,33 +1506,34 @@ gnc_dow_abbrev(gchar *buf, int buf_len, int dow)
/* *******************************************************************
* GValue handling
********************************************************************/
static gpointer
timespec_boxed_copy_func( gpointer in_timespec )
{
Timespec* newvalue;
newvalue = static_cast<Timespec*>(g_malloc (sizeof (Timespec)));
memcpy( newvalue, in_timespec, sizeof( Timespec ) );
static gpointer
time64_boxed_copy_func (gpointer in_time64)
{
Time64* newvalue;
newvalue = static_cast<Time64*>(g_malloc (sizeof (Time64)));
memcpy (newvalue, in_time64, sizeof(Time64));
return newvalue;
}
static void
timespec_boxed_free_func( gpointer in_timespec )
time64_boxed_free_func (gpointer in_time64)
{
g_free( in_timespec );
g_free (in_time64);
}
GType
timespec_get_type( void )
time64_get_type( void )
{
static GType type = 0;
if ( type == 0 )
{
type = g_boxed_type_register_static( "timespec",
timespec_boxed_copy_func,
timespec_boxed_free_func );
type = g_boxed_type_register_static( "time64",
time64_boxed_copy_func,
time64_boxed_free_func );
}
return type;
}

View File

@ -82,6 +82,14 @@ extern "C"
* this stops working in 2038, we define our own:
*/
typedef gint64 time64;
/* A bit of a hack to create a type separate from the alias of int64_t so that
* compile-time dispatch can use the right KVP visitor.
*/
typedef struct
{
time64 t;
} Time64;
/** The Timespec is just like the unix 'struct timespec'
* except that we use a 64-bit unsigned int to
@ -96,8 +104,8 @@ typedef struct timespec64 Timespec;
/** @name GValue
@{
*/
GType timespec_get_type( void );
#define GNC_TYPE_TIMESPEC (timespec_get_type ())
GType time64_get_type( void );
#define GNC_TYPE_TIME64 (time64_get_type ())
/** @} */
/** The default date format for use with strftime. */

View File

@ -101,7 +101,7 @@ GncInvoice *gncInvoiceCopy (const GncInvoice *other_invoice);
void gncInvoiceSetID (GncInvoice *invoice, const char *id);
void gncInvoiceSetOwner (GncInvoice *invoice, GncOwner *owner);
/** Set the DateOpened using a GDate argument. (Note: Internally this stores
the date in a time64 as created through timespecCanonicalDayTime()). */
the date in a time64 as created through time64CanonicalDayTime()). */
void gncInvoiceSetDateOpenedGDate (GncInvoice *invoice, const GDate *date);
void gncInvoiceSetDateOpened (GncInvoice *invoice, time64 date);
void gncInvoiceSetDatePosted (GncInvoice *invoice, time64 date);

View File

@ -257,7 +257,7 @@ gnc_order_class_init (GncOrderClass *klass)
g_param_spec_boxed("date-opened",
"Date Opened",
"The date the order was opened.",
GNC_TYPE_TIMESPEC,
GNC_TYPE_TIME64,
G_PARAM_READWRITE));
g_object_class_install_property
@ -266,7 +266,7 @@ gnc_order_class_init (GncOrderClass *klass)
g_param_spec_boxed("date-closed",
"Date Closed",
"The date the order was closed.",
GNC_TYPE_TIMESPEC,
GNC_TYPE_TIME64,
G_PARAM_READWRITE));
g_object_class_install_property

View File

@ -261,7 +261,7 @@ gvalue_from_kvp_value (const KvpValue *kval)
{
GValue *val;
gnc_numeric num;
Timespec tm;
Time64 tm;
GDate gdate;
if (kval == NULL) return NULL;
@ -290,9 +290,9 @@ gvalue_from_kvp_value (const KvpValue *kval)
g_value_init (val, GNC_TYPE_GUID);
g_value_set_boxed (val, kval->get<GncGUID*>());
break;
case KvpValue::Type::TIMESPEC:
g_value_init (val, GNC_TYPE_TIMESPEC);
tm = kval->get<Timespec>();
case KvpValue::Type::TIME64:
g_value_init (val, GNC_TYPE_TIME64);
tm = kval->get<Time64>();
g_value_set_boxed (val, &tm);
break;
case KvpValue::Type::GDATE:
@ -357,8 +357,8 @@ kvp_value_from_gvalue (const GValue *gval)
if (boxed != nullptr)
val = new KvpValue(guid_copy(static_cast<GncGUID*>(boxed)));
}
else if (type == GNC_TYPE_TIMESPEC)
val = new KvpValue(*(Timespec*)g_value_get_boxed (gval));
else if (type == GNC_TYPE_TIME64)
val = new KvpValue(*(Time64*)g_value_get_boxed (gval));
else if (type == G_TYPE_DATE)
val = new KvpValue(*(GDate*)g_value_get_boxed (gval));
else if (type == GNC_TYPE_VALUE_LIST)

View File

@ -85,8 +85,8 @@ KvpValueImpl::get_type() const noexcept
return KvpValue::Type::STRING;
else if (datastore.type() == typeid(GncGUID *))
return KvpValue::Type::GUID;
else if (datastore.type() == typeid(Timespec))
return KvpValue::Type::TIMESPEC;
else if (datastore.type() == typeid(Time64))
return KvpValue::Type::TIME64;
else if (datastore.type() == typeid(GList *))
return KvpValue::Type::GLIST;
else if (datastore.type() == typeid(KvpFrameImpl *))
@ -155,11 +155,11 @@ struct to_string_visitor : boost::static_visitor<void>
output << ")";
}
void operator()(Timespec val)
void operator()(Time64 val)
{
char tmp1[40] {};
gnc_timespec_to_iso8601_buff (val, tmp1);
output << tmp1 << " (timespec)";
char tmp1[MAX_DATE_LENGTH + 1] {};
gnc_time64_to_iso8601_buff (val.t, tmp1);
output << tmp1 << " (time64)";
}
void operator()(gnc_numeric val)
@ -301,9 +301,9 @@ template <> int compare_visitor::operator()(GncGUID * const & one, GncGUID * con
{
return guid_compare(one, two);
}
template <> int compare_visitor::operator()(Timespec const & one, Timespec const & two) const
template <> int compare_visitor::operator()(Time64 const & one, Time64 const & two) const
{
return timespec_cmp(&one,&two);
return one.t < two.t ? -1 : one.t > two.t ? 1 : 0;
}
template <> int compare_visitor::operator()(GDate const & one, GDate const & two) const
{

View File

@ -65,7 +65,7 @@ struct KvpValueImpl
NUMERIC, /**< QOF_TYPE_NUMERIC */
STRING, /**< QOF_TYPE_STRING gchar* */
GUID, /**< QOF_TYPE_GUID */
TIMESPEC, /**< QOF_TYPE_DATE */
TIME64, /**< QOF_TYPE_DATE */
PLACEHOLDER_DONT_USE, /* Replaces KVP_TYPE_BINARY */
GLIST, /**< no QOF equivalent. */
FRAME, /**< no QOF equivalent. */
@ -156,7 +156,7 @@ struct KvpValueImpl
gnc_numeric,
const char*,
GncGUID *,
Timespec,
Time64,
GList *,
KvpFrame *,
GDate> datastore;

View File

@ -72,7 +72,7 @@ Use: An enumerated identifier indicating how often books are supposed
\verbatim
Name: /book/close-date
Type: Timespec
Type: Time64
Entities: Book
Use: The posted closing date of this book. This book only contains
transactions whose posted date is earlier than this closing date.
@ -98,7 +98,7 @@ Use: The GUID of the book for which this transaction represents the
\verbatim
Name: /book/log-date
Type: Timespec
Type: Time64
Entities: Book
Use: A log of the date which the user performed the closing of the book.
\endverbatim
@ -131,7 +131,7 @@ Use: User-suplied notes for the book. The user can set this to any value
\verbatim
Name: /book/open-date
Type: Timespec
Type: Time64
Entities: Book
Use: The posted opening date of this book. This book only contains transactions
whose posted date is later than this closing date.
@ -254,7 +254,7 @@ Use: When this appears in an account, then it contains the guid of
\verbatim
Name: /gemini/<type>/date
Type: timespec
Type: time64
Entities: Account, Book
Use: date that the copy was created.
\endverbatim
@ -293,7 +293,7 @@ Use: Country code of the bank of HBCI account
\verbatim
Name: /hbci/trans-retrieval
Type: Timespec
Type: Time64
Entities: Account
Use: Time of the last statement retrieval through HBCI for this
specific account
@ -577,7 +577,7 @@ Use: A user-supplied title for the lot. The user can set this to
\verbatim
Name: trans-date-due
Type: Timespec
Type: Time64
Entities: Transaction
Use: Accounts/Receivable, Accounts/Payable Due Date.
\endverbatim

View File

@ -1144,8 +1144,9 @@ qof_instance_kvp_add_guid (const QofInstance *inst, const char* path,
g_return_if_fail (inst->kvp_data != NULL);
auto container = new KvpFrame;
Time64 t{time.tv_sec};
container->set({key}, new KvpValue(const_cast<GncGUID*>(guid)));
container->set({"date"}, new KvpValue(time));
container->set({"date"}, new KvpValue(t));
delete inst->kvp_data->set_path({path}, new KvpValue(container));
}

View File

@ -324,11 +324,10 @@ get_random_kvp_value_depth (int type, gint depth)
}
break;
case KvpValue::Type::TIMESPEC:
case KvpValue::Type::TIME64:
{
Timespec *ts = get_random_timespec();
ret = new KvpValue(*ts);
g_free(ts);
time64 t = get_random_time();
ret = new KvpValue(t);
}
break;

View File

@ -144,8 +144,8 @@ test_account_kvp_properties (Fixture *fixture, gconstpointer pData)
gchar *online_id_r, *ab_acct_id_r, *ab_bank_code_r;
GncGUID *ofx_income_acct = guid_malloc ();
GncGUID *ofx_income_acct_r;
Timespec trans_retr = timespec_now ();
Timespec *trans_retr_r;
Time64 trans_retr = {gnc_time(NULL)};
Time64 *trans_retr_r;
xaccAccountBeginEdit (fixture->acct);
qof_instance_set (QOF_INSTANCE (fixture->acct),
@ -176,7 +176,7 @@ test_account_kvp_properties (Fixture *fixture, gconstpointer pData)
g_assert_cmpstr (ab_acct_id, ==, ab_acct_id_r);
g_assert_cmpstr (ab_bank_code, ==, ab_bank_code_r);
g_assert_cmpint (ab_acct_uid, ==, ab_acct_uid_r);
g_assert (timespec_equal (&trans_retr, trans_retr_r));
g_assert_cmpint (trans_retr.t, ==, trans_retr_r->t);
g_assert (!qof_instance_is_dirty (QOF_INSTANCE (fixture->acct)));
}

View File

@ -55,14 +55,14 @@ TEST (KvpValueTest, Equality)
v2 = std::unique_ptr<KvpValueImpl> {new KvpValueImpl {guid_copy (guid)}};
EXPECT_EQ (compare (*v1, *v2), 0);
v1 = std::unique_ptr<KvpValueImpl> {new KvpValueImpl {timespec_now ()}};
v1 = std::unique_ptr<KvpValueImpl> {new KvpValueImpl {gnc_time(nullptr)}};
v2 = std::unique_ptr<KvpValueImpl> {new KvpValueImpl {*v1}};
EXPECT_EQ (compare (*v1, *v2), 0);
}
TEST (KvpValueTest, Add)
{
auto v3 = new KvpValueImpl {timespec_now ()};
auto v3 = new KvpValueImpl {gnc_time(nullptr)};
auto v4 = new KvpValueImpl {*v3};
auto new_one = v3->add (v4);
EXPECT_NE (new_one, v3);

View File

@ -201,7 +201,8 @@ test_gnc_split_set_get_property ()
Account *acc = xaccMallocAccount (book), *racc = NULL;
GNCLot *lot = gnc_lot_new (book), *rlot = NULL;
Split *split = xaccMallocSplit (book);
Timespec time = timespec_now (), *rtime;
time64 time = gnc_time(nullptr);
Time64 t = {time}, *rtime;
char *r_action, *r_memo;
gnc_numeric value = gnc_numeric_create (123, 100);
gnc_numeric amount = gnc_numeric_create (321, 100);
@ -218,7 +219,7 @@ test_gnc_split_set_get_property ()
"memo", "bar",
"value", &value,
"amount", &amount,
"reconcile-date", &time,
"reconcile-date", &t,
"account", acc,
"lot", lot,
"transaction", txn,
@ -240,7 +241,7 @@ test_gnc_split_set_get_property ()
g_assert (gnc_numeric_equal (*r_value, value));
/* Setting the transaction causes the amount to be scrubbed into the value */
g_assert (gnc_numeric_equal (*r_amount, value));
g_assert (timespec_equal (rtime, &time));
g_assert_cmpint (rtime->t, ==, time);
g_assert (txn == rtxn);
g_assert (acc == racc);
g_assert (lot == rlot);