QOF  0.7.5
qof-sqlite.c File Reference

Public interface of qof-backend-sqlite. More...

#include "config.h"
#include <errno.h>
#include <stdlib.h>
#include <time.h>
#include <glib/gstdio.h>
#include <sqlite.h>
#include <glib.h>
#include <libintl.h>
#include "qof.h"

Go to the source code of this file.

Macros

#define _(String)   dgettext (GETTEXT_PACKAGE, String)
#define ACCESS_METHOD   "sqlite"
#define PRIORITY_HIGH   9
#define PRIORITY_STANDARD   5
#define PRIORITY_LOW   0
#define QSQL_ERROR   -1
#define QSQL_KVP_TABLE   "sqlite_kvp"
#define END_DB_VERSION   " dbversion int );"

Enumerations

enum  QsqlStatementType {
  SQL_NONE = 0, SQL_CREATE, SQL_LOAD, SQL_WRITE,
  SQL_INSERT, SQL_DELETE, SQL_UPDATE
}

Functions

static gchar * add_to_sql (gchar *sql_str, const gchar *add)
static QofIdTypeConst kvp_value_to_qof_type_helper (KvpValueType n)
 Map a KvpValue to a QofIdType.
static KvpValueType sql_to_kvp_helper (const gchar *type_string)
KvpValuestring_to_kvp_value (const gchar *content, KvpValueType type)
 Convert a string value into KvpValue.
static void kvpvalue_to_sql (const gchar *key, KvpValue *val, gpointer builder)
static gchar * string_param_to_sql (QofParam *param)
static void create_param_list (QofParam *param, gpointer builder)
 list just the parameter names
static void create_each_param (QofParam *param, gpointer builder)
static void delete_event (QofEntity *ent, QofEventId event_type, gpointer handler_data, gpointer event_data)
 use the new-style event handlers for insert and update insert runs after QOF_EVENT_CREATE delete runs before QOF_EVENT_DESTROY
static void create_event (QofEntity *ent, QofEventId event_type, gpointer handler_data, gpointer event_data)
static void qsql_modify (QofBackend *be, QofInstance *inst)
static gint record_foreach (gpointer builder, gint col_num, gchar **strings, gchar **columnNames)
static void string_param_foreach (QofParam *param, gpointer builder)
static void update_param_foreach (QofParam *param, gpointer builder)
static void update_dirty (gpointer value, gpointer builder)
static gint create_dirty_list (gpointer builder, gint col_num, gchar **strings, gchar **columnNames)
static gint mark_entity (gpointer builder, gint col_num, gchar **strings, gchar **columnNames)
static void qsql_create (QofBackend *be, QofInstance *inst)
static void check_state (QofEntity *ent, gpointer builder)
static gint build_kvp_table (gpointer builder, gint col_num, gchar **strings, gchar **columnNames)
 chekc kvp data once per record
static void qsql_load_kvp (QSQLiteBackend *qsql_be)
static void qsql_class_foreach (QofObject *obj, gpointer data)
static void qsql_backend_createdb (QofBackend *be, QofSession *session)
static void qsql_backend_opendb (QofBackend *be, QofSession *session)
static void qsqlite_session_begin (QofBackend *be, QofSession *session, const gchar *book_path, gboolean ignore_lock, gboolean create_if_nonexistent)
static void qsqlite_db_load (QofBackend *be, QofBook *book)
static void qsqlite_write_db (QofBackend *be, QofBook *book)
static gboolean qsql_determine_file_type (const gchar *path)
static void qsqlite_session_end (QofBackend *be)
static void qsqlite_destroy_backend (QofBackend *be)
static void qsql_provider_free (QofBackendProvider *prov)
static QofBackendqsql_backend_new (void)
 Starts the backend and creates the context.
void qof_sqlite_provider_init (void)
 Initialises the SQLite backend.

Variables

static QofLogModule log_module = QOF_MOD_SQLITE
static gboolean loading = FALSE

Detailed Description

Public interface of qof-backend-sqlite.

Author
Copyright 2006-2007 Neil Williams linux.nosp@m.@cod.nosp@m.ehelp.nosp@m..co..nosp@m.uk

Definition in file qof-sqlite.c.

Macro Definition Documentation

#define PRIORITY_HIGH   9

Indicates an item with high priority.

Definition at line 43 of file qof-sqlite.c.

#define PRIORITY_LOW   0

Indicates a low priority item.

Definition at line 47 of file qof-sqlite.c.

#define PRIORITY_STANDARD   5

Indicates an item with default priority.

Definition at line 45 of file qof-sqlite.c.

#define QSQL_ERROR   -1

Indicate an error to sqlite

Definition at line 49 of file qof-sqlite.c.

#define QSQL_KVP_TABLE   "sqlite_kvp"

One KVP table per file for all instances.

Definition at line 51 of file qof-sqlite.c.

Enumeration Type Documentation

Enumerator:
SQL_NONE 

no operation defined. init value.

SQL_CREATE 

Create a new database

SQL_LOAD 

Load all data from existing database.

SQL_WRITE 

Write / sync all data to the database.

SQL_INSERT 

Run a single INSERT statement.

SQL_DELETE 

Run a single DELETE statement.

SQL_UPDATE 

Run a single UPDATE statement.

Definition at line 58 of file qof-sqlite.c.

Function Documentation

static gint build_kvp_table ( gpointer  builder,
gint  col_num,
gchar **  strings,
gchar **  columnNames 
)
static

chekc kvp data once per record

creates a new KvpFrame as data for a GHashTable with the guid as key

Todo:
improve error checking support in case the SQLite data is tweaked manually.

Definition at line 1076 of file qof-sqlite.c.

{
QSQLiteBackend *qsql_be;
struct QsqlBuilder *qb;
KvpFrame *frame;
KvpValue *value;
glong max;
gchar *tail;
g_return_val_if_fail (builder, QSQL_ERROR);
qb = (struct QsqlBuilder *) builder;
max = 0;
qsql_be = qb->qsql_be;
g_return_val_if_fail ((col_num < 4), QSQL_ERROR);
g_return_val_if_fail (strings[2], QSQL_ERROR);
frame = kvp_frame_new ();
/* columnNames = fields strings = values
[0]=kvp_id, [1]=guid, [2]=path, [3]=type, [4]=value
get type from type_string */
type = sql_to_kvp_helper (strings[3]);
if (type == 0)
{
PERR (" invalid type returned from kvp table");
return QSQL_ERROR;
}
/* use the type to make a KvpValue from value */
value = string_to_kvp_value (strings[4], type);
if (!value)
{
PERR (" invalid KvpValue for type: %d", type);
return QSQL_ERROR;
}
/* add the KvpValue to the frame at path */
kvp_frame_set_value (frame, strings[2], value);
/* index the frame under the entity GUID */
g_hash_table_insert (qsql_be->kvp_table, strings[1], frame);
/* index the guid under the kvp_id */
g_hash_table_insert (qsql_be->kvp_id, strings[0], strings[1]);
errno = 0;
max = strtol (strings[0], &tail, 0);
if (errno == 0)
{
qsql_be->index = (max > qsql_be->index) ? max : qsql_be->index;
}
return SQLITE_OK;
}
static void create_each_param ( QofParam param,
gpointer  builder 
)
static

create the sql for each parameter

Bug:
will need to use QofEntityReference here if partial books are actually to be supported.

Definition at line 447 of file qof-sqlite.c.

{
gchar *value;
struct QsqlBuilder *qb;
qb = (struct QsqlBuilder *) builder;
GList *references;
/* avoid creating database fields for calculated values */
if (!param->param_setfcn)
return;
/* avoid setting KVP even if a param_setfcn has been set
because a QofSetterFunc for KVP is quite pointless. */
if (0 == safe_strcmp (param->param_type, QOF_TYPE_KVP))
return;
references = qof_class_get_referenceList (qb->ent->e_type);
if (g_list_find (references, param))
{
e = param->param_getfcn (qb->ent, param);
value = g_strnfill (GUID_ENCODING_LENGTH + 1, ' ');
PINFO (" ref=%p GUID=%s", e, value);
}
else
value = qof_util_param_to_string (qb->ent, param);
if (value)
g_strescape (value, NULL);
if (!value)
value = g_strdup ("");
if (!g_str_has_suffix (qb->sql_str, "("))
{
gchar *val;
val = g_strconcat (", \"", value, "\"", NULL);
qb->sql_str = add_to_sql (qb->sql_str, val);
g_free (val);
}
else
{
gchar *val;
val = g_strconcat ("\"", value, "\"", NULL);
qb->sql_str = add_to_sql (qb->sql_str, val);
g_free (val);
}
}
static void create_event ( QofEntity ent,
QofEventId  event_type,
gpointer  handler_data,
gpointer  event_data 
)
static

receives QSQLiteBackend, passes on QsqlBuilder

Definition at line 548 of file qof-sqlite.c.

{
struct QsqlBuilder qb;
QSQLiteBackend *qsql_be;
gchar *gstr;
KvpFrame *slots;
qsql_be = (QSQLiteBackend *) handler_data;
be = (QofBackend *) qsql_be;
if (!ent)
return;
if (0 == safe_strcmp (ent->e_type, QOF_ID_BOOK))
return;
if (!qof_class_is_registered (ent->e_type))
return;
switch (event_type)
{
{
gchar *tmp;
ENTER (" create:%s", ent->e_type);
gstr = g_strnfill (GUID_ENCODING_LENGTH + 1, ' ');
ent), gstr);
DEBUG (" guid=%s", gstr);
qb.ent = ent;
qb.sql_str =
g_strdup_printf ("INSERT into %s (guid ", ent->e_type);
tmp = g_strconcat (") VALUES (\"", gstr, "\" ", NULL);
qb.sql_str = add_to_sql (qb.sql_str, tmp);
g_free (tmp);
qb.sql_str = add_to_sql (qb.sql_str, ");");
DEBUG (" sql_str=%s", qb.sql_str);
if (sqlite_exec (qsql_be->sqliteh, qb.sql_str,
NULL, &qb, &qsql_be->err) != SQLITE_OK)
{
qof_error_set_be (be, qsql_be->err_insert);
qsql_be->error = TRUE;
PERR (" error on create_event:%s", qsql_be->err);
}
else
{
((QofInstance *) ent)->dirty = FALSE;
qsql_be->error = FALSE;
g_free (qb.sql_str);
g_free (gstr);
LEAVE (" ");
break;
}
/* insert sqlite_kvp data */
if (slots)
{
/* id, guid, path, type, value */
qb.sql_str = g_strconcat ("INSERT into ", QSQL_KVP_TABLE,
" (kvp_id \"", gstr, "\", ", NULL);
qb.sql_str = add_to_sql (qb.sql_str, END_DB_VERSION);
if (sqlite_exec (qsql_be->sqliteh, qb.sql_str,
NULL, &qb, &qsql_be->err) != SQLITE_OK)
{
qof_error_set_be (be, qsql_be->err_insert);
qsql_be->error = TRUE;
PERR (" error on KVP create_event:%s", qsql_be->err);
}
else
{
((QofInstance *) ent)->dirty = FALSE;
qsql_be->error = FALSE;
g_free (qb.sql_str);
g_free (gstr);
LEAVE (" ");
break;
}
}
g_free (qb.sql_str);
g_free (gstr);
LEAVE (" ");
break;
}
default:
break;
}
}
static void create_param_list ( QofParam param,
gpointer  builder 
)
static

list just the parameter names

Note
Must match the number and order of the list of parameter values from create_each_param

Definition at line 419 of file qof-sqlite.c.

{
struct QsqlBuilder *qb;
qb = (struct QsqlBuilder *) builder;
/* avoid creating database fields for calculated values */
if (!param->param_setfcn)
return;
/* avoid setting KVP even if a param_setfcn has been set
because a QofSetterFunc for KVP is quite pointless. */
if (0 == safe_strcmp (param->param_type, QOF_TYPE_KVP))
{
PINFO (" kvp support tag");
return;
}
if (!g_str_has_suffix (qb->sql_str, "("))
{
gchar *add;
add = g_strconcat (", ", param->param_name, NULL);
qb->sql_str = add_to_sql (qb->sql_str, add);
g_free (add);
}
else
qb->sql_str = add_to_sql (qb->sql_str, param->param_name);
}
static void delete_event ( QofEntity ent,
QofEventId  event_type,
gpointer  handler_data,
gpointer  event_data 
)
static

use the new-style event handlers for insert and update insert runs after QOF_EVENT_CREATE delete runs before QOF_EVENT_DESTROY

Todo:
delete records from QSQL_KVP_TABLE with this GUID

Definition at line 499 of file qof-sqlite.c.

{
QSQLiteBackend *qsql_be;
gchar *gstr, *sql_str;
qsql_be = (QSQLiteBackend *) handler_data;
be = (QofBackend *) qsql_be;
if (!ent)
return;
if (0 == safe_strcmp (ent->e_type, QOF_ID_BOOK))
return;
/* do not try to delete if only a QofObject has been loaded. */
if (!qof_class_is_registered (ent->e_type))
return;
switch (event_type)
{
{
ENTER (" %s do_free=%d", ent->e_type,
((QofInstance *) ent)->do_free);
gstr = g_strnfill (GUID_ENCODING_LENGTH + 1, ' ');
sql_str = g_strconcat ("DELETE from ", ent->e_type, " WHERE ",
QOF_TYPE_GUID, "='", gstr, "';", NULL);
DEBUG (" sql_str=%s", sql_str);
if (sqlite_exec (qsql_be->sqliteh, sql_str,
NULL, qsql_be, &qsql_be->err) != SQLITE_OK)
{
qof_error_set_be (be, qsql_be->err_delete);
qsql_be->error = TRUE;
LEAVE (" error on delete:%s", qsql_be->err);
break;
}
/* SELECT kvp_id from QSQL_KVP_TABLE where guid = gstr */
LEAVE (" %d", event_type);
qsql_be->error = FALSE;
g_free (gstr);
break;
}
default:
break;
}
}
static QofIdTypeConst kvp_value_to_qof_type_helper ( KvpValueType  n)
static

Map a KvpValue to a QofIdType.

Todo:
reconcile the duplication with the QSF version

Definition at line 145 of file qof-sqlite.c.

{
switch (n)
{
{
return QOF_TYPE_INT64;
break;
}
{
return QOF_TYPE_DOUBLE;
break;
}
{
return QOF_TYPE_NUMERIC;
break;
}
{
return QOF_TYPE_STRING;
break;
}
{
return QOF_TYPE_GUID;
break;
}
#ifndef QOF_DISABLE_DEPRECATED
{
return QOF_TYPE_DATE;
break;
}
#endif
{
return QOF_TYPE_BOOLEAN;
break;
}
{
return QOF_TYPE_TIME;
break;
}
default:
{
return NULL;
}
}
}
static void kvpvalue_to_sql ( const gchar *  key,
KvpValue val,
gpointer  builder 
)
static

returns the VALUES for INSERT in pre-defined order

Definition at line 316 of file qof-sqlite.c.

{
QSQLiteBackend *qsql_be;
struct QsqlBuilder *qb;
gchar *full_path;
full_path = NULL;
ENTER (" ");
qb = (struct QsqlBuilder *) builder;
qsql_be = qb->qsql_be;
g_return_if_fail (key && val && qsql_be);
n = kvp_value_get_type (val);
switch (n)
{
#ifndef QOF_DISABLE_DEPRECATED
#endif
{
/* ("kvp_id int primary key not null", "guid char(32)", "path mediumtext",
"type mediumtext", "value text", */
qb->sql_str =
g_strdup_printf (" kvp key=%s val=%s type=%s", key,
DEBUG (" %s", qb->sql_str);
qb->has_slots = TRUE;
break;
}
{
break;
}
default:
{
PERR (" unsupported value = %d", kvp_value_get_type (val));
break;
}
}
LEAVE (" %s", qb->sql_str);
}
static QofBackend* qsql_backend_new ( void  )
static

Starts the backend and creates the context.

Note
Take care when handling the main QSQLiteBackend context and the QsqlBuilder context. QSQLiteBackend contains the long-term data, QsqlBuilder the transient. Only QSQLiteBackend is guaranteed to exist at any one time. All functions need to be able to locate the QSQLiteBackend. Functions started from the QofBackend routines or from the event handlers will be passed the QofBackend which can be cast to QSQLiteBackend. Internal functions create a local QsqlBuilder struct and set the QSQLiteBackend pointer before passing a pointer to the QsqlBuilder. Use the qsql_ prefix only for functions that are started from QofBackend and the _event suffix for QofEvent.

Definition at line 1446 of file qof-sqlite.c.

{
QSQLiteBackend *qsql_be;
ENTER (" ");
qsql_be = g_new0 (QSQLiteBackend, 1);
be = (QofBackend *) qsql_be;
qsql_be->kvp_table = g_hash_table_new (g_str_hash, g_str_equal);
qsql_be->kvp_id = g_hash_table_new (g_str_hash, g_str_equal);
qsql_be->dbversion = QOF_OBJECT_VERSION;
qsql_be->stm_type = SQL_NONE;
qsql_be->err_delete =
qof_error_register (_("Unable to delete record."), FALSE);
qsql_be->err_create =
qof_error_register (_("Unable to create record."), FALSE);
qsql_be->err_insert =
qof_error_register (_("Unable to insert a new record."), FALSE);
qsql_be->err_update =
qof_error_register (_("Unable to update existing record."), FALSE);
be->session_begin = qsqlite_session_begin;
be->session_end = qsqlite_session_end;
be->destroy_backend = qsqlite_destroy_backend;
be->load = qsqlite_db_load;
/* begin: create an empty entity if none exists,
even if events are suspended. */
be->begin = qsql_create;
/* commit: write to sqlite, commit undo record. */
be->commit = qsql_modify;
be->rollback = NULL;
/* would need a QofQuery back to QofSqlQuery conversion. */
be->compile_query = NULL;
/* unused */
be->free_query = NULL;
be->run_query = NULL;
be->counter = NULL;
/* The QOF SQLite backend is not multi-user - all QOF users are the same. */
be->events_pending = NULL;
be->process_events = NULL;
be->sync = qsqlite_write_db;
be->load_config = NULL;
be->get_config = NULL;
LEAVE (" ");
return be;
}
static void qsql_class_foreach ( QofObject obj,
gpointer  data 
)
static

receives QSQLiteBackend from QofBackend

Definition at line 1168 of file qof-sqlite.c.

{
struct QsqlBuilder qb;
QSQLiteBackend *qsql_be;
qsql_be = (QSQLiteBackend *) data;
be = (QofBackend *) qsql_be;
qb.qsql_be = qsql_be;
qb.e_type = obj->e_type;
ENTER (" obj_type=%s", qb.e_type);
switch (qsql_be->stm_type)
{
case SQL_NONE:
case SQL_INSERT:
case SQL_DELETE:
case SQL_UPDATE:
{
break;
}
case SQL_CREATE:
{
/* KVP is handled separately */
qb.sql_str =
g_strdup_printf ("CREATE TABLE %s (", obj->e_type);
qof_class_param_foreach (obj->e_type, string_param_foreach,
&qb);
qb.sql_str = add_to_sql (qb.sql_str, END_DB_VERSION);
if (sqlite_exec (qsql_be->sqliteh, qb.sql_str,
NULL, NULL, &qsql_be->err) != SQLITE_OK)
{
qof_error_set_be (be, qsql_be->err_create);
qsql_be->error = TRUE;
PERR (" error on SQL_CREATE:%s", qsql_be->err);
}
g_free (qb.sql_str);
break;
}
case SQL_LOAD:
{
qb.sql_str =
g_strdup_printf ("SELECT * FROM %s;", obj->e_type);
PINFO (" sql=%s", qb.sql_str);
if (sqlite_exec (qsql_be->sqliteh, qb.sql_str,
record_foreach, &qb, &qsql_be->err) != SQLITE_OK)
{
qsql_be->error = TRUE;
PERR (" error on SQL_LOAD:%s", qsql_be->err);
}
break;
}
case SQL_WRITE:
{
if (!qof_book_not_saved (qsql_be->book))
break;
qof_object_foreach (obj->e_type, qsql_be->book, check_state,
&qb);
break;
}
}
LEAVE (" ");
}
static void qsql_load_kvp ( QSQLiteBackend *  qsql_be)
static

only call once per book

Definition at line 1127 of file qof-sqlite.c.

{
struct QsqlBuilder qb;
gint sq_code;
g_return_if_fail (qsql_be);
sq_code = SQLITE_OK;
be = (QofBackend *) qsql_be;
qb.sql_str =
g_strdup_printf ("SELECT kvp_id from %s;", QSQL_KVP_TABLE);
sq_code = sqlite_exec (qsql_be->sqliteh, qb.sql_str, build_kvp_table,
&qb, &qsql_be->err);
/* catch older files without a sqlite_kvp table */
if (sq_code == SQLITE_ERROR)
{
g_free (qb.sql_str);
qb.sql_str =
g_strdup_printf ("CREATE TABLE %s (%s, %s, %s, %s, %s, %s",
QSQL_KVP_TABLE, "kvp_id int primary key not null",
"guid char(32)", "path mediumtext", "type mediumtext",
"value text", END_DB_VERSION);
PINFO (" creating kvp table. sql=%s", qb.sql_str);
if (sqlite_exec (qsql_be->sqliteh, qb.sql_str,
record_foreach, &qb, &qsql_be->err) != SQLITE_OK)
{
qsql_be->error = TRUE;
PERR (" unable to create kvp table:%s", qsql_be->err);
}
}
else if (sq_code != SQLITE_OK)
{
qof_error_set_be (be, qsql_be->err_create);
qsql_be->error = TRUE;
PERR (" error on KVP select:%s:%s:%d", qb.sql_str, qsql_be->err, sq_code);
}
g_free (qb.sql_str);
}
static gint record_foreach ( gpointer  builder,
gint  col_num,
gchar **  strings,
gchar **  columnNames 
)
static
Todo:
need a KVP version to load data into the slots

Definition at line 713 of file qof-sqlite.c.

{
QSQLiteBackend *qsql_be;
struct QsqlBuilder *qb;
const QofParam *param;
QofInstance *inst;
QofEntity *ent;
gint i;
g_return_val_if_fail (builder, QSQL_ERROR);
qb = (struct QsqlBuilder *) builder;
qsql_be = qb->qsql_be;
inst = (QofInstance *) qof_object_new_instance (qb->e_type, qsql_be->book);
ent = &inst->entity;
for (i = 0; i < col_num; i++)
{
/* get param and set as string */
param = qof_class_get_parameter (qb->e_type, columnNames[i]);
if (!param)
continue;
/* set the inst->param entry */
inst->param = param;
if (0 == safe_strcmp (columnNames[i], QOF_TYPE_GUID))
{
GUID *guid;
guid = guid_malloc ();
if (!string_to_guid (strings[i], guid))
{
DEBUG (" set guid failed:%s", strings[i]);
return QSQL_ERROR;
}
qof_entity_set_guid (ent, guid);
}
if (strings[i])
qof_util_param_set_string (ent, param, strings[i]);
}
return SQLITE_OK;
}
static KvpValueType sql_to_kvp_helper ( const gchar *  type_string)
static
Todo:
reconcile the duplication with the QSF version

Definition at line 200 of file qof-sqlite.c.

{
if (0 == safe_strcmp (QOF_TYPE_INT64, type_string))
if (0 == safe_strcmp (QOF_TYPE_DOUBLE, type_string))
if (0 == safe_strcmp (QOF_TYPE_NUMERIC, type_string))
if (0 == safe_strcmp (QOF_TYPE_STRING, type_string))
if (0 == safe_strcmp (QOF_TYPE_GUID, type_string))
return KVP_TYPE_GUID;
#ifndef QOF_DISABLE_DEPRECATED
if (0 == safe_strcmp (QOF_TYPE_DATE, type_string))
#endif
if (0 == safe_strcmp (QOF_TYPE_TIME, type_string))
return KVP_TYPE_TIME;
return 0;
}
KvpValue* string_to_kvp_value ( const gchar *  content,
KvpValueType  type 
)

Convert a string value into KvpValue.

Todo:
reconcile the duplication with the QSF version

Definition at line 223 of file qof-sqlite.c.

{
gchar *tail;
gint64 cm_i64;
gdouble cm_double;
QofNumeric cm_numeric;
GUID *cm_guid;
#ifndef QOF_DISABLE_DEPRECATED
struct tm kvp_time;
time_t kvp_time_t;
Timespec cm_date;
#endif
switch (type)
{
{
errno = 0;
cm_i64 = strtoll (content, &tail, 0);
if (errno == 0)
{
return kvp_value_new_gint64 (cm_i64);
}
break;
}
{
errno = 0;
cm_double = strtod (content, &tail);
if (errno == 0)
return kvp_value_new_double (cm_double);
break;
}
{
qof_numeric_from_string (content, &cm_numeric);
return kvp_value_new_numeric (cm_numeric);
break;
}
{
return kvp_value_new_string (content);
break;
}
{
cm_guid = g_new0 (GUID, 1);
if (TRUE == string_to_guid (content, cm_guid))
return kvp_value_new_guid (cm_guid);
break;
}
{
QofDate *qd;
QofTime *qt;
KvpValue *retval;
if (qd)
{
qt = qof_date_to_qtime (qd);
retval = kvp_value_new_time (qt);
return retval;
}
else
PERR (" failed to parse date");
}
#ifndef QOF_DISABLE_DEPRECATED
{
strptime (content, QOF_UTC_DATE_FORMAT, &kvp_time);
kvp_time_t = mktime (&kvp_time);
timespecFromTime_t (&cm_date, kvp_time_t);
return kvp_value_new_timespec (cm_date);
break;
}
#endif
{
gboolean val;
val = qof_util_bool_to_int (content);
return kvp_value_new_boolean (val);
}
default:
break;
}
return NULL;
}