static void gom_resource_save_cb (GomAdapter *adapter, gpointer user_data) { GSimpleAsyncResult *simple = user_data; GomResource *resource; gboolean ret; GError *error = NULL; GAsyncQueue *queue; g_return_if_fail(GOM_IS_ADAPTER(adapter)); g_return_if_fail(G_IS_SIMPLE_ASYNC_RESULT(simple)); resource = GOM_RESOURCE(g_async_result_get_source_object(G_ASYNC_RESULT(simple))); g_assert(GOM_IS_RESOURCE(resource)); queue = g_object_get_data(G_OBJECT(simple), "queue"); if (!(ret = gom_resource_do_save(resource, adapter, &error))) { g_simple_async_result_take_error(simple, error); } g_simple_async_result_set_op_res_gboolean(simple, ret); if (!queue) g_simple_async_result_complete_in_idle(simple); else g_async_queue_push(queue, GINT_TO_POINTER(TRUE)); g_object_unref(resource); }
static void test_notnull (void) { GomAdapter *adapter; GomRepository *repository; GList *object_types; ItemResource *item; GError *error = NULL; adapter = gom_adapter_new(); gom_adapter_open_sync(adapter, ":memory:", &error); g_assert_no_error(error); repository = gom_repository_new(adapter); object_types = g_list_prepend(NULL, GINT_TO_POINTER(ITEM_TYPE_RESOURCE)); gom_repository_automatic_migrate_sync(repository, 1, object_types, &error); g_assert_no_error(error); /* Insert an item without a name */ item = g_object_new (ITEM_TYPE_RESOURCE, "repository", repository, "email", "*****@*****.**", NULL); gom_resource_save_sync(GOM_RESOURCE(item), &error); g_assert_error(error, GOM_ERROR, GOM_ERROR_COMMAND_SQLITE); g_assert (strstr (error->message, "NOT NULL") != NULL); g_assert (strstr (error->message, "items.name") != NULL); g_clear_error(&error); g_object_unref(item); /* Try inserting an item without an email */ item = g_object_new (ITEM_TYPE_RESOURCE, "repository", repository, "name", "gom", NULL); gom_resource_save_sync(GOM_RESOURCE(item), &error); g_assert_error(error, GOM_ERROR, GOM_ERROR_COMMAND_SQLITE); g_assert (strstr (error->message, "NOT NULL") != NULL); g_assert (strstr (error->message, "items.email") != NULL); g_clear_error(&error); g_object_unref(item); gom_adapter_close_sync(adapter, &error); g_assert_no_error(error); g_object_unref(repository); g_object_unref(adapter); }
static void pkey_changed_cb (GObject *gobject, GParamSpec *pspec, gpointer user_data) { GomResource *resource = (GomResource *) gobject; /* Did the developer reset the primary key? */ if (!has_primary_key(GOM_RESOURCE(resource))) { resource->priv->is_from_table = FALSE; } }
/** * gom_resource_get_property: * @object: (in): A #GObject. * @prop_id: (in): The property identifier. * @value: (out): The given property. * @pspec: (in): A #ParamSpec. * * Get a given #GObject property. */ static void gom_resource_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { GomResource *resource = GOM_RESOURCE(object); switch (prop_id) { case PROP_REPOSITORY: g_value_set_object(value, gom_resource_get_repository(resource)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); } }
static void news_sync_task_reduce_categories (NewsSyncTask *task, GomCollection *categories) { NewsCategory *category; GomCondition *cond = NULL; GomResource *resource; GomProperty *name_prop = NULL; GPtrArray *array; gchar *name; gint i; g_assert(NEWS_IS_SYNC_TASK(task)); g_assert(GOM_IS_COLLECTION(categories)); if ((array = gom_collection_get_additions(categories))) { for (i = 0; i < array->len; i++) { resource = g_ptr_array_index(array, i); if (!name_prop) { name_prop = gom_resource_find_property(resource, "name"); g_assert(name_prop); } g_object_get(resource, "name", &name, NULL); if (name) { cond = gom_condition_equal(name_prop, name); } if (cond) { category = gom_resource_find_first(NEWS_TYPE_CATEGORY, task->priv->adapter, cond, NULL); if (category) { gom_resource_merge(resource, GOM_RESOURCE(category)); g_object_set(resource, "is-new", FALSE, NULL); g_clear_object(&category); } gom_condition_unref(cond); } g_free(name); } } }
static void news_sync_task_reduce_links (NewsSyncTask *task, GomCollection *links) { GomCondition *cond = NULL; GomResource *resource; GomProperty *href_prop = NULL; GPtrArray *array; NewsLink *link_; gchar *href; gint i; g_assert(NEWS_IS_SYNC_TASK(task)); g_assert(GOM_IS_COLLECTION(links)); if ((array = gom_collection_get_additions(links))) { for (i = 0; i < array->len; i++) { resource = g_ptr_array_index(array, i); if (!href_prop) { href_prop = gom_resource_find_property(resource, "href"); g_assert(href_prop); } g_object_get(resource, "href", &href, NULL); if (href) { cond = gom_condition_equal(href_prop, href); } if (cond) { link_ = gom_resource_find_first(NEWS_TYPE_LINK, task->priv->adapter, cond, NULL); if (link_) { gom_resource_merge(resource, GOM_RESOURCE(link_)); g_object_set(resource, "is-new", FALSE, NULL); g_clear_object(&link_); } gom_condition_unref(cond); } g_free(href); } } }
static void news_sync_task_parse_cb (GObject *object, GAsyncResult *result, gpointer user_data) { NewsSyncTaskPrivate *priv; GSimpleAsyncResult *simple = user_data; NewsSyncTask *task; NewsParser *parser = (NewsParser *)object; GError *error = NULL; g_assert(NEWS_IS_PARSER(parser)); g_assert(G_IS_SIMPLE_ASYNC_RESULT(simple)); task = (NewsSyncTask *)g_async_result_get_source_object(G_ASYNC_RESULT(simple)); g_assert(NEWS_IS_SYNC_TASK(task)); priv = task->priv; priv->fraction = 0.666; g_object_notify_by_pspec(G_OBJECT(task), gParamSpecs[PROP_FRACTION]); if (!(priv->feed = news_parser_parse_finish(parser, result, &error))) { g_simple_async_result_take_error(simple, error); g_simple_async_result_complete_in_idle(simple); g_object_unref(simple); return; } if (g_cancellable_is_cancelled(priv->cancellable)) { g_simple_async_result_set_error(simple, NEWS_SYNC_TASK_ERROR, NEWS_SYNC_TASK_ERROR_CANCELLED, _("The task was cancelled.")); g_simple_async_result_complete_in_idle(simple); g_object_unref(simple); return; } news_sync_task_prepare_save(task); gom_adapter_sqlite_begin(GOM_ADAPTER_SQLITE(priv->adapter)); gom_resource_save_async(GOM_RESOURCE(priv->feed), priv->cancellable, news_sync_task_save_cb, simple); }
/** * catch_space_get_objects_async: * @space: (in): A #CatchSpace. * @filter: (in): A #GomFilter. * @callback: (in): A callback to execute upon completion. * @user_data: (in): User data for @callback. * * Fetches the objects found in a space using the filter provided. * @callback is responsible for calling catch_space_get_objects_finish() * to complete the request. */ void catch_space_get_objects_async (CatchSpace *space, GomFilter *filter, GAsyncReadyCallback callback, gpointer user_data) { GSimpleAsyncResult *simple; GomFilter *map_filter; GomFilter *tmp; GValue value = { 0 }; ENTRY; g_return_if_fail(CATCH_IS_SPACE(space)); g_return_if_fail(!filter || GOM_IS_FILTER(filter)); g_return_if_fail(callback != NULL); simple = g_simple_async_result_new(G_OBJECT(space), callback, user_data, catch_space_get_objects_async); g_value_init(&value, G_TYPE_INT64); g_object_get_property(G_OBJECT(space), "local-id", &value); map_filter = gom_filter_new_eq(CATCH_TYPE_SPACE, "local-id", &value); g_value_unset(&value); if (filter) { tmp = map_filter; map_filter = gom_filter_new_and(map_filter, filter); g_object_unref(tmp); } gom_resource_fetch_m2m_async(GOM_RESOURCE(space), CATCH_TYPE_OBJECT, "spaces_objects", map_filter, catch_space_get_objects_cb, simple); EXIT; }
static void news_sync_task_reduce_persons (NewsSyncTask *task, GomCollection *persons) { GomCondition *cond = NULL; GomCondition *cond1 = NULL; GomCondition *cond2 = NULL; GomResource *resource; GomProperty *email_prop = NULL; GomProperty *name_prop = NULL; NewsPerson *person; GPtrArray *array; gchar *name; gchar *email; gint i; g_assert(NEWS_IS_SYNC_TASK(task)); g_assert(GOM_IS_COLLECTION(persons)); if ((array = gom_collection_get_additions(persons))) { for (i = 0; i < array->len; i++) { resource = g_ptr_array_index(array, i); if (!email_prop) { email_prop = gom_resource_find_property(resource, "email"); name_prop = gom_resource_find_property(resource, "name"); } g_object_get(resource, "email", &email, "name", &name, NULL); if (email) { cond1 = gom_condition_equal(email_prop, email); } if (name) { cond2 = gom_condition_equal(name_prop, name); } if (cond1 && cond2) { cond = gom_condition_or(cond1, cond2); gom_condition_unref(cond1); gom_condition_unref(cond2); } else if (cond1) { cond = cond1; } else if (cond2) { cond = cond2; } if (cond) { person = gom_resource_find_first(NEWS_TYPE_PERSON, task->priv->adapter, cond, NULL); if (person) { gom_resource_merge(resource, GOM_RESOURCE(person)); g_object_set(resource, "is-new", FALSE, NULL); g_clear_object(&person); } gom_condition_unref(cond); } g_free(email); g_free(name); } } }
static void news_sync_task_reduce_items (NewsSyncTask *task, GomCollection *items, guint *count) { GomCondition *cond; GomResource *resource; GomProperty *item_id_prop = NULL; GPtrArray *array; NewsItem *item; gchar *item_id; gint i; ENTRY; g_assert(NEWS_IS_SYNC_TASK(task)); g_assert(GOM_IS_COLLECTION(items)); g_assert(count != NULL); if ((array = gom_collection_get_additions(items))) { *count += array->len; for (i = 0; i < array->len; i++) { resource = g_ptr_array_index(array, i); if (!item_id_prop) { item_id_prop = gom_resource_find_property(resource, "item-id"); g_assert(item_id_prop); } g_object_get(resource, "item-id", &item_id, NULL); if (item_id) { cond = gom_condition_equal(item_id_prop, item_id); item = gom_resource_find_first(NEWS_TYPE_ITEM, task->priv->adapter, cond, NULL); if (item) { gom_resource_merge(resource, GOM_RESOURCE(item)); g_object_set(resource, "is-new", FALSE, NULL); g_clear_object(&item); } gom_condition_unref(cond); g_free(item_id); } { //GomCollection *authors; //GomCollection *categories; //GomCollection *contributors; GomCollection *links; g_object_get(resource, //"authors", &authors, //"categories", &categories, //"contributors", &contributors, "links", &links, NULL); //g_assert(authors); //g_assert(categories); //g_assert(contributors); g_assert(links); //news_sync_task_reduce_persons(task, authors, count); //news_sync_task_reduce_persons(task, contributors, count); //news_sync_task_reduce_categories(task, categories, count); news_sync_task_reduce_links(task, links); //g_clear_object(&authors); //g_clear_object(&categories); //g_clear_object(&contributors); g_clear_object(&links); } } } EXIT; }
static void test_unique (void) { GomAdapter *adapter; GomRepository *repository; GList *object_types; ItemResource *item; GomFilter *filter; GValue value = { 0, }; guint id; gchar *name, *email; GError *error = NULL; adapter = gom_adapter_new(); gom_adapter_open_sync(adapter, ":memory:", &error); g_assert_no_error(error); repository = gom_repository_new(adapter); object_types = g_list_prepend(NULL, GINT_TO_POINTER(ITEM_TYPE_RESOURCE)); gom_repository_automatic_migrate_sync(repository, 1, object_types, &error); g_assert_no_error(error); /* Insert an item */ item = g_object_new (ITEM_TYPE_RESOURCE, "repository", repository, "name", "gom", "email", "*****@*****.**", NULL); gom_resource_save_sync(GOM_RESOURCE(item), &error); g_assert_no_error(error); g_object_get(item, "id", &id, NULL); g_object_unref(item); /* Fetch it, to make sure it was saved correctly */ g_value_init(&value, G_TYPE_UINT); g_value_set_uint(&value, id); filter = gom_filter_new_eq(ITEM_TYPE_RESOURCE, "id", &value); g_value_unset(&value); item = ITEM_RESOURCE (gom_repository_find_one_sync(repository, ITEM_TYPE_RESOURCE, filter, &error)); g_assert_no_error(error); g_assert(item); g_object_unref(filter); g_object_get(item, "name", &name, "email", &email, NULL); g_assert_cmpstr(name, ==, "gom"); g_free(name); g_assert_cmpstr(email, ==, "*****@*****.**"); g_free(email); g_object_unref(item); /* Now try inserting a new item with the same name (non UNIQUE column) */ item = g_object_new (ITEM_TYPE_RESOURCE, "repository", repository, "name", "gom", "email", "*****@*****.**", NULL); gom_resource_save_sync(GOM_RESOURCE(item), &error); g_assert_no_error(error); g_object_get(item, "id", &id, NULL); g_object_unref(item); /* Fetch it, to make sure it was saved correctly */ g_value_init(&value, G_TYPE_UINT); g_value_set_uint(&value, id); filter = gom_filter_new_eq(ITEM_TYPE_RESOURCE, "id", &value); g_value_unset(&value); item = ITEM_RESOURCE (gom_repository_find_one_sync(repository, ITEM_TYPE_RESOURCE, filter, &error)); g_assert_no_error(error); g_assert(item); g_object_unref(filter); g_object_get(item, "name", &name, "email", &email, NULL); g_assert_cmpstr(name, ==, "gom"); g_free(name); g_assert_cmpstr(email, ==, "*****@*****.**"); g_free(email); g_object_unref(item); /* And finally try inserting an item with the same email (UNIQUE column) */ item = g_object_new (ITEM_TYPE_RESOURCE, "repository", repository, "name", "gom2", "email", "*****@*****.**", NULL); gom_resource_save_sync(GOM_RESOURCE(item), &error); g_assert_error(error, GOM_ERROR, GOM_ERROR_COMMAND_SQLITE); g_assert (strstr (error->message, "UNIQUE") != NULL); g_assert (strstr (error->message, "items.email") != NULL); g_object_unref(item); g_clear_error(&error); gom_adapter_close_sync(adapter, &error); g_assert_no_error(error); g_object_unref(repository); g_object_unref(adapter); }
static gboolean news_format_rss_read_from_xml (NewsFormatRss *rss, XmlReader *reader, NewsFeed *feed, GError **error) { GHashTable *categories = NULL; GHashTable *persons = NULL; GHashTable *links = NULL; GomAdapter *adapter; gchar *str; ENTRY; g_return_val_if_fail(NEWS_IS_FORMAT_RSS(rss), FALSE); g_return_val_if_fail(XML_IS_READER(reader), FALSE); g_return_val_if_fail(NEWS_IS_FEED(feed), FALSE); adapter = news_format_get_adapter(NEWS_FORMAT(rss)); g_assert(adapter); skip: if (!xml_reader_read_to_next(reader) || !xml_reader_is_a(reader, "rss")) { if (xml_reader_is_a(reader, "xml-stylesheet") || xml_reader_is_a(reader, "#comment")) { goto skip; } RETURN_ERROR; } if (!xml_reader_is_a_local(reader, "rss")) { RETURN_ERROR; } if ((str = xml_reader_get_attribute(reader, "version"))) { if (!!g_strcmp0(str, "2.0")) { g_set_error(error, XML_READER_ERROR, XML_READER_ERROR_INVALID, _("RSS Version \"%s\" is not supported."), str); g_free(str); RETURN(FALSE); } g_free(str); } if (!xml_reader_read_start_element(reader, "channel")) { RETURN_ERROR; } persons = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_object_unref); categories = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_object_unref); links = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_object_unref); xml_reader_read(reader); for (xml_reader_read_to_next(reader); xml_reader_get_node_type(reader) != XML_READER_TYPE_END_ELEMENT; xml_reader_read_to_next(reader)) { if ((xml_reader_get_node_type(reader) != XML_READER_TYPE_ELEMENT) || rss->priv->error) { g_hash_table_destroy(categories); g_hash_table_destroy(persons); g_hash_table_destroy(links); RETURN_ERROR; } if (xml_reader_is_a_local(reader, "title")) { str = xml_reader_read_string(reader); g_object_set(feed, "title", str, NULL); g_free(str); } else if (xml_reader_is_a_local(reader, "link")) { GomCollection *collection; NewsLink *link_; g_object_get(feed, "links", &collection, NULL); if ((link_ = news_format_rss_read_link(rss, reader, links))) { gom_collection_add_resource(collection, GOM_RESOURCE(link_)); g_object_unref(link_); } g_object_unref(collection); } else if (xml_reader_is_a_local(reader, "description")) { str = xml_reader_read_string(reader); g_object_set(feed, "description", str, NULL); g_free(str); xml_reader_read_end_element(reader); } else if (xml_reader_is_a_local(reader, "language")) { str = xml_reader_read_string(reader); g_object_set(feed, "language", str, NULL); g_free(str); } else if (xml_reader_is_a_local(reader, "copyright")) { str = xml_reader_read_string(reader); g_object_set(feed, "copyright", str, NULL); g_free(str); } else if (xml_reader_is_a_local(reader, "managingEditor")) { GomCollection *collection; NewsPerson *person; g_object_get(feed, "authors", &collection, NULL); if ((person = news_format_rss_read_person(rss, reader, persons))) { gom_collection_add_resource(collection, GOM_RESOURCE(person)); g_object_unref(person); } g_object_unref(collection); } else if (xml_reader_is_a_local(reader, "pubDate") || xml_reader_is_a_local(reader, "lastBuildDate")) { GDateTime *dt; GTimeVal tv; if ((str = xml_reader_read_string(reader))) { if (g_time_val_from_iso8601(str, &tv)) { if ((dt = g_date_time_new_from_timeval_utc(&tv))) { g_object_set(feed, "last-updated-at", dt, NULL); g_date_time_unref(dt); } } g_free(str); } } else if (xml_reader_is_a_local(reader, "category")) { GomCollection *collection; NewsCategory *category; g_object_get(feed, "categories", &collection, NULL); if ((category = news_format_rss_read_category(rss, reader, categories))) { gom_collection_add_resource(collection, GOM_RESOURCE(category)); g_object_unref(category); } g_object_unref(collection); } else if (xml_reader_is_a_local(reader, "generator")) { str = xml_reader_read_string(reader); g_object_set(feed, "generator", str, NULL); g_free(str); } else if (xml_reader_is_a_local(reader, "item")) { GomCollection *collection; NewsItem *item; g_object_get(feed, "items", &collection, NULL); item = g_object_new(NEWS_TYPE_ITEM, "adapter", adapter, "is-new", TRUE, NULL); if (news_format_rss_read_item(rss, reader, item, persons, categories, links)) { gom_collection_add_resource(collection, GOM_RESOURCE(item)); } g_object_unref(item); g_object_unref(collection); } } g_hash_table_destroy(categories); g_hash_table_destroy(links); g_hash_table_destroy(persons); RETURN(TRUE); }
static gboolean news_format_rss_read_item (NewsFormatRss *rss, XmlReader *reader, NewsItem *item, GHashTable *persons, GHashTable *categories, GHashTable *links) { gchar *str; xml_reader_read(reader); for (; xml_reader_get_node_type(reader) != XML_READER_TYPE_END_ELEMENT; xml_reader_read_to_next(reader)) { if (rss->priv->error) { break; } if (xml_reader_is_a_local(reader, "author")) { GomCollection *collection; NewsPerson *person; g_object_get(item, "authors", &collection, NULL); if ((person = news_format_rss_read_person(rss, reader, persons))) { gom_collection_add_resource(collection, GOM_RESOURCE(person)); g_object_unref(person); } g_object_unref(collection); } else if (xml_reader_is_a_local(reader, "category")) { GomCollection *collection; NewsCategory *category; g_object_get(item, "categories", &collection, NULL); if ((category = news_format_rss_read_category(rss, reader, categories))) { gom_collection_add_resource(collection, GOM_RESOURCE(category)); g_object_unref(category); } g_object_unref(collection); } else if (xml_reader_is_a_local(reader, "link")) { GomCollection *collection; NewsLink *link_; g_object_get(item, "links", &collection, NULL); if ((link_ = news_format_rss_read_link(rss, reader, links))) { gom_collection_add_resource(collection, GOM_RESOURCE(link_)); g_object_unref(link_); } g_object_unref(collection); } else if (xml_reader_is_a_local(reader, "guid")) { str = xml_reader_read_string(reader); g_object_set(item, "item-id", str, NULL); g_free(str); } else if (xml_reader_is_a_local(reader, "description")) { str = xml_reader_read_inner_xml(reader); g_object_set(item, "summary", str, NULL); g_free(str); xml_reader_read_end_element(reader); } else if (xml_reader_is_a_local(reader, "title")) { str = xml_reader_read_string(reader); g_object_set(item, "title", str, NULL); g_free(str); } else if (xml_reader_is_a_local(reader, "pubDate")) { GDateTime *dt; GTimeVal tv; if ((str = xml_reader_read_string(reader))) { if (g_time_val_from_iso8601(str, &tv)) { if ((dt = g_date_time_new_from_timeval_utc(&tv))) { g_object_set(item, "last-updated-at", dt, NULL); g_date_time_unref(dt); } } g_free(str); } } else if (xml_reader_is_a_local(reader, "source")) { /* * TODO: */ } } xml_reader_read_end_element(reader); return TRUE; }
static void gom_resource_fetch_m2m_cb (GomAdapter *adapter, gpointer user_data) { GSimpleAsyncResult *simple = user_data; GomCommandBuilder *builder = NULL; GomResourceGroup *group; GomRepository *repository; const gchar *m2m_table; GomResource *resource; GomCommand *command = NULL; GomCursor *cursor = NULL; GomFilter *filter = NULL; GError *error = NULL; guint count = 0; GType resource_type; g_return_if_fail(GOM_IS_ADAPTER(adapter)); g_return_if_fail(G_IS_SIMPLE_ASYNC_RESULT(simple)); m2m_table = g_object_get_data(G_OBJECT(simple), "m2m-table"); resource_type = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(simple), "resource-type")); filter = g_object_get_data(G_OBJECT(simple), "filter"); resource = GOM_RESOURCE(g_async_result_get_source_object(G_ASYNC_RESULT(simple))); repository = gom_resource_get_repository(resource); g_assert(GOM_IS_RESOURCE(resource)); g_assert(m2m_table); g_assert(g_type_is_a(resource_type, GOM_TYPE_RESOURCE)); g_assert(!filter || GOM_IS_FILTER(filter)); g_assert(GOM_IS_REPOSITORY(repository)); builder = g_object_new(GOM_TYPE_COMMAND_BUILDER, "adapter", adapter, "filter", filter, "resource-type", resource_type, "m2m-table", m2m_table, "m2m-type", G_TYPE_FROM_INSTANCE(resource), NULL); command = gom_command_builder_build_count(builder); if (!gom_command_execute(command, &cursor, &error)) { g_simple_async_result_take_error(simple, error); goto out; } if (!gom_cursor_next(cursor)) { g_simple_async_result_set_error(simple, GOM_ERROR, GOM_ERROR_RESOURCE_CURSOR, _("No result was returned from the cursor.")); goto out; } count = gom_cursor_get_column_int64(cursor, 0); group = g_object_new(GOM_TYPE_RESOURCE_GROUP, "count", count, "filter", filter, "m2m-table", m2m_table, "m2m-type", G_TYPE_FROM_INSTANCE(resource), "repository", repository, "resource-type", resource_type, NULL); g_simple_async_result_set_op_res_gpointer(simple, group, g_object_unref); out: g_object_unref(resource); g_clear_object(&command); g_clear_object(&cursor); g_clear_object(&builder); g_simple_async_result_complete_in_idle(simple); g_object_unref(simple); }