diff options
90 files changed, 8 insertions, 26396 deletions
diff --git a/docs/reference/libtracker-miner/libtracker-miner-docs.xml b/docs/reference/libtracker-miner/libtracker-miner-docs.xml deleted file mode 100644 index a54ae7482..000000000 --- a/docs/reference/libtracker-miner/libtracker-miner-docs.xml +++ /dev/null @@ -1,115 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE book PUBLIC '-//OASIS//DTD DocBook XML V4.5//EN' - 'http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd' [ - -<!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'"> -<!ENTITY version SYSTEM "version.xml"> -]> -<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude"> - <bookinfo> - <title>Tracker Miner Library Reference Manual</title> - <releaseinfo> - for libtracker-miner &version;. - The latest version of this documentation can be found on-line at - <ulink role="online-location" url="https://developer.gnome.org/libtracker-miner/stable/"> - https://developer.gnome.org/libtracker-miner/stable - </ulink>. - </releaseinfo> - </bookinfo> - - <!-- The Library Overview --> - <xi:include href="overview.xml"/> - - <!-- The API Reference --> - <part id="libtracker-miner-reference"> - <title>Reference</title> - <partintro> - <para> - This section provides the detailed API of the Tracker Miner library. - </para> - </partintro> - - <chapter> - <title>Base abstract miner classes</title> - <xi:include href="xml/tracker-miner-enums.xml"/> - <xi:include href="xml/tracker-miner-object.xml"/> - <xi:include href="xml/tracker-miner-online.xml"/> - <xi:include href="xml/tracker-data-provider.xml"/> - <xi:include href="xml/tracker-indexing-tree.xml"/> - </chapter> - - <chapter> - <title>Miner classes for file system</title> - <xi:include href="xml/tracker-miner-fs.xml"/> - <xi:include href="xml/tracker-file-system.xml"/> - <xi:include href="xml/tracker-file-data-provider.xml"/> - <xi:include href="xml/tracker-file-notifier.xml"/> - <xi:include href="xml/tracker-monitor.xml"/> - <xi:include href="xml/tracker-decorator-fs.xml"/> - <xi:include href="xml/tracker-crawler.xml"/> - <xi:include href="xml/tracker-priority-queue.xml"/> - <xi:include href="xml/tracker-task-pool.xml"/> - <xi:include href="xml/tracker-sparql-buffer.xml"/> - <xi:include href="xml/tracker-utils.xml"/> - </chapter> - - <chapter> - <title>DBus helpers</title> - <xi:include href="xml/tracker-decorator.xml"/> - <xi:include href="xml/tracker-miner-proxy.xml"/> - </chapter> - </part> - - <xi:include href="migrating-1to2.xml"/> - - <index id="api-index-full"> - <title>Index</title> - <xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include> - </index> - <index id="api-index-deprecated" role="deprecated"> - <title>Index of deprecated symbols</title> - <xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include> - </index> - <index id="api-index-0-8" role="0.8"> - <title>Index of new symbols in 0.8</title> - <xi:include href="xml/api-index-0.8.xml"><xi:fallback /></xi:include> - </index> - <index id="api-index-0-10" role="0.10"> - <title>Index of new symbols in 0.10</title> - <xi:include href="xml/api-index-0.10.xml"><xi:fallback /></xi:include> - </index> - <index id="api-index-0-12" role="0.12"> - <title>Index of new symbols in 0.12</title> - <xi:include href="xml/api-index-0.12.xml"><xi:fallback /></xi:include> - </index> - <index id="api-index-0-14" role="0.14"> - <title>Index of new symbols in 0.14</title> - <xi:include href="xml/api-index-0.14.xml"><xi:fallback /></xi:include> - </index> - <index id="api-index-0-18" role="0.18"> - <title>Index of new symbols in 0.18</title> - <xi:include href="xml/api-index-0.18.xml"><xi:fallback /></xi:include> - </index> - <index id="api-index-1-2" role="1.2"> - <title>Index of new symbols in 1.2</title> - <xi:include href="xml/api-index-1.2.xml"><xi:fallback /></xi:include> - </index> - <index id="api-index-1-2-2" role="1.2.2"> - <title>Index of new symbols in 1.2.2</title> - <xi:include href="xml/api-index-1.2.2.xml"><xi:fallback /></xi:include> - </index> - <index id="api-index-1-8" role="1.8"> - <title>Index of new symbols in 1.8</title> - <xi:include href="xml/api-index-1.8.xml"><xi:fallback /></xi:include> - </index> - <index id="api-index-1-10" role="1.10"> - <title>Index of new symbols in 1.10</title> - <xi:include href="xml/api-index-1.10.xml"><xi:fallback /></xi:include> - </index> - <index id="api-index-2-0" role="2.0"> - <title>Index of new symbols in 2.0</title> - <xi:include href="xml/api-index-2.0.xml"><xi:fallback /></xi:include> - </index> - - <xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include> -</book> diff --git a/docs/reference/libtracker-miner/meson.build b/docs/reference/libtracker-miner/meson.build deleted file mode 100644 index 30bcb43b5..000000000 --- a/docs/reference/libtracker-miner/meson.build +++ /dev/null @@ -1,12 +0,0 @@ -version_xml = configure_file(input: 'version.xml.in', - output: 'version.xml', - configuration: conf) - -gnome.gtkdoc('libtracker-miner', - src_dir: minerinc, - main_xml: 'libtracker-miner-docs.xml', - content_files: ['overview.xml', 'migrating-1to2.xml'], - dependencies: tracker_miner_dep, - scan_args: ['--rebuild-sections'], - fixxref_args: fixxref_args, - install: true) diff --git a/docs/reference/libtracker-miner/migrating-1to2.xml b/docs/reference/libtracker-miner/migrating-1to2.xml deleted file mode 100644 index 6538d2a08..000000000 --- a/docs/reference/libtracker-miner/migrating-1to2.xml +++ /dev/null @@ -1,73 +0,0 @@ -<?xml version='1.0'?> - -<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" - "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [ -<!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'"> -]> -<chapter id="tracker-migrating-1-to-2"> - <title>Migrating from libtracker-miner 1.x to 2.0</title> - - <para> - Tracker 2.0 is a new major version, containing some possibly - incompatible changes. Most of the changes are not hard to adapt, - and even unlikely to be a problem if the ported application was - kept up-to-date in its usage of 1.x. - </para> - - <section> - <title>TrackerMiner instances do not implement org.freedesktop.Tracker1.Miner</title> - <para> - TrackerMiner abstract classes have been made useful for situations where - there is a local connection (e.g. no interaction with tracker-store). - In order to expose TrackerMiner implementations through the traditional - org.freedesktop.Tracker1.Miner DBus interface, you must now create a - TrackerMinerProxy for it. - </para> - </section> - - <section> - <title>No TrackerEnumerator</title> - <para> - TrackerDataProvider implementations now use the GFileEnumerator interface - from GLib in order to iterate across a tree of uniquely identified - resources. If you implemented a TrackerEnumerator, it must be converted - into a GFileEnumerator interface implementation. No further instructions - are provided as the API almost matches 1:1. - </para> - </section> - - <section> - <title>No tracker_miner_fs_get_parent_urn()</title> - <para> - Use tracker_miner_fs_get_urn(). - </para> - </section> - - <section> - <title>No tracker_miner_fs_force_recheck()</title> - <para> - Use tracker_indexing_tree_notify_updated(). - </para> - </section> - - <section> - <title>No tracker_miner_fs_force_recheck() or tracker_miner_fs_force_mtime_checking()</title> - <para> - Use tracker_indexing_tree_notify_updated(). - </para> - </section> - - <section> - <title>No tracker_miner_fs_check_directory*()</title> - <para> - Use tracker_indexing_tree_add(). - </para> - </section> - - <section> - <title>No tracker_miner_fs_writeback_notify() and tracker_miner_fs_file_notify()</title> - <para> - You can now use tracker_miner_fs_notify_finish() to notify the end of both operations. - </para> - </section> -</chapter> diff --git a/docs/reference/libtracker-miner/overview.xml b/docs/reference/libtracker-miner/overview.xml deleted file mode 100644 index 5becdcd14..000000000 --- a/docs/reference/libtracker-miner/overview.xml +++ /dev/null @@ -1,52 +0,0 @@ -<?xml version='1.0' encoding="UTF-8"?> - -<part id="tracker-overview"> - <title>Overview</title> - <partintro> - <para> - The libtracker-miner library is the foundation for Tracker data miners, - these miners will extract metadata and insert it in SPARQL form to - a TrackerSparqlConnection. - </para> - <para> - The abstract objects provided by this library implement the data indexing - logic necessary for different data and patterns. They merely provide the - guidelines, SPARQL updates are also possible without a libtracker-miner - object implementation. - </para> - </partintro> - - <chapter id="tracker-overview-compiling"> - <title>Compiling applications</title> - - <para> - To compile applications using libtracker-miner, you - need to tell the compiler where to find the proper header files - and libraries. This is done with the - <application>pkg-config</application> utility. - </para> - - <para> - The following interactive shell session demonstrates how - <application>pkg-config</application> is used (the actual output on - your system may be different): -<programlisting> -$ pkg-config --cflags tracker-miner-2.0 --pthread -I/usr/include/tracker-2.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/tracker-2.0/libtracker-sparql - -$ pkg-config --libs tracker-miner-2.0 --pthread -Wl,--export-dynamic -ltracker-miner-2.0 -ltracker-sparql-2.0 -lgio-2.0 -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lrt -lglib-2.0 - -</programlisting> - </para> - <para> - The simplest way to compile a program is to use the "backticks" - feature of the shell. If you enclose a command in backticks - (<emphasis>not single quotes</emphasis>), then its output will be - substituted into the command line before execution: -<programlisting> - $ cc `pkg-config --cflags --libs tracker-miner-2.0` hello.c -o hello -</programlisting> - </para> - </chapter> -</part> diff --git a/docs/reference/libtracker-miner/version.xml.in b/docs/reference/libtracker-miner/version.xml.in deleted file mode 100644 index c7e1225e2..000000000 --- a/docs/reference/libtracker-miner/version.xml.in +++ /dev/null @@ -1 +0,0 @@ -@TRACKER_VERSION@ diff --git a/docs/reference/libtracker-sparql/migrating-2to3.xml b/docs/reference/libtracker-sparql/migrating-2to3.xml index 282300f89..b9bcfc07f 100644 --- a/docs/reference/libtracker-sparql/migrating-2to3.xml +++ b/docs/reference/libtracker-sparql/migrating-2to3.xml @@ -78,4 +78,12 @@ SELECT ?s { ?s a nfo:FileDataObject } interest. </para> </section> + <section> + <title>No libtracker-miner</title> + <para> + This library offered a too shallow collection of abstract objects + whose sole role is inserting data to Tracker data store. There is + no provided migration path, use TrackerSparqlConnection directly. + </para> + </section> </chapter> diff --git a/docs/reference/meson.build b/docs/reference/meson.build index 314c6c494..882344b81 100644 --- a/docs/reference/meson.build +++ b/docs/reference/meson.build @@ -11,7 +11,6 @@ fixxref_args = [ '--extra-dir=@0@'.format(join_paths(docpath, 'libtracker-sparql')), ] -subdir('libtracker-miner') subdir('libtracker-sparql') subdir('ontology') diff --git a/examples/libtracker-miner/.gitignore b/examples/libtracker-miner/.gitignore deleted file mode 100644 index 8011919fb..000000000 --- a/examples/libtracker-miner/.gitignore +++ /dev/null @@ -1 +0,0 @@ -tracker-miner-test diff --git a/examples/libtracker-miner/meson.build b/examples/libtracker-miner/meson.build deleted file mode 100644 index 460b9c732..000000000 --- a/examples/libtracker-miner/meson.build +++ /dev/null @@ -1,7 +0,0 @@ -sources = [ - 'tracker-miner-test.c', - 'tracker-main.c'] - -executable('tracker-miner-test', sources, - dependencies: [tracker_common_dep, tracker_miner_dep, tracker_sparql_dep] -) diff --git a/examples/libtracker-miner/tracker-main.c b/examples/libtracker-miner/tracker-main.c deleted file mode 100644 index 4be5af31d..000000000 --- a/examples/libtracker-miner/tracker-main.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (C) 2009, Nokia <ivan.frade@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "config.h" - -#include <string.h> -#include <stdlib.h> - -#include <glib.h> - -#include "tracker-miner-test.h" - -static void -miner_finished_cb (TrackerMiner *miner, - gdouble seconds_elapsed, - guint total_directories_found, - guint total_directories_ignored, - guint total_files_found, - guint total_files_ignored, - gpointer user_data) -{ - GMainLoop *main_loop = user_data; - - g_message ("Finished mining in seconds:%f, total directories:%d, total files:%d", - seconds_elapsed, - total_directories_found + total_directories_ignored, - total_files_found + total_files_ignored); - - g_main_loop_quit (main_loop); -} - -static gboolean -miner_start_cb (gpointer user_data) -{ - TrackerMiner *miner = user_data; - - g_message ("Starting miner"); - tracker_miner_start (miner); - - return FALSE; -} - -static gboolean -process_file_cb (TrackerMinerFS *fs, - GFile *file, - GTask *task, - gpointer user_data) -{ - gchar *path; - - path = g_file_get_path (file); - g_print ("** PROCESSING FILE:'%s'\n", path); - g_free (path); - - /* Notify that processing is complete. */ - tracker_miner_fs_notify_finish (fs, task, "", NULL); - - /* Return FALSE here if you ignored the file. */ - return TRUE; -} - -static void -add_directory_path (TrackerMinerFS *fs, - const gchar *path, - gboolean recurse) -{ - TrackerIndexingTree *tree; - TrackerDirectoryFlags flags = 0; - GFile *file; - - if (recurse) - flags |= TRACKER_DIRECTORY_FLAG_RECURSE; - - file = g_file_new_for_path (path); - tree = tracker_miner_fs_get_indexing_tree (fs); - tracker_indexing_tree_add (tree, file, flags); - g_object_unref (file); -} - -static void -add_special_directory (TrackerMinerFS *fs, - GUserDirectory dir, - const char *dir_name, - gboolean recurse) -{ - if (strcmp (g_get_user_special_dir (dir), g_get_home_dir ()) == 0) { - g_message ("User dir %s is set to home directory; ignoring.", dir_name); - } else { - add_directory_path (fs, - g_get_user_special_dir (dir), - recurse); - } -} - -int -main (int argc, char *argv[]) -{ - TrackerMiner *miner; - TrackerIndexingTree *tree; - GMainLoop *main_loop; - - main_loop = g_main_loop_new (NULL, FALSE); - - miner = tracker_miner_test_new ("test"); - - g_signal_connect (TRACKER_MINER_FS (miner), "process-file", - G_CALLBACK (process_file_cb), - NULL); - - tree = tracker_miner_fs_get_indexing_tree (TRACKER_MINER_FS (miner)); - - /* Ignore files that g_file_info_get_is_hidden() tells us are hidden files. */ - tracker_indexing_tree_set_filter_hidden (tree, TRUE); - - /* Ignore special filesystems that definitely shouldn't be indexed */ - /* FIXME: it would be better to avoid based on filesystem type; i.e. avoid - * devtmpfs, sysfs and procfs filesystems. */ - tracker_indexing_tree_add_filter(tree, TRACKER_FILTER_PARENT_DIRECTORY, "/dev"); - tracker_indexing_tree_add_filter(tree, TRACKER_FILTER_PARENT_DIRECTORY, "/proc"); - tracker_indexing_tree_add_filter(tree, TRACKER_FILTER_PARENT_DIRECTORY, "/sys"); - - tracker_indexing_tree_add_filter(tree, TRACKER_FILTER_PARENT_DIRECTORY, g_get_tmp_dir()); - - add_directory_path (TRACKER_MINER_FS (miner), - g_get_home_dir (), - FALSE); - - /* This should be ignored */ - add_directory_path (TRACKER_MINER_FS (miner), - g_get_tmp_dir (), - TRUE); - - add_special_directory (TRACKER_MINER_FS (miner), G_USER_DIRECTORY_PICTURES, "PICTURES", TRUE); - add_special_directory (TRACKER_MINER_FS (miner), G_USER_DIRECTORY_MUSIC, "MUSIC", TRUE); - add_special_directory (TRACKER_MINER_FS (miner), G_USER_DIRECTORY_VIDEOS, "VIDEOS", TRUE); - add_special_directory (TRACKER_MINER_FS (miner), G_USER_DIRECTORY_DOWNLOAD, "DOWNLOAD", TRUE); - add_special_directory (TRACKER_MINER_FS (miner), G_USER_DIRECTORY_DOCUMENTS, "DOCUMENTS", TRUE); - add_special_directory (TRACKER_MINER_FS (miner), G_USER_DIRECTORY_DESKTOP, "DESKTOP", TRUE); - - g_signal_connect (miner, "finished", - G_CALLBACK (miner_finished_cb), - main_loop); - g_timeout_add_seconds (1, miner_start_cb, miner); - - g_main_loop_run (main_loop); - - return EXIT_SUCCESS; -} diff --git a/examples/libtracker-miner/tracker-miner-test.c b/examples/libtracker-miner/tracker-miner-test.c deleted file mode 100644 index 60148d7d6..000000000 --- a/examples/libtracker-miner/tracker-miner-test.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2009, Nokia <ivan.frade@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "config.h" - -#include "tracker-miner-test.h" - -G_DEFINE_TYPE (TrackerMinerTest, tracker_miner_test, TRACKER_TYPE_MINER_FS) - -static void -tracker_miner_test_class_init (TrackerMinerTestClass *klass) -{ -} - -static void -tracker_miner_test_init (TrackerMinerTest *miner) -{ -} - -TrackerMiner * -tracker_miner_test_new (const gchar *name) -{ - return g_initable_new (TRACKER_TYPE_MINER_TEST, - NULL, - NULL, - "name", name, - NULL); -} diff --git a/examples/libtracker-miner/tracker-miner-test.h b/examples/libtracker-miner/tracker-miner-test.h deleted file mode 100644 index 63d4b5963..000000000 --- a/examples/libtracker-miner/tracker-miner-test.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2009, Nokia <ivan.frade@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __TRACKER_MINER_TEST_H__ -#define __TRACKER_MINER_TEST_H__ - -#include <glib-object.h> - -#include <libtracker-miner/tracker-miner.h> - -G_BEGIN_DECLS - -#define TRACKER_TYPE_MINER_TEST (tracker_miner_test_get_type()) -#define TRACKER_MINER_TEST(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_MINER_TEST, TrackerMinerTest)) -#define TRACKER_MINER_TEST_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), TRACKER_TYPE_MINER_TEST, TrackerMinerTestClass)) -#define TRACKER_IS_MINER_TEST(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_MINER_TEST)) -#define TRACKER_IS_MINER_TEST_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), TRACKER_TYPE_MINER_TEST)) -#define TRACKER_MINER_TEST_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_MINER_TEST, TrackerMinerTestClass)) - -typedef struct TrackerMinerTest TrackerMinerTest; -typedef struct TrackerMinerTestClass TrackerMinerTestClass; - -struct TrackerMinerTest { - TrackerMinerFS parent_instance; -}; - -struct TrackerMinerTestClass { - TrackerMinerFSClass parent_class; -}; - -GType tracker_miner_test_get_type (void) G_GNUC_CONST; -TrackerMiner * tracker_miner_test_new (const gchar *name); - -G_END_DECLS - -#endif /* __TRACKER_MINER_TEST_H__ */ diff --git a/examples/meson.build b/examples/meson.build index 6ab29f9c5..f788edc7d 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -1,2 +1 @@ -subdir('libtracker-miner') subdir('libtracker-sparql') diff --git a/src/libtracker-miner/.gitignore b/src/libtracker-miner/.gitignore deleted file mode 100644 index 4664a2c8c..000000000 --- a/src/libtracker-miner/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -tracker-miner-*.deps -tracker-miner-*.vapi -tracker-miner-web-full.xml -tracker-miner-enum-types.c -tracker-miner-enum-types.h -*.pc diff --git a/src/libtracker-miner/COPYING.LIB b/src/libtracker-miner/COPYING.LIB deleted file mode 100644 index 2d2d780e6..000000000 --- a/src/libtracker-miner/COPYING.LIB +++ /dev/null @@ -1,510 +0,0 @@ - - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations -below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it -becomes a de-facto standard. To achieve this, non-free programs must -be allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control -compilation and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at least - three years, to give the same user the materials specified in - Subsection 6a, above, for a charge no more than the cost of - performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply, and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License -may add an explicit geographical distribution limitation excluding those -countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms -of the ordinary General Public License). - - To apply these terms, attach the following notices to the library. -It is safest to attach them to the start of each source file to most -effectively convey the exclusion of warranty; and each file should -have at least the "copyright" line and a pointer to where the full -notice is found. - - - <one line to give the library's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or -your school, if any, to sign a "copyright disclaimer" for the library, -if necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James - Random Hacker. - - <signature of Ty Coon>, 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - diff --git a/src/libtracker-miner/Makefile-shared-sources.decl b/src/libtracker-miner/Makefile-shared-sources.decl deleted file mode 100644 index 702885e4e..000000000 --- a/src/libtracker-miner/Makefile-shared-sources.decl +++ /dev/null @@ -1,21 +0,0 @@ - -# Includes sources that will be shared with the -# testers in test/libtracker-miner - -libtracker_miner_monitor_sources = \ - $(top_srcdir)/src/libtracker-miner/tracker-monitor.c - -libtracker_miner_monitor_headers = \ - $(top_srcdir)/src/libtracker-miner/tracker-monitor.h - -libtracker_miner_file_system_sources = \ - $(top_srcdir)/src/libtracker-miner/tracker-file-system.c - -libtracker_miner_file_system_headers = \ - $(top_srcdir)/src/libtracker-miner/tracker-file-system.h - -libtracker_miner_crawler_sources = \ - $(top_srcdir)/src/libtracker-miner/tracker-crawler.c - -libtracker_miner_crawler_headers = \ - $(top_srcdir)/src/libtracker-miner/tracker-crawler.h diff --git a/src/libtracker-miner/TrackerMiner-1.0.metadata b/src/libtracker-miner/TrackerMiner-1.0.metadata deleted file mode 100644 index 670bf1973..000000000 --- a/src/libtracker-miner/TrackerMiner-1.0.metadata +++ /dev/null @@ -1,18 +0,0 @@ -*.*.cancellable#parameter nullable default=null - -DecoratorInfo - .get_sparql type="Tracker.Sparql.Builder" - -Miner - .get_connection type="Tracker.Sparql.Connection" - .progress#virtual_method skip - -MinerFS - .finished_root#virtual_method skip - .process_file.builder type="Tracker.Sparql.Builder" - .process_file_attributes.builder type="Tracker.Sparql.Builder" - .writeback_file#method skip - -DecoratorError errordomain -MinerError errordomain -MinerFSError errordomain diff --git a/src/libtracker-miner/meson.build b/src/libtracker-miner/meson.build deleted file mode 100644 index 53e230013..000000000 --- a/src/libtracker-miner/meson.build +++ /dev/null @@ -1,117 +0,0 @@ -miner_enums = gnome.mkenums('tracker-miner-enum-types', - sources: 'tracker-miner-enums.h', - c_template: 'tracker-miner-enum-types.c.template', - h_template: 'tracker-miner-enum-types.h.template', - install_header: true, - install_dir: join_paths(get_option('includedir'), 'tracker-@0@'.format(tracker_api_version), 'libtracker-miner'), -) - -private_sources = [ - 'tracker-crawler.c', - 'tracker-file-data-provider.c', - 'tracker-file-notifier.c', - 'tracker-file-system.c', - 'tracker-monitor.c', - 'tracker-priority-queue.c', - 'tracker-task-pool.c', - 'tracker-sparql-buffer.c', - 'tracker-utils.c'] - -miner_headers = [ - 'tracker-miner-online.h', - 'tracker-data-provider.h', - 'tracker-indexing-tree.h', - 'tracker-decorator-fs.h', - 'tracker-miner-fs.h', - 'tracker-miner-object.h', - 'tracker-miner-proxy.h', - 'tracker-decorator.h', - 'tracker-miner-enums.h', - 'tracker-miner.h', -] - -miner_sources = ( - ['tracker-data-provider.c', - 'tracker-decorator.c', - 'tracker-decorator-fs.c', - 'tracker-indexing-tree.c', - 'tracker-miner-object.c', - 'tracker-miner-online.c', - 'tracker-miner-proxy.c', - 'tracker-miner-fs.c']) - -libtracker_miner_private = static_library( - 'tracker-miner-private', - miner_enums[0], miner_enums[1], private_sources, - dependencies: [tracker_common_dep, tracker_sparql_dep], - c_args: tracker_c_args, -) - -tracker_miner_dependencies = [] -if have_network_manager - tracker_miner_dependencies += network_manager -endif - -mapfile = 'tracker-miner-2.map' -vflag = '-Wl,--version-script,@0@/@1@'.format(meson.current_source_dir(), mapfile) - -libtracker_miner = library( - 'tracker-miner-' + tracker_api_version, - miner_enums[0], miner_enums[1], miner_sources, - c_args: tracker_c_args, - soversion: soversion, - version: libversion, - install: true, - install_rpath: tracker_internal_libs_dir, - # This doesn't depend on tracker_common_dep because of - # https://github.com/mesonbuild/meson/issues/671 - include_directories: [commoninc, configinc, srcinc], - dependencies: [tracker_sparql_dep] + tracker_miner_dependencies, - link_args: vflag, - link_with: [libtracker_miner_private], -) - -minerinc = include_directories('.') - -tracker_miner_dep = declare_dependency( - sources: miner_enums[1], - link_with: libtracker_miner, - include_directories: include_directories('.') -) - -tracker_miner_gir = gnome.generate_gir(libtracker_miner, - sources: miner_sources + miner_headers, - nsversion: tracker_api_version, - namespace: 'TrackerMiner', - identifier_prefix: 'Tracker', - symbol_prefix: 'tracker', - # FIXME: also depends on Tracker-2.0.gir (output of libtracker-sparql) - # but we can't currently access that from the Vala target - includes : ['GLib-2.0', 'GObject-2.0', 'Gio-2.0' ], - install: true, - extra_args: tracker_c_args + [ - '--c-include=libtracker-miner/tracker-miner.h', - '-DTRACKER_COMPILATION', - ]) - -gnome.generate_vapi( - 'tracker-miner-' + tracker_api_version, - sources : tracker_miner_gir[0], - packages : 'gio-2.0', - install : true, - ) - -pkg.generate(libtracker_miner, - description: 'A library to develop tracker data miners', - requires: [libtracker_sparql], - subdirs: 'tracker-' + tracker_api_version, - variables: [ - 'exec_prefix=${prefix}' - ], -) - -install_headers(miner_headers, subdir: 'tracker-@0@/libtracker-miner'.format(tracker_api_version)) - -install_data( - 'tracker-miner.xml', - install_dir: join_paths(get_option('prefix'), get_option('datadir'), 'tracker')) diff --git a/src/libtracker-miner/tracker-crawler.c b/src/libtracker-miner/tracker-crawler.c deleted file mode 100644 index bfad387c6..000000000 --- a/src/libtracker-miner/tracker-crawler.c +++ /dev/null @@ -1,1274 +0,0 @@ -/* - * Copyright (C) 2009, Nokia <ivan.frade@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "config.h" - -#include "tracker-crawler.h" -#include "tracker-file-data-provider.h" -#include "tracker-miner-enums.h" -#include "tracker-miner-enum-types.h" -#include "tracker-utils.h" - -#define FILE_ATTRIBUTES \ - G_FILE_ATTRIBUTE_STANDARD_NAME "," \ - G_FILE_ATTRIBUTE_STANDARD_TYPE - -#define FILES_QUEUE_PROCESS_INTERVAL 2000 -#define FILES_QUEUE_PROCESS_MAX 5000 - -/* This is the number of files to be called back with from GIO at a - * time so we don't get called back for every file. - */ -#define FILES_GROUP_SIZE 100 - -#define MAX_SIMULTANEOUS_ITEMS 64 - -typedef struct TrackerCrawlerPrivate TrackerCrawlerPrivate; -typedef struct DirectoryChildData DirectoryChildData; -typedef struct DirectoryProcessingData DirectoryProcessingData; -typedef struct DirectoryRootInfo DirectoryRootInfo; - -typedef struct { - TrackerCrawler *crawler; - GFileEnumerator *enumerator; - DirectoryRootInfo *root_info; - DirectoryProcessingData *dir_info; - GFile *dir_file; - GList *files; -} DataProviderData; - -struct DirectoryChildData { - GFile *child; - gboolean is_dir; -}; - -struct DirectoryProcessingData { - GNode *node; - GSList *children; - guint was_inspected : 1; - guint ignored_by_content : 1; -}; - -struct DirectoryRootInfo { - GFile *directory; - GNode *tree; - - GQueue *directory_processing_queue; - - TrackerDirectoryFlags flags; - - DataProviderData *dpd; - - /* Directory stats */ - guint directories_found; - guint directories_ignored; - guint files_found; - guint files_ignored; -}; - -struct TrackerCrawlerPrivate { - TrackerDataProvider *data_provider; - - /* Directories to crawl */ - GQueue *directories; - - GCancellable *cancellable; - - /* Idle handler for processing found data */ - guint idle_id; - - gdouble throttle; - - gchar *file_attributes; - - /* Statistics */ - GTimer *timer; - - /* Status */ - gboolean is_running; - gboolean is_finished; - gboolean is_paused; - gboolean was_started; -}; - -enum { - CHECK_DIRECTORY, - CHECK_FILE, - CHECK_DIRECTORY_CONTENTS, - DIRECTORY_CRAWLED, - FINISHED, - LAST_SIGNAL -}; - -enum { - PROP_0, - PROP_DATA_PROVIDER, -}; - -static void crawler_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static void crawler_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void crawler_finalize (GObject *object); -static gboolean check_defaults (TrackerCrawler *crawler, - GFile *file); -static gboolean check_contents_defaults (TrackerCrawler *crawler, - GFile *file, - GList *contents); -static void data_provider_data_free (DataProviderData *dpd); - -static void data_provider_begin (TrackerCrawler *crawler, - DirectoryRootInfo *info, - DirectoryProcessingData *dir_data); -static void data_provider_end (TrackerCrawler *crawler, - DirectoryRootInfo *info); -static void directory_root_info_free (DirectoryRootInfo *info); - - -static guint signals[LAST_SIGNAL] = { 0, }; -static GQuark file_info_quark = 0; - -G_DEFINE_TYPE_WITH_PRIVATE (TrackerCrawler, tracker_crawler, G_TYPE_OBJECT) - -static void -tracker_crawler_class_init (TrackerCrawlerClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - TrackerCrawlerClass *crawler_class = TRACKER_CRAWLER_CLASS (klass); - - object_class->set_property = crawler_set_property; - object_class->get_property = crawler_get_property; - object_class->finalize = crawler_finalize; - - crawler_class->check_directory = check_defaults; - crawler_class->check_file = check_defaults; - crawler_class->check_directory_contents = check_contents_defaults; - - signals[CHECK_DIRECTORY] = - g_signal_new ("check-directory", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (TrackerCrawlerClass, check_directory), - tracker_accumulator_check_file, - NULL, - NULL, - G_TYPE_BOOLEAN, - 1, - G_TYPE_FILE); - signals[CHECK_FILE] = - g_signal_new ("check-file", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (TrackerCrawlerClass, check_file), - tracker_accumulator_check_file, - NULL, - NULL, - G_TYPE_BOOLEAN, - 1, - G_TYPE_FILE); - signals[CHECK_DIRECTORY_CONTENTS] = - g_signal_new ("check-directory-contents", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (TrackerCrawlerClass, check_directory_contents), - tracker_accumulator_check_file, - NULL, - NULL, - G_TYPE_BOOLEAN, - 2, G_TYPE_FILE, G_TYPE_POINTER); - signals[DIRECTORY_CRAWLED] = - g_signal_new ("directory-crawled", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (TrackerCrawlerClass, directory_crawled), - NULL, NULL, - NULL, - G_TYPE_NONE, - 6, - G_TYPE_FILE, - G_TYPE_POINTER, - G_TYPE_UINT, - G_TYPE_UINT, - G_TYPE_UINT, - G_TYPE_UINT); - signals[FINISHED] = - g_signal_new ("finished", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (TrackerCrawlerClass, finished), - NULL, NULL, - NULL, - G_TYPE_NONE, - 1, G_TYPE_BOOLEAN); - - g_object_class_install_property (object_class, - PROP_DATA_PROVIDER, - g_param_spec_object ("data-provider", - "Data provider", - "Data provider to use to crawl structures populating data, e.g. like GFileEnumerator", - TRACKER_TYPE_DATA_PROVIDER, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); - - file_info_quark = g_quark_from_static_string ("tracker-crawler-file-info"); -} - -static void -tracker_crawler_init (TrackerCrawler *object) -{ - TrackerCrawlerPrivate *priv; - - priv = tracker_crawler_get_instance_private (TRACKER_CRAWLER (object)); - priv->directories = g_queue_new (); -} - -static void -crawler_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - TrackerCrawlerPrivate *priv; - - priv = tracker_crawler_get_instance_private (TRACKER_CRAWLER (object)); - - switch (prop_id) { - case PROP_DATA_PROVIDER: - priv->data_provider = g_value_dup_object (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -crawler_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - TrackerCrawlerPrivate *priv; - - priv = tracker_crawler_get_instance_private (TRACKER_CRAWLER (object)); - - switch (prop_id) { - case PROP_DATA_PROVIDER: - g_value_set_object (value, priv->data_provider); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -crawler_finalize (GObject *object) -{ - TrackerCrawlerPrivate *priv; - - priv = tracker_crawler_get_instance_private (TRACKER_CRAWLER (object)); - - if (priv->timer) { - g_timer_destroy (priv->timer); - } - - if (priv->idle_id) { - g_source_remove (priv->idle_id); - } - - if (priv->cancellable) { - g_cancellable_cancel (priv->cancellable); - g_object_unref (priv->cancellable); - } - - g_queue_foreach (priv->directories, (GFunc) directory_root_info_free, NULL); - g_queue_free (priv->directories); - - g_free (priv->file_attributes); - - if (priv->data_provider) { - g_object_unref (priv->data_provider); - } - - G_OBJECT_CLASS (tracker_crawler_parent_class)->finalize (object); -} - -static gboolean -check_defaults (TrackerCrawler *crawler, - GFile *file) -{ - return TRUE; -} - -static gboolean -check_contents_defaults (TrackerCrawler *crawler, - GFile *file, - GList *contents) -{ - return TRUE; -} - -TrackerCrawler * -tracker_crawler_new (TrackerDataProvider *data_provider) -{ - TrackerCrawler *crawler; - TrackerDataProvider *default_data_provider = NULL; - - if (G_LIKELY (!data_provider)) { - /* Default to the file data_provider if none is passed */ - data_provider = default_data_provider = tracker_file_data_provider_new (); - } - - crawler = g_object_new (TRACKER_TYPE_CRAWLER, - "data-provider", data_provider, - NULL); - - /* When a data provider is passed to us, we add a reference in - * the set_properties() function for this class, however, if - * we create the data provider, we also have the original - * reference for the created object which needs to be cleared - * up here. - */ - if (default_data_provider) { - g_object_unref (default_data_provider); - } - - return crawler; -} - -static gboolean -check_file (TrackerCrawler *crawler, - DirectoryRootInfo *info, - GFile *file) -{ - gboolean use = FALSE; - TrackerCrawlerPrivate *priv; - - priv = tracker_crawler_get_instance_private (crawler); - - g_signal_emit (crawler, signals[CHECK_FILE], 0, file, &use); - - /* Crawler may have been stopped while waiting for the 'use' value, - * and the DirectoryRootInfo already disposed... */ - if (!priv->is_running) { - return FALSE; - } - - info->files_found++; - - if (!use) { - info->files_ignored++; - } - - return use; -} - -static gboolean -check_directory (TrackerCrawler *crawler, - DirectoryRootInfo *info, - GFile *file) -{ - gboolean use = FALSE; - TrackerCrawlerPrivate *priv; - - priv = tracker_crawler_get_instance_private (crawler); - - g_signal_emit (crawler, signals[CHECK_DIRECTORY], 0, file, &use); - - /* Crawler may have been stopped while waiting for the 'use' value, - * and the DirectoryRootInfo already disposed... */ - if (!priv->is_running) { - return FALSE; - } - - info->directories_found++; - - if (!use) { - info->directories_ignored++; - } - - return use; -} - -static DirectoryChildData * -directory_child_data_new (GFile *child, - gboolean is_dir) -{ - DirectoryChildData *child_data; - - child_data = g_slice_new (DirectoryChildData); - child_data->child = g_object_ref (child); - child_data->is_dir = is_dir; - - return child_data; -} - -static void -directory_child_data_free (DirectoryChildData *child_data) -{ - g_object_unref (child_data->child); - g_slice_free (DirectoryChildData, child_data); -} - -static DirectoryProcessingData * -directory_processing_data_new (GNode *node) -{ - DirectoryProcessingData *data; - - data = g_slice_new0 (DirectoryProcessingData); - data->node = node; - - return data; -} - -static void -directory_processing_data_free (DirectoryProcessingData *data) -{ - g_slist_foreach (data->children, (GFunc) directory_child_data_free, NULL); - g_slist_free (data->children); - - g_slice_free (DirectoryProcessingData, data); -} - -static void -directory_processing_data_add_child (DirectoryProcessingData *data, - GFile *child, - gboolean is_dir) -{ - DirectoryChildData *child_data; - - child_data = directory_child_data_new (child, is_dir); - data->children = g_slist_prepend (data->children, child_data); -} - -static DirectoryRootInfo * -directory_root_info_new (GFile *file, - gchar *file_attributes, - TrackerDirectoryFlags flags) -{ - DirectoryRootInfo *info; - DirectoryProcessingData *dir_info; - gboolean allow_stat = TRUE; - - info = g_slice_new0 (DirectoryRootInfo); - - info->directory = g_object_ref (file); - info->directory_processing_queue = g_queue_new (); - - info->tree = g_node_new (g_object_ref (file)); - - info->flags = flags; - - if ((info->flags & TRACKER_DIRECTORY_FLAG_NO_STAT) != 0) { - allow_stat = FALSE; - } - - /* NOTE: GFileInfo is ABSOLUTELY required here, without it the - * TrackerFileNotifier will think that top level roots have - * been deleted because the GFileInfo GQuark does not exist. - * - * This is seen easily by mounting a removable device, - * indexing, then removing, then re-inserting that same - * device. - * - * The check is done later in the TrackerFileNotifier by - * looking up the qdata that we set in both conditions below. - */ - if (allow_stat && file_attributes) { - GFileInfo *file_info; - GFileQueryInfoFlags file_flags; - - file_flags = G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS; - - file_info = g_file_query_info (file, - file_attributes, - file_flags, - NULL, - NULL); - g_object_set_qdata_full (G_OBJECT (file), - file_info_quark, - file_info, - (GDestroyNotify) g_object_unref); - } else { - GFileInfo *file_info; - gchar *basename; - - file_info = g_file_info_new (); - g_file_info_set_file_type (file_info, G_FILE_TYPE_DIRECTORY); - - basename = g_file_get_basename (file); - g_file_info_set_name (file_info, basename); - g_free (basename); - - /* Only thing missing is mtime, we can't know this. - * Not setting it means 0 is assumed, but if we set it - * to 'now' then the state machines above us will - * assume the directory is always newer when it may - * not be. - */ - - g_file_info_set_content_type (file_info, "inode/directory"); - - g_object_set_qdata_full (G_OBJECT (file), - file_info_quark, - file_info, - (GDestroyNotify) g_object_unref); - } - - /* Fill in the processing info for the root node */ - dir_info = directory_processing_data_new (info->tree); - g_queue_push_tail (info->directory_processing_queue, dir_info); - - return info; -} - -static gboolean -directory_tree_free_foreach (GNode *node, - gpointer user_data) -{ - g_object_unref (node->data); - return FALSE; -} - -static void -directory_root_info_free (DirectoryRootInfo *info) -{ - if (info->dpd) { - data_provider_end (info->dpd->crawler, info); - } - - g_object_unref (info->directory); - - g_node_traverse (info->tree, - G_PRE_ORDER, - G_TRAVERSE_ALL, - -1, - directory_tree_free_foreach, - NULL); - g_node_destroy (info->tree); - - g_queue_foreach (info->directory_processing_queue, - (GFunc) directory_processing_data_free, - NULL); - g_queue_free (info->directory_processing_queue); - - g_slice_free (DirectoryRootInfo, info); -} - -static gboolean -process_next (TrackerCrawler *crawler) -{ - TrackerCrawlerPrivate *priv; - DirectoryRootInfo *info; - DirectoryProcessingData *dir_data = NULL; - gboolean stop_idle = FALSE; - - priv = tracker_crawler_get_instance_private (crawler); - - if (priv->is_paused) { - /* Stop the idle func for now until we are unpaused */ - priv->idle_id = 0; - - return FALSE; - } - - info = g_queue_peek_head (priv->directories); - - if (info) { - dir_data = g_queue_peek_head (info->directory_processing_queue); - } - - if (dir_data) { - /* One directory inside the tree hierarchy is being inspected */ - if (!dir_data->was_inspected) { - dir_data->was_inspected = TRUE; - - /* Crawler may have been already stopped while we were waiting for the - * check_directory return value, and thus we should check if it's - * running before going on with the iteration */ - if (priv->is_running && G_NODE_IS_ROOT (dir_data->node)) { - /* Directory contents haven't been inspected yet, - * stop this idle function while it's being iterated - */ - data_provider_begin (crawler, info, dir_data); - stop_idle = TRUE; - } - } else if (dir_data->was_inspected && - !dir_data->ignored_by_content && - dir_data->children != NULL) { - DirectoryChildData *child_data; - GNode *child_node = NULL; - - /* Directory has been already inspected, take children - * one by one and check whether they should be incorporated - * to the tree. - */ - child_data = dir_data->children->data; - dir_data->children = g_slist_remove (dir_data->children, child_data); - - if (((child_data->is_dir && - check_directory (crawler, info, child_data->child)) || - (!child_data->is_dir && - check_file (crawler, info, child_data->child))) && - /* Crawler may have been already stopped while we were waiting for the - * check_directory or check_file return value, and thus we should - * check if it's running before going on */ - priv->is_running) { - child_node = g_node_prepend_data (dir_data->node, - g_object_ref (child_data->child)); - } - - if (G_NODE_IS_ROOT (dir_data->node) && priv->is_running && - child_node && child_data->is_dir) { - DirectoryProcessingData *child_dir_data; - - child_dir_data = directory_processing_data_new (child_node); - g_queue_push_tail (info->directory_processing_queue, child_dir_data); - } - - directory_child_data_free (child_data); - } else { - /* No (more) children, or directory ignored. stop processing. */ - g_queue_pop_head (info->directory_processing_queue); - directory_processing_data_free (dir_data); - } - } else if (!dir_data && info) { - /* Current directory being crawled doesn't have anything else - * to process, emit ::directory-crawled and free data. - */ - g_signal_emit (crawler, signals[DIRECTORY_CRAWLED], 0, - info->directory, - info->tree, - info->directories_found, - info->directories_ignored, - info->files_found, - info->files_ignored); - - data_provider_end (crawler, info); - g_queue_pop_head (priv->directories); - directory_root_info_free (info); - } - - if (!g_queue_peek_head (priv->directories)) { - /* There's nothing else to process */ - priv->is_finished = TRUE; - tracker_crawler_stop (crawler); - stop_idle = TRUE; - } - - if (stop_idle) { - priv->idle_id = 0; - return FALSE; - } - - return TRUE; -} - -static gboolean -process_func (gpointer data) -{ - TrackerCrawler *crawler = data; - gboolean retval = FALSE; - gint i; - - for (i = 0; i < MAX_SIMULTANEOUS_ITEMS; i++) { - retval = process_next (crawler); - if (retval == FALSE) - break; - } - - return retval; -} - -static gboolean -process_func_start (TrackerCrawler *crawler) -{ - TrackerCrawlerPrivate *priv; - - priv = tracker_crawler_get_instance_private (crawler); - - if (priv->is_paused) { - return FALSE; - } - - if (priv->is_finished) { - return FALSE; - } - - if (priv->idle_id == 0) { - priv->idle_id = g_idle_add (process_func, crawler); - } - - return TRUE; -} - -static void -process_func_stop (TrackerCrawler *crawler) -{ - TrackerCrawlerPrivate *priv; - - priv = tracker_crawler_get_instance_private (crawler); - - if (priv->idle_id != 0) { - g_source_remove (priv->idle_id); - priv->idle_id = 0; - } -} - -static DataProviderData * -data_provider_data_new (TrackerCrawler *crawler, - DirectoryRootInfo *root_info, - DirectoryProcessingData *dir_info) -{ - DataProviderData *dpd; - - dpd = g_slice_new0 (DataProviderData); - - dpd->crawler = g_object_ref (crawler); - dpd->root_info = root_info; - dpd->dir_info = dir_info; - /* Make sure there's always a ref of the GFile while we're - * iterating it */ - dpd->dir_file = g_object_ref (G_FILE (dir_info->node->data)); - - return dpd; -} - -static void -data_provider_data_process (DataProviderData *dpd) -{ - TrackerCrawler *crawler; - GSList *l; - GList *children = NULL; - gboolean use; - - crawler = dpd->crawler; - - for (l = dpd->dir_info->children; l; l = l->next) { - DirectoryChildData *child_data; - - child_data = l->data; - children = g_list_prepend (children, child_data->child); - } - - g_signal_emit (crawler, signals[CHECK_DIRECTORY_CONTENTS], 0, dpd->dir_file, children, &use); - g_list_free (children); - - if (!use) { - dpd->dir_info->ignored_by_content = TRUE; - /* FIXME: Update stats */ - return; - } -} - -static void -data_provider_data_add (DataProviderData *dpd) -{ - TrackerCrawlerPrivate *priv; - TrackerCrawler *crawler; - GFile *parent; - GList *l; - - crawler = dpd->crawler; - parent = dpd->dir_file; - priv = tracker_crawler_get_instance_private (crawler); - - for (l = dpd->files; l; l = l->next) { - GFileInfo *info; - GFile *child; - const gchar *child_name; - gboolean is_dir; - - info = l->data; - - child_name = g_file_info_get_name (info); - child = g_file_get_child (parent, child_name); - is_dir = g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY; - - if (priv->file_attributes) { - /* Store the file info for future retrieval */ - g_object_set_qdata_full (G_OBJECT (child), - file_info_quark, - g_object_ref (info), - (GDestroyNotify) g_object_unref); - } - - directory_processing_data_add_child (dpd->dir_info, child, is_dir); - - g_object_unref (child); - g_object_unref (info); - } - - g_list_free (dpd->files); - dpd->files = NULL; -} - -static void -data_provider_data_free (DataProviderData *dpd) -{ - g_object_unref (dpd->dir_file); - g_object_unref (dpd->crawler); - - if (dpd->files) { - g_list_free_full (dpd->files, g_object_unref); - } - - if (dpd->enumerator) { - g_object_unref (dpd->enumerator); - } - - g_slice_free (DataProviderData, dpd); -} - -static void -data_provider_end_cb (GObject *object, - GAsyncResult *result, - gpointer user_data) -{ - DataProviderData *dpd; - GError *error = NULL; - - g_file_enumerator_close_finish (G_FILE_ENUMERATOR (object), result, &error); - dpd = user_data; - - if (error) { - if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - gchar *uri = g_file_get_uri (dpd->dir_file); - g_warning ("Could not end data provider for container / directory '%s', %s", - uri, error ? error->message : "no error given"); - g_free (uri); - } - g_clear_error (&error); - } - - data_provider_data_free (dpd); -} - -static void -data_provider_end (TrackerCrawler *crawler, - DirectoryRootInfo *info) -{ - DataProviderData *dpd; - - g_return_if_fail (info != NULL); - - if (info->dpd == NULL) { - /* Nothing to do */ - return; - } - - /* We detach the DataProviderData from the DirectoryRootInfo - * here so it's not freed early. We can't use - * DirectoryRootInfo as user data for the async function below - * because it's freed before that callback will be called. - */ - dpd = info->dpd; - info->dpd = NULL; - - if (dpd->enumerator) { - g_file_enumerator_close_async (dpd->enumerator, - G_PRIORITY_LOW, NULL, - data_provider_end_cb, - dpd); - } else { - data_provider_data_free (dpd); - } -} - -static void -enumerate_next_cb (GObject *object, - GAsyncResult *result, - gpointer user_data) -{ - DataProviderData *dpd; - GList *info; - g_autoptr(GError) error = NULL; - - info = g_file_enumerator_next_files_finish (G_FILE_ENUMERATOR (object), result, &error); - dpd = user_data; - - if (!info) { - /* Could be due to: - * a) error, - * b) no more items - */ - if (error) { - /* We don't consider cancellation an error, so we only - * log errors which are not cancellations. - */ - if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - gchar *uri = g_file_get_uri (dpd->dir_file); - g_warning ("Could not enumerate next item in container / directory '%s', %s", - uri, error ? error->message : "no error given"); - g_free (uri); - } else { - return; - } - } else { - /* Done enumerating, start processing what we got ... */ - data_provider_data_add (dpd); - data_provider_data_process (dpd); - } - - process_func_start (dpd->crawler); - } else { - TrackerCrawlerPrivate *priv; - - priv = tracker_crawler_get_instance_private (dpd->crawler); - - /* More work to do, we keep reference given to us */ - dpd->files = g_list_concat (dpd->files, info); - g_file_enumerator_next_files_async (G_FILE_ENUMERATOR (object), - MAX_SIMULTANEOUS_ITEMS, - G_PRIORITY_LOW, - priv->cancellable, - enumerate_next_cb, - dpd); - } -} - -static void -data_provider_begin_cb (GObject *object, - GAsyncResult *result, - gpointer user_data) -{ - TrackerCrawlerPrivate *priv; - GFileEnumerator *enumerator; - DirectoryRootInfo *info; - DataProviderData *dpd; - GError *error = NULL; - - enumerator = tracker_data_provider_begin_finish (TRACKER_DATA_PROVIDER (object), result, &error); - - info = user_data; - - if (error) { - if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - gchar *uri; - - dpd = info->dpd; - uri = g_file_get_uri (dpd->dir_file); - g_warning ("Could not enumerate container / directory '%s', %s", - uri, error ? error->message : "no error given"); - g_free (uri); - process_func_start (dpd->crawler); - } - g_clear_error (&error); - return; - } - - dpd = info->dpd; - dpd->enumerator = enumerator; - priv = tracker_crawler_get_instance_private (dpd->crawler); - g_file_enumerator_next_files_async (enumerator, - MAX_SIMULTANEOUS_ITEMS, - G_PRIORITY_LOW, - priv->cancellable, - enumerate_next_cb, - dpd); -} - -static void -data_provider_begin (TrackerCrawler *crawler, - DirectoryRootInfo *info, - DirectoryProcessingData *dir_data) -{ - TrackerCrawlerPrivate *priv; - DataProviderData *dpd; - gchar *attrs; - - priv = tracker_crawler_get_instance_private (crawler); - - /* DataProviderData is freed in data_provider_end() call. This - * call must _ALWAYS_ be reached even on cancellation or - * failure, this is normally the case when we return to the - * process_func() and finish a directory. - */ - dir_data->was_inspected = TRUE; - dpd = data_provider_data_new (crawler, info, dir_data); - info->dpd = dpd; - - if (priv->file_attributes) { - attrs = g_strconcat (FILE_ATTRIBUTES ",", - priv->file_attributes, - NULL); - } else { - attrs = g_strdup (FILE_ATTRIBUTES); - } - - tracker_data_provider_begin_async (priv->data_provider, - dpd->dir_file, - attrs, - info->flags, - G_PRIORITY_LOW, - priv->cancellable, - data_provider_begin_cb, - info); - g_free (attrs); -} - -gboolean -tracker_crawler_start (TrackerCrawler *crawler, - GFile *file, - TrackerDirectoryFlags flags) -{ - TrackerCrawlerPrivate *priv; - DirectoryProcessingData *dir_data; - DirectoryRootInfo *info; - gboolean enable_stat; - - g_return_val_if_fail (TRACKER_IS_CRAWLER (crawler), FALSE); - g_return_val_if_fail (G_IS_FILE (file), FALSE); - - priv = tracker_crawler_get_instance_private (crawler); - - enable_stat = (flags & TRACKER_DIRECTORY_FLAG_NO_STAT) == 0; - - if (enable_stat && !g_file_query_exists (file, NULL)) { - /* This shouldn't happen, unless the removal/unmount notification - * didn't yet reach the TrackerFileNotifier. - */ - return FALSE; - } - - priv->was_started = TRUE; - - /* Time the event */ - if (priv->timer) { - g_timer_destroy (priv->timer); - } - - priv->timer = g_timer_new (); - - if (priv->is_paused) { - g_timer_stop (priv->timer); - } - - /* Set a brand new cancellable */ - if (priv->cancellable) { - g_cancellable_cancel (priv->cancellable); - g_object_unref (priv->cancellable); - } - - priv->cancellable = g_cancellable_new (); - - /* Set as running now */ - priv->is_running = TRUE; - priv->is_finished = FALSE; - - info = directory_root_info_new (file, priv->file_attributes, flags); - - if (!check_directory (crawler, info, file)) { - directory_root_info_free (info); - - g_timer_destroy (priv->timer); - priv->timer = NULL; - - priv->is_running = FALSE; - priv->is_finished = TRUE; - - return FALSE; - } - - g_queue_push_tail (priv->directories, info); - - dir_data = g_queue_peek_head (info->directory_processing_queue); - - if (dir_data) - data_provider_begin (crawler, info, dir_data); - - return TRUE; -} - -void -tracker_crawler_stop (TrackerCrawler *crawler) -{ - TrackerCrawlerPrivate *priv; - - g_return_if_fail (TRACKER_IS_CRAWLER (crawler)); - - priv = tracker_crawler_get_instance_private (crawler); - - /* If already not running, just ignore */ - if (!priv->is_running) { - return; - } - - priv->is_running = FALSE; - g_cancellable_cancel (priv->cancellable); - - process_func_stop (crawler); - - if (priv->timer) { - g_timer_destroy (priv->timer); - priv->timer = NULL; - } - - /* Clean up queue */ - g_queue_foreach (priv->directories, (GFunc) directory_root_info_free, NULL); - g_queue_clear (priv->directories); - - g_signal_emit (crawler, signals[FINISHED], 0, - !priv->is_finished); - - /* We don't free the queue in case the crawler is reused, it - * is only freed in finalize. - */ -} - -void -tracker_crawler_pause (TrackerCrawler *crawler) -{ - TrackerCrawlerPrivate *priv; - - g_return_if_fail (TRACKER_IS_CRAWLER (crawler)); - - priv = tracker_crawler_get_instance_private (crawler); - priv->is_paused = TRUE; - - if (priv->is_running) { - g_timer_stop (priv->timer); - process_func_stop (crawler); - } - - g_message ("Crawler is paused, %s", - priv->is_running ? "currently running" : "not running"); -} - -void -tracker_crawler_resume (TrackerCrawler *crawler) -{ - TrackerCrawlerPrivate *priv; - - g_return_if_fail (TRACKER_IS_CRAWLER (crawler)); - - priv = tracker_crawler_get_instance_private (crawler); - - priv->is_paused = FALSE; - - if (priv->is_running) { - g_timer_continue (priv->timer); - process_func_start (crawler); - } - - g_message ("Crawler is resuming, %s", - priv->is_running ? "currently running" : "not running"); -} - -void -tracker_crawler_set_throttle (TrackerCrawler *crawler, - gdouble throttle) -{ - TrackerCrawlerPrivate *priv; - - g_return_if_fail (TRACKER_IS_CRAWLER (crawler)); - - priv = tracker_crawler_get_instance_private (crawler); - - throttle = CLAMP (throttle, 0, 1); - priv->throttle = throttle; - - /* Update timeouts */ - if (priv->idle_id != 0) { - guint interval, idle_id; - - interval = TRACKER_CRAWLER_MAX_TIMEOUT_INTERVAL * priv->throttle; - - g_source_remove (priv->idle_id); - - if (interval == 0) { - idle_id = g_idle_add (process_func, crawler); - } else { - idle_id = g_timeout_add (interval, process_func, crawler); - } - - priv->idle_id = idle_id; - } -} - -/** - * tracker_crawler_set_file_attributes: - * @crawler: a #TrackerCrawler - * @file_attributes: file attributes to extract - * - * Sets the file attributes that @crawler will fetch for every - * file it gets, this info may be requested through - * tracker_crawler_get_file_info() in any #TrackerCrawler callback - **/ -void -tracker_crawler_set_file_attributes (TrackerCrawler *crawler, - const gchar *file_attributes) -{ - TrackerCrawlerPrivate *priv; - - g_return_if_fail (TRACKER_IS_CRAWLER (crawler)); - - priv = tracker_crawler_get_instance_private (crawler); - - g_free (priv->file_attributes); - priv->file_attributes = g_strdup (file_attributes); -} - -/** - * tracker_crawler_get_file_attributes: - * @crawler: a #TrackerCrawler - * - * Returns the file attributes that @crawler will fetch - * - * Returns: the file attributes as a string. - **/ -const gchar * -tracker_crawler_get_file_attributes (TrackerCrawler *crawler) -{ - TrackerCrawlerPrivate *priv; - - g_return_val_if_fail (TRACKER_IS_CRAWLER (crawler), NULL); - - priv = tracker_crawler_get_instance_private (crawler); - - return priv->file_attributes; -} - -/** - * tracker_crawler_get_file_info: - * @crawler: a #TrackerCrawler - * @file: a #GFile returned by @crawler - * - * Returns a #GFileInfo with the file attributes requested through - * tracker_crawler_set_file_attributes(). - * - * Returns: (transfer none): a #GFileInfo with the file information - **/ -GFileInfo * -tracker_crawler_get_file_info (TrackerCrawler *crawler, - GFile *file) -{ - GFileInfo *info; - - g_return_val_if_fail (TRACKER_IS_CRAWLER (crawler), NULL); - g_return_val_if_fail (G_IS_FILE (file), NULL); - - info = g_object_steal_qdata (G_OBJECT (file), file_info_quark); - return info; -} diff --git a/src/libtracker-miner/tracker-crawler.h b/src/libtracker-miner/tracker-crawler.h deleted file mode 100644 index 8a1034b59..000000000 --- a/src/libtracker-miner/tracker-crawler.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 2009, Nokia <ivan.frade@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __LIBTRACKER_MINER_CRAWLER_H__ -#define __LIBTRACKER_MINER_CRAWLER_H__ - -#if !defined (__LIBTRACKER_MINER_H_INSIDE__) && !defined (TRACKER_COMPILATION) -#error "Only <libtracker-miner/tracker-miner.h> can be included directly." -#endif - -#include <glib-object.h> -#include <gio/gio.h> - -#include "tracker-data-provider.h" - -G_BEGIN_DECLS - -#define TRACKER_TYPE_CRAWLER (tracker_crawler_get_type ()) -#define TRACKER_CRAWLER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), TRACKER_TYPE_CRAWLER, TrackerCrawler)) -#define TRACKER_CRAWLER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TRACKER_TYPE_CRAWLER, TrackerCrawlerClass)) -#define TRACKER_IS_CRAWLER(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), TRACKER_TYPE_CRAWLER)) -#define TRACKER_IS_CRAWLER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TRACKER_TYPE_CRAWLER)) -#define TRACKER_CRAWLER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TRACKER_TYPE_CRAWLER, TrackerCrawlerClass)) - -/* Max timeouts time (in msec) */ -#define TRACKER_CRAWLER_MAX_TIMEOUT_INTERVAL 1000 - -typedef struct TrackerCrawler TrackerCrawler; -typedef struct TrackerCrawlerClass TrackerCrawlerClass; -typedef struct TrackerCrawlerPrivate TrackerCrawlerPrivate; - -struct TrackerCrawler { - GObject parent; -}; - -struct TrackerCrawlerClass { - GObjectClass parent; - - gboolean (* check_directory) (TrackerCrawler *crawler, - GFile *file); - gboolean (* check_file) (TrackerCrawler *crawler, - GFile *file); - gboolean (* check_directory_contents) (TrackerCrawler *crawler, - GFile *file, - GList *contents); - void (* directory_crawled) (TrackerCrawler *crawler, - GFile *directory, - GNode *tree, - guint directories_found, - guint directories_ignored, - guint files_found, - guint files_ignored); - void (* finished) (TrackerCrawler *crawler, - gboolean interrupted); -}; - -GType tracker_crawler_get_type (void); -TrackerCrawler *tracker_crawler_new (TrackerDataProvider *data_provider); -gboolean tracker_crawler_start (TrackerCrawler *crawler, - GFile *file, - TrackerDirectoryFlags flags); -void tracker_crawler_stop (TrackerCrawler *crawler); -void tracker_crawler_pause (TrackerCrawler *crawler); -void tracker_crawler_resume (TrackerCrawler *crawler); -void tracker_crawler_set_throttle (TrackerCrawler *crawler, - gdouble throttle); - -void tracker_crawler_set_file_attributes (TrackerCrawler *crawler, - const gchar *file_attributes); -const gchar * tracker_crawler_get_file_attributes (TrackerCrawler *crawler); - -GFileInfo * tracker_crawler_get_file_info (TrackerCrawler *crawler, - GFile *file); - -G_END_DECLS - -#endif /* __LIBTRACKER_MINER_CRAWLER_H__ */ diff --git a/src/libtracker-miner/tracker-data-provider.c b/src/libtracker-miner/tracker-data-provider.c deleted file mode 100644 index 20a3396b6..000000000 --- a/src/libtracker-miner/tracker-data-provider.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright (C) 2014, Softathome <contact@softathome.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Author: Martyn Russell <martyn@lanedo.com> - */ - -#include "config.h" - -#include <glib/gi18n.h> - -#include "tracker-data-provider.h" - -/** - * SECTION:tracker-data-provider - * @short_description: Provide data to be indexed - * @include: libtracker-miner/miner.h - * - * #TrackerDataProvider allows you to operate on a set of #GFiles, - * returning a #GFileInfo structure for each file enumerated (e.g. - * tracker_data_provider_begin() will return a #GFileEnumerator - * which can be used to enumerate resources provided by the - * #TrackerDataProvider. - * - * There is also a #TrackerFileDataProvider which is an implementation - * of this #TrackerDataProvider interface. - * - * The #TrackerMinerFS class which is a subclass to #TrackerMiner - * takes a #TrackerDataProvider property which is passed down to the - * TrackerCrawler created upon instantiation. This property is - * #TrackerMinerFS:data-provider. - * - * Since: 1.2 - **/ - -typedef TrackerDataProviderIface TrackerDataProviderInterface; -G_DEFINE_INTERFACE (TrackerDataProvider, tracker_data_provider, G_TYPE_OBJECT) - -static void -tracker_data_provider_default_init (TrackerDataProviderInterface *iface) -{ -} - -/** - * tracker_data_provider_begin: - * @data_provider: a #TrackerDataProvider - * @url: a #GFile to enumerate - * @attributes: an attribute query string - * @flags: a set of #TrackerDirectoryFlags - * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore. - * @error: location to store the error occurring, or %NULL to ignore - * - * Creates a #GFileEnumerator to enumerate children at the URI - * provided by @url. - * - * The attributes value is a string that specifies the file attributes - * that should be gathered. It is not an error if it's not possible to - * read a particular requested attribute from a file - it just won't - * be set. attributes should be a comma-separated list of attributes - * or attribute wildcards. The wildcard "*" means all attributes, and - * a wildcard like "standard::*" means all attributes in the standard - * namespace. An example attribute query be "standard::*,owner::user". - * The standard attributes are available as defines, like - * G_FILE_ATTRIBUTE_STANDARD_NAME. See g_file_enumerate_children() for - * more details. - * - * Returns: (transfer full): a #GFileEnumerator or %NULL on failure. - * This must be freed with g_object_unref(). - * - * Since: 1.2 - **/ -GFileEnumerator * -tracker_data_provider_begin (TrackerDataProvider *data_provider, - GFile *url, - const gchar *attributes, - TrackerDirectoryFlags flags, - GCancellable *cancellable, - GError **error) -{ - TrackerDataProviderIface *iface; - - g_return_val_if_fail (TRACKER_IS_DATA_PROVIDER (data_provider), NULL); - - if (g_cancellable_set_error_if_cancelled (cancellable, error)) { - return NULL; - } - - iface = TRACKER_DATA_PROVIDER_GET_IFACE (data_provider); - - if (iface->begin == NULL) { - g_set_error_literal (error, - G_IO_ERROR, - G_IO_ERROR_NOT_SUPPORTED, - _("Operation not supported")); - return NULL; - } - - return (* iface->begin) (data_provider, url, attributes, flags, cancellable, error); -} - -/** - * tracker_data_provider_begin_async: - * @data_provider: a #TrackerDataProvider. - * @url: a #GFile to enumerate - * @attributes: an attribute query string - * @flags: a set of #TrackerDirectoryFlags - * @io_priority: the I/O priority of the request (example: %G_PRIORITY_DEFAULT) - * @cancellable: (allow-none): optional #GCancellable object, %NULL to - * ignore - * @callback: (scope async): a #GAsyncReadyCallback to call when the - * request is satisfied - * @user_data: (closure): the data to pass to callback function - * - * Precisely the same operation as tracker_data_provider_begin() - * is performing, but asynchronously. - * - * When all i/o for the operation is finished the @callback will be - * called with the requested information. - - * See the documentation of #TrackerDataProvider for information about the - * order of returned files. - * - * In case of a partial error the callback will be called with any - * succeeding items and no error, and on the next request the error - * will be reported. If a request is cancelled the callback will be - * called with %G_IO_ERROR_CANCELLED. - * - * During an async request no other sync and async calls are allowed, - * and will result in %G_IO_ERROR_PENDING errors. - * - * Any outstanding i/o request with higher priority (lower numerical - * value) will be executed before an outstanding request with lower - * priority. Default priority is %G_PRIORITY_DEFAULT. - * - * Since: 1.2 - **/ -void -tracker_data_provider_begin_async (TrackerDataProvider *data_provider, - GFile *url, - const gchar *attributes, - TrackerDirectoryFlags flags, - int io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - TrackerDataProviderIface *iface; - - g_return_if_fail (TRACKER_IS_DATA_PROVIDER (data_provider)); - - iface = TRACKER_DATA_PROVIDER_GET_IFACE (data_provider); - - if (iface->begin_async == NULL) { - g_critical (_("Operation not supported")); - return; - } - - (* iface->begin_async) (data_provider, url, attributes, flags, io_priority, cancellable, callback, user_data); -} - -/** - * tracker_data_provider_begin_finish: - * @data_provider: a #TrackerDataProvider. - * @result: a #GAsyncResult. - * @error: a #GError location to store the error occurring, or %NULL - * to ignore. - * - * Finishes the asynchronous operation started with - * tracker_data_provider_begin_async(). - * - * Returns: (transfer full): a #GFileEnumerator or %NULL on failure. - * This must be freed with g_object_unref(). - * - * Since: 1.2 - **/ -GFileEnumerator * -tracker_data_provider_begin_finish (TrackerDataProvider *data_provider, - GAsyncResult *result, - GError **error) -{ - TrackerDataProviderIface *iface; - - g_return_val_if_fail (TRACKER_IS_DATA_PROVIDER (data_provider), NULL); - g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL); - - iface = TRACKER_DATA_PROVIDER_GET_IFACE (data_provider); - - if (g_async_result_legacy_propagate_error (result, error)) { - return NULL; - } - - return (* iface->begin_finish) (data_provider, result, error); -} diff --git a/src/libtracker-miner/tracker-data-provider.h b/src/libtracker-miner/tracker-data-provider.h deleted file mode 100644 index a2cf15552..000000000 --- a/src/libtracker-miner/tracker-data-provider.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2014, Softathome <contact@softathome.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Author: Martyn Russell <martyn@lanedo.com> - */ - -#ifndef __LIBTRACKER_MINER_DATA_PROVIDER_H__ -#define __LIBTRACKER_MINER_DATA_PROVIDER_H__ - -#if !defined (__LIBTRACKER_MINER_H_INSIDE__) && !defined (TRACKER_COMPILATION) -#error "Only <libtracker-miner/tracker-miner.h> can be included directly." -#endif - -#include <gio/gio.h> - -#include "tracker-miner-enums.h" - -G_BEGIN_DECLS - -#define TRACKER_TYPE_DATA_PROVIDER (tracker_data_provider_get_type ()) -#define TRACKER_DATA_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TRACKER_TYPE_DATA_PROVIDER, TrackerDataProvider)) -#define TRACKER_IS_DATA_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TRACKER_TYPE_DATA_PROVIDER)) -#define TRACKER_DATA_PROVIDER_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TRACKER_TYPE_DATA_PROVIDER, TrackerDataProviderIface)) - -/** - * TrackerDataProvider: - * - * An interface to enumerate URIs and feed the data to Tracker. - **/ -typedef struct _TrackerDataProvider TrackerDataProvider; -typedef struct _TrackerDataProviderIface TrackerDataProviderIface; - -/** - * TrackerDataProviderIface: - * @g_iface: Parent interface type. - * @begin: Called when the data_provider is synchronously - * opening and starting the iteration of a given location. - * @begin_async: Called when the data_provider is synchronously - * opening and starting the iteration of a given location. Completed - * using @begin_finish. - * @begin_finish: Called when the data_provider is completing the - * asynchronous operation provided by @begin_async. - * - * Virtual methods left to implement. - **/ -struct _TrackerDataProviderIface { - GTypeInterface g_iface; - - /* Virtual Table */ - - /* Start the data_provider for a given location, attributes and flags */ - GFileEnumerator * (* begin) (TrackerDataProvider *data_provider, - GFile *url, - const gchar *attributes, - TrackerDirectoryFlags flags, - GCancellable *cancellable, - GError **error); - void (* begin_async) (TrackerDataProvider *data_provider, - GFile *url, - const gchar *attributes, - TrackerDirectoryFlags flags, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); - GFileEnumerator * (* begin_finish) (TrackerDataProvider *data_provider, - GAsyncResult *result, - GError **error); - - /*< private >*/ - gpointer padding[10]; -}; - -GType tracker_data_provider_get_type (void) G_GNUC_CONST; -GFileEnumerator *tracker_data_provider_begin (TrackerDataProvider *data_provider, - GFile *url, - const gchar *attributes, - TrackerDirectoryFlags flags, - GCancellable *cancellable, - GError **error); -void tracker_data_provider_begin_async (TrackerDataProvider *data_provider, - GFile *url, - const gchar *attributes, - TrackerDirectoryFlags flags, - gint io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -GFileEnumerator *tracker_data_provider_begin_finish (TrackerDataProvider *data_provider, - GAsyncResult *result, - GError **error); - -G_END_DECLS - -#endif /* __LIBTRACKER_MINER_DATA_PROVIDER_H__ */ diff --git a/src/libtracker-miner/tracker-decorator-fs.c b/src/libtracker-miner/tracker-decorator-fs.c deleted file mode 100644 index bd7f672d4..000000000 --- a/src/libtracker-miner/tracker-decorator-fs.c +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Copyright (C) 2014 Carlos Garnacho <carlosg@gnome.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ -#include "config.h" - -#include <glib.h> - -#include <libtracker-common/tracker-common.h> -#include <libtracker-sparql/tracker-sparql.h> - -#include "tracker-decorator-private.h" -#include "tracker-decorator-fs.h" - -/** - * SECTION:tracker-decorator-fs - * @short_description: Filesystem implementation for TrackerDecorator - * @include: libtracker-miner/tracker-miner.h - * @title: TrackerDecoratorFS - * @see_also: #TrackerDecorator - * - * #TrackerDecoratorFS is used to handle extended metadata extraction - * for resources on file systems that are mounted or unmounted. - **/ - -typedef struct _TrackerDecoratorFSPrivate TrackerDecoratorFSPrivate; - -struct _TrackerDecoratorFSPrivate { - GVolumeMonitor *volume_monitor; -}; - -static GInitableIface *parent_initable_iface; - -static void tracker_decorator_fs_initable_iface_init (GInitableIface *iface); - -G_DEFINE_ABSTRACT_TYPE_WITH_CODE (TrackerDecoratorFS, tracker_decorator_fs, - TRACKER_TYPE_DECORATOR, - G_ADD_PRIVATE (TrackerDecoratorFS) - G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, tracker_decorator_fs_initable_iface_init)) - -static void -tracker_decorator_fs_finalize (GObject *object) -{ - TrackerDecoratorFSPrivate *priv; - - priv = TRACKER_DECORATOR_FS (object)->priv; - - if (priv->volume_monitor) - g_object_unref (priv->volume_monitor); - - G_OBJECT_CLASS (tracker_decorator_fs_parent_class)->finalize (object); -} - -static void -tracker_decorator_fs_class_init (TrackerDecoratorFSClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = tracker_decorator_fs_finalize; -} - -static void -process_files_cb (GObject *object, - GAsyncResult *result, - gpointer user_data) -{ - TrackerSparqlConnection *conn; - TrackerSparqlCursor *cursor; - GError *error = NULL; - - conn = TRACKER_SPARQL_CONNECTION (object); - cursor = tracker_sparql_connection_query_finish (conn, result, &error); - - if (error) { - g_critical ("Could not check files on mount point for missing metadata: %s", error->message); - g_error_free (error); - return; - } - - while (tracker_sparql_cursor_next (cursor, NULL, NULL)) { - gint id = tracker_sparql_cursor_get_integer (cursor, 0); - gint class_name_id = tracker_sparql_cursor_get_integer (cursor, 1); - tracker_decorator_prepend_id (TRACKER_DECORATOR (user_data), id, class_name_id); - } - - g_object_unref (cursor); -} - -static void -remove_files_cb (GObject *object, - GAsyncResult *result, - gpointer user_data) -{ - TrackerSparqlConnection *conn; - TrackerSparqlCursor *cursor; - GError *error = NULL; - - conn = TRACKER_SPARQL_CONNECTION (object); - cursor = tracker_sparql_connection_query_finish (conn, result, &error); - - if (error) { - g_critical ("Could not remove files on mount point with missing metadata: %s", error->message); - g_error_free (error); - return; - } - - while (tracker_sparql_cursor_next (cursor, NULL, NULL)) { - gint id = tracker_sparql_cursor_get_integer (cursor, 0); - tracker_decorator_delete_id (TRACKER_DECORATOR (user_data), id); - } - - g_object_unref (cursor); -} - -static void -_tracker_decorator_query_append_rdf_type_filter (TrackerDecorator *decorator, - GString *query) -{ - const gchar **class_names; - gint i = 0; - - class_names = tracker_decorator_get_class_names (decorator); - - if (!class_names || !*class_names) - return; - - g_string_append (query, "&& ?type IN ("); - - while (class_names[i]) { - if (i != 0) - g_string_append (query, ","); - - g_string_append (query, class_names[i]); - i++; - } - - g_string_append (query, ") "); -} - -static void -check_files (TrackerDecorator *decorator, - const gchar *mount_point_urn, - gboolean available, - GAsyncReadyCallback callback) -{ - TrackerSparqlConnection *sparql_conn; - const gchar *data_source; - GString *query; - - data_source = tracker_decorator_get_data_source (decorator); - query = g_string_new ("SELECT tracker:id(?urn) tracker:id(?type) { ?urn "); - - if (mount_point_urn) { - g_string_append_printf (query, - " nie:dataSource <%s> ;", - mount_point_urn); - } - - g_string_append (query, " a nfo:FileDataObject ;" - " a ?type ."); - g_string_append_printf (query, - "FILTER (! EXISTS { ?urn nie:dataSource <%s> } ", - data_source); - - _tracker_decorator_query_append_rdf_type_filter (decorator, query); - - if (available) - g_string_append (query, "&& BOUND(tracker:available(?urn))"); - - g_string_append (query, ")}"); - - sparql_conn = tracker_miner_get_connection (TRACKER_MINER (decorator)); - tracker_sparql_connection_query_async (sparql_conn, query->str, - NULL, callback, decorator); - g_string_free (query, TRUE); -} - -static inline gchar * -mount_point_get_uuid (GMount *mount) -{ - GVolume *volume; - gchar *uuid = NULL; - - volume = g_mount_get_volume (mount); - if (volume) { - uuid = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_UUID); - if (!uuid) { - gchar *mount_name; - - mount_name = g_mount_get_name (mount); - uuid = g_compute_checksum_for_string (G_CHECKSUM_MD5, mount_name, -1); - g_free (mount_name); - } - - g_object_unref (volume); - } - - return uuid; -} - -static void -mount_point_added_cb (GVolumeMonitor *monitor, - GMount *mount, - gpointer user_data) -{ - gchar *uuid; - gchar *urn; - - uuid = mount_point_get_uuid (mount); - urn = g_strdup_printf (TRACKER_PREFIX_DATASOURCE_URN "%s", uuid); - check_files (user_data, urn, TRUE, process_files_cb); - g_free (urn); - g_free (uuid); -} - -static void -mount_point_removed_cb (GVolumeMonitor *monitor, - GMount *mount, - gpointer user_data) -{ - gchar *uuid; - gchar *urn; - - uuid = mount_point_get_uuid (mount); - urn = g_strdup_printf (TRACKER_PREFIX_DATASOURCE_URN "%s", uuid); - _tracker_decorator_invalidate_cache (user_data); - check_files (user_data, urn, FALSE, remove_files_cb); - g_free (urn); - g_free (uuid); -} - -static gboolean -tracker_decorator_fs_iface_init (GInitable *initable, - GCancellable *cancellable, - GError **error) -{ - TrackerDecoratorFSPrivate *priv; - - priv = TRACKER_DECORATOR_FS (initable)->priv; - - priv->volume_monitor = g_volume_monitor_get (); - g_signal_connect_object (priv->volume_monitor, "mount-added", - G_CALLBACK (mount_point_added_cb), initable, 0); - g_signal_connect_object (priv->volume_monitor, "mount-pre-unmount", - G_CALLBACK (mount_point_removed_cb), initable, 0); - g_signal_connect_object (priv->volume_monitor, "mount-removed", - G_CALLBACK (mount_point_removed_cb), initable, 0); - - return parent_initable_iface->init (initable, cancellable, error); -} - -static void -tracker_decorator_fs_initable_iface_init (GInitableIface *iface) -{ - parent_initable_iface = g_type_interface_peek_parent (iface); - iface->init = tracker_decorator_fs_iface_init; -} - -static void -tracker_decorator_fs_init (TrackerDecoratorFS *decorator) -{ - decorator->priv = tracker_decorator_fs_get_instance_private (decorator); -} - -/** - * tracker_decorator_fs_prepend_file: - * @decorator: a #TrackerDecoratorFS - * @file: a #GFile to process - * - * Prepends a file for processing. - * - * Returns: the tracker:id of the element corresponding to the file - * - * Since: 1.2 - **/ -gint -tracker_decorator_fs_prepend_file (TrackerDecoratorFS *decorator, - GFile *file) -{ - TrackerSparqlConnection *sparql_conn; - TrackerSparqlCursor *cursor; - gchar *query, *uri; - gint id, class_id; - - g_return_val_if_fail (TRACKER_IS_DECORATOR_FS (decorator), 0); - g_return_val_if_fail (G_IS_FILE (file), 0); - - uri = g_file_get_uri (file); - query = g_strdup_printf ("SELECT tracker:id(?urn) tracker:id(?type) {" - " ?urn a ?type; nie:url \"%s\" " - "}", uri); - g_free (uri); - - sparql_conn = tracker_miner_get_connection (TRACKER_MINER (decorator)); - cursor = tracker_sparql_connection_query (sparql_conn, query, - NULL, NULL); - g_free (query); - - if (!cursor) - return 0; - - if (!tracker_sparql_cursor_next (cursor, NULL, NULL)) { - g_object_unref (cursor); - return 0; - } - - id = tracker_sparql_cursor_get_integer (cursor, 0); - class_id = tracker_sparql_cursor_get_integer (cursor, 1); - - tracker_decorator_prepend_id (TRACKER_DECORATOR (decorator), - id, class_id); - g_object_unref (cursor); - - return id; -} diff --git a/src/libtracker-miner/tracker-decorator-fs.h b/src/libtracker-miner/tracker-decorator-fs.h deleted file mode 100644 index 2afc205a8..000000000 --- a/src/libtracker-miner/tracker-decorator-fs.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2014 Carlos Garnacho <carlosg@gnome.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __LIBTRACKER_MINER_DECORATOR_FS_H__ -#define __LIBTRACKER_MINER_DECORATOR_FS_H__ - -#if !defined (__LIBTRACKER_MINER_H_INSIDE__) && !defined (TRACKER_COMPILATION) -#error "Only <libtracker-miner/tracker-miner.h> can be included directly." -#endif - -#include "tracker-decorator.h" - -G_BEGIN_DECLS - -#define TRACKER_TYPE_DECORATOR_FS (tracker_decorator_fs_get_type()) -#define TRACKER_DECORATOR_FS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_DECORATOR_FS, TrackerDecoratorFS)) -#define TRACKER_DECORATOR_FS_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), TRACKER_TYPE_DECORATOR_FS, TrackerDecoratorFSClass)) -#define TRACKER_IS_DECORATOR_FS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_DECORATOR_FS)) -#define TRACKER_IS_DECORATOR_FS_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), TRACKER_TYPE_DECORATOR_FS)) -#define TRACKER_DECORATOR_FS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_DECORATOR_FS, TrackerDecoratorFSClass)) - -typedef struct _TrackerDecoratorFS TrackerDecoratorFS; -typedef struct _TrackerDecoratorFSClass TrackerDecoratorFSClass; - -/** - * TrackerDecoratorFS: - * - * A decorator object. - **/ -struct _TrackerDecoratorFS { - TrackerDecorator parent_instance; - gpointer priv; -}; - -/** - * TrackerDecoratorFSClass: - * @parent_class: parent object class. - * @padding: Reserved for future API improvements. - * - * A class that takes care of resources on mount points added or - * removed, this is based on #TrackerDecoratorClass. - **/ -struct _TrackerDecoratorFSClass { - TrackerDecoratorClass parent_class; - - /* <Private> */ - gpointer padding[10]; -}; - -GType tracker_decorator_fs_get_type (void) G_GNUC_CONST; - -gint tracker_decorator_fs_prepend_file (TrackerDecoratorFS *decorator, - GFile *file); - -G_END_DECLS - -#endif /* __LIBTRACKER_MINER_DECORATOR_FS_H__ */ diff --git a/src/libtracker-miner/tracker-decorator-private.h b/src/libtracker-miner/tracker-decorator-private.h deleted file mode 100644 index 8acc7e17c..000000000 --- a/src/libtracker-miner/tracker-decorator-private.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2014 Carlos Garnacho <carlosg@gnome.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __TRACKER_DECORATOR_PRIVATE_H__ -#define __TRACKER_DECORATOR_PRIVATE_H__ - -#include "tracker-decorator.h" - -void _tracker_decorator_invalidate_cache (TrackerDecorator *decorator); - -#endif /* __TRACKER_DECORATOR_PRIVATE_H__ */ diff --git a/src/libtracker-miner/tracker-decorator.c b/src/libtracker-miner/tracker-decorator.c deleted file mode 100644 index 16fa21db7..000000000 --- a/src/libtracker-miner/tracker-decorator.c +++ /dev/null @@ -1,1699 +0,0 @@ -/* - * Copyright (C) 2014 Carlos Garnacho <carlosg@gnome.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "config.h" - -#include <string.h> - -#include "tracker-decorator.h" -#include "tracker-priority-queue.h" -#include "tracker-decorator-private.h" - -#define QUERY_BATCH_SIZE 100 -#define DEFAULT_BATCH_SIZE 200 - -/** - * SECTION:tracker-decorator - * @short_description: A miner tasked with listening for DB resource changes and extracting metadata - * @include: libtracker-miner/tracker-miner.h - * @title: TrackerDecorator - * @see_also: #TrackerDecoratorFS - * - * #TrackerDecorator watches for signal updates based on content changes - * in the database. When new files are added initially, only simple - * metadata exists, for example, name, size, mtime, etc. The - * #TrackerDecorator queues files for extended metadata extraction - * (i.e. for tracker-extract to fetch metadata specific to the file - * type) for example 'nmm:whiteBalance' for a picture. -**/ - -typedef struct _TrackerDecoratorPrivate TrackerDecoratorPrivate; -typedef struct _SparqlUpdate SparqlUpdate; -typedef struct _ClassInfo ClassInfo; - -struct _TrackerDecoratorInfo { - GTask *task; - gchar *urn; - gchar *url; - gchar *mimetype; - gint id; - gint ref_count; -}; - -struct _ClassInfo { - gchar *class_name; - gint priority; -}; - -struct _SparqlUpdate { - gchar *sparql; - gint id; -}; - -struct _TrackerDecoratorPrivate { - TrackerNotifier *notifier; - gchar *data_source; - - GArray *classes; /* Array of ClassInfo */ - gchar **class_names; - - gssize n_remaining_items; - gssize n_processed_items; - - GQueue item_cache; /* Queue of TrackerDecoratorInfo */ - - /* Arrays of tracker IDs */ - GArray *prepended_ids; - GSequence *blacklist_items; - - GHashTable *tasks; /* Associative array of GTasks */ - GArray *sparql_buffer; /* Array of SparqlUpdate */ - GArray *commit_buffer; /* Array of SparqlUpdate */ - GTimer *timer; - GQueue next_elem_queue; /* Queue of incoming tasks */ - - GCancellable *cancellable; - - gint batch_size; - - guint processing : 1; - guint querying : 1; -}; - -enum { - PROP_DATA_SOURCE = 1, - PROP_CLASS_NAMES, - PROP_COMMIT_BATCH_SIZE, - PROP_PRIORITY_RDF_TYPES, -}; - -enum { - ITEMS_AVAILABLE, - FINISHED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; -static GInitableIface *parent_initable_iface; - -static void tracker_decorator_initable_iface_init (GInitableIface *iface); - -static void decorator_task_done (GObject *object, - GAsyncResult *result, - gpointer user_data); -static void decorator_cache_next_items (TrackerDecorator *decorator); -static gboolean decorator_check_commit (TrackerDecorator *decorator); - -static void notifier_events_cb (TrackerDecorator *decorator, - GPtrArray *events, - TrackerNotifier *notifier); - -/** - * tracker_decorator_error_quark: - * - * Gives the caller the #GQuark used to identify #TrackerDecorator errors - * in #GError structures. The #GQuark is used as the domain for the error. - * - * Returns: the #GQuark used for the domain of a #GError. - * - * Since: 0.18 - **/ -G_DEFINE_QUARK (TrackerDecoratorError, tracker_decorator_error) - -G_DEFINE_ABSTRACT_TYPE_WITH_CODE (TrackerDecorator, tracker_decorator, TRACKER_TYPE_MINER, - G_ADD_PRIVATE (TrackerDecorator) - G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, tracker_decorator_initable_iface_init)) - -static TrackerDecoratorInfo * -tracker_decorator_info_new (TrackerDecorator *decorator, - TrackerSparqlCursor *cursor) -{ - TrackerSparqlBuilder *sparql; - TrackerDecoratorInfo *info; - GCancellable *cancellable; - - info = g_slice_new0 (TrackerDecoratorInfo); - info->urn = g_strdup (tracker_sparql_cursor_get_string (cursor, 0, NULL)); - info->id = tracker_sparql_cursor_get_integer (cursor, 1); - info->url = g_strdup (tracker_sparql_cursor_get_string (cursor, 2, NULL)); - info->mimetype = g_strdup (tracker_sparql_cursor_get_string (cursor, 3, NULL)); - info->ref_count = 1; - - cancellable = g_cancellable_new (); - info->task = g_task_new (decorator, cancellable, - decorator_task_done, info); - g_object_unref (cancellable); - - sparql = tracker_sparql_builder_new_update (); - g_task_set_task_data (info->task, sparql, - (GDestroyNotify) g_object_unref); - - return info; -} - -/** - * tracker_decorator_info_ref: - * @info: a #TrackerDecoratorInfo - * - * Increases the reference count of @info by 1. - * - * Returns: the same @info passed in, or %NULL on error. - * - * Since: 0.18 - **/ -TrackerDecoratorInfo * -tracker_decorator_info_ref (TrackerDecoratorInfo *info) -{ - g_atomic_int_inc (&info->ref_count); - return info; -} - -/** - * tracker_decorator_info_unref: - * @info: a #TrackerDecoratorInfo - * - * Decreases the reference count of @info by 1 and frees it when the - * reference count reaches 0. - * - * Since: 0.18 - **/ -void -tracker_decorator_info_unref (TrackerDecoratorInfo *info) -{ - if (!g_atomic_int_dec_and_test (&info->ref_count)) - return; - - if (info->task) - g_object_unref (info->task); - g_free (info->urn); - g_free (info->url); - g_free (info->mimetype); - g_slice_free (TrackerDecoratorInfo, info); -} - -G_DEFINE_BOXED_TYPE (TrackerDecoratorInfo, - tracker_decorator_info, - tracker_decorator_info_ref, - tracker_decorator_info_unref) - -static gint -sequence_compare_func (gconstpointer data1, - gconstpointer data2, - gpointer user_data) -{ - return GPOINTER_TO_INT (data1) - GPOINTER_TO_INT (data2); -} - -static void -decorator_blacklist_add (TrackerDecorator *decorator, - gint id) -{ - TrackerDecoratorPrivate *priv = decorator->priv; - GSequenceIter *iter; - - iter = g_sequence_search (priv->blacklist_items, - GINT_TO_POINTER (id), - sequence_compare_func, - NULL); - - if (g_sequence_iter_is_end (iter) || - g_sequence_get (g_sequence_iter_prev (iter)) != GINT_TO_POINTER (id)) - g_sequence_insert_before (iter, GINT_TO_POINTER (id)); -} - -static void -decorator_blacklist_remove (TrackerDecorator *decorator, - gint id) -{ - TrackerDecoratorPrivate *priv = decorator->priv; - GSequenceIter *iter; - - iter = g_sequence_lookup (priv->blacklist_items, - GINT_TO_POINTER (id), - sequence_compare_func, - NULL); - if (iter) - g_sequence_remove (iter); -} - -static void -decorator_update_state (TrackerDecorator *decorator, - const gchar *message, - gboolean estimate_time) -{ - TrackerDecoratorPrivate *priv; - gint remaining_time = -1; - gdouble progress = 1; - gsize total_items; - - priv = decorator->priv; - remaining_time = 0; - total_items = priv->n_remaining_items + priv->n_processed_items; - - if (priv->n_remaining_items > 0) - progress = ((gdouble) priv->n_processed_items / total_items); - - if (priv->timer && estimate_time && - !tracker_miner_is_paused (TRACKER_MINER (decorator))) { - gdouble elapsed; - - /* FIXME: Quite naive calculation */ - elapsed = g_timer_elapsed (priv->timer, NULL); - - if (priv->n_processed_items > 0) - remaining_time = (priv->n_remaining_items * elapsed) / priv->n_processed_items; - } - - g_object_set (decorator, - "progress", progress, - "remaining-time", remaining_time, - NULL); - - if (message) - g_object_set (decorator, "status", message, NULL); -} - -static void -item_warn (TrackerSparqlConnection *conn, - gint id, - const gchar *sparql, - const GError *error) -{ - TrackerSparqlCursor *cursor; - const gchar *elem; - gchar *query; - - query = g_strdup_printf ("SELECT COALESCE (nie:url (?u), ?u) {" - " ?u a rdfs:Resource. " - " FILTER (tracker:id (?u) = %d)" - "}", id); - - cursor = tracker_sparql_connection_query (conn, query, NULL, NULL); - g_free (query); - - g_debug ("--8<------------------------------"); - g_debug ("The information relevant for a bug report is between " - "the dotted lines"); - - if (cursor && - tracker_sparql_cursor_next (cursor, NULL, NULL)) { - elem = tracker_sparql_cursor_get_string (cursor, 0, NULL); - g_warning ("Could not insert metadata for item \"%s\": %s", - elem, error->message); - } else { - g_warning ("Could not insert metadata for item with ID %d: %s", - id, error->message); - } - - g_warning ("If the error above is recurrent for the same item/ID, " - "consider running \"%s\" in the terminal with the " - "TRACKER_VERBOSITY=3 environment variable, and filing a " - "bug with the additional information", g_get_prgname ()); - - g_debug ("Sparql was:\n%s", sparql); - g_debug ("NOTE: The information above may contain data you " - "consider sensitive. Feel free to edit it out, but please " - "keep it as unmodified as you possibly can."); - g_debug ("------------------------------>8--"); - - g_clear_object (&cursor); -} - -static void -decorator_commit_cb (GObject *object, - GAsyncResult *result, - gpointer user_data) -{ - TrackerSparqlConnection *conn; - TrackerDecoratorPrivate *priv; - TrackerDecorator *decorator; - GError *error = NULL; - GPtrArray *errors; - guint i; - - decorator = user_data; - priv = decorator->priv; - conn = TRACKER_SPARQL_CONNECTION (object); - errors = tracker_sparql_connection_update_array_finish (conn, result, &error); - - if (error) { - g_warning ("There was an error pushing metadata: %s\n", error->message); - } - - if (errors) { - for (i = 0; i < errors->len; i++) { - SparqlUpdate *update; - GError *child_error; - - child_error = g_ptr_array_index (errors, i); - update = &g_array_index (priv->commit_buffer, SparqlUpdate, i); - - if (!child_error) - continue; - - decorator_blacklist_add (decorator, update->id); - item_warn (conn, update->id, update->sparql, child_error); - } - - g_ptr_array_unref (errors); - } - - g_clear_pointer (&priv->commit_buffer, g_array_unref); - - if (!decorator_check_commit (decorator)) - decorator_cache_next_items (decorator); -} - -static void -sparql_update_clear (SparqlUpdate *update) -{ - g_free (update->sparql); -} - -static GArray * -sparql_buffer_new (void) -{ - GArray *array; - - array = g_array_new (FALSE, FALSE, sizeof (SparqlUpdate)); - g_array_set_clear_func (array, (GDestroyNotify) sparql_update_clear); - - return array; -} - -static gboolean -decorator_commit_info (TrackerDecorator *decorator) -{ - TrackerSparqlConnection *sparql_conn; - TrackerDecoratorPrivate *priv; - GPtrArray *array; - gint i; - - priv = decorator->priv; - - if (!priv->sparql_buffer || priv->sparql_buffer->len == 0) - return FALSE; - - if (priv->commit_buffer) - return FALSE; - - /* Move sparql buffer to commit buffer */ - priv->commit_buffer = priv->sparql_buffer; - priv->sparql_buffer = NULL; - array = g_ptr_array_new (); - - for (i = 0; i < priv->commit_buffer->len; i++) { - SparqlUpdate *update; - - update = &g_array_index (priv->commit_buffer, SparqlUpdate, i); - g_ptr_array_add (array, update->sparql); - } - - sparql_conn = tracker_miner_get_connection (TRACKER_MINER (decorator)); - tracker_sparql_connection_update_array_async (sparql_conn, - (gchar **) array->pdata, - array->len, - G_PRIORITY_DEFAULT, - priv->cancellable, - decorator_commit_cb, - decorator); - - decorator_update_state (decorator, NULL, TRUE); - g_ptr_array_unref (array); - return TRUE; -} - -static gboolean -decorator_check_commit (TrackerDecorator *decorator) -{ - TrackerDecoratorPrivate *priv; - - priv = decorator->priv; - - if (!priv->sparql_buffer || - (priv->n_remaining_items > 0 && - priv->sparql_buffer->len < (guint) priv->batch_size)) - return FALSE; - - return decorator_commit_info (decorator); -} - -static void -decorator_notify_task_error (TrackerDecorator *decorator, - GError *error) -{ - TrackerDecoratorPrivate *priv = decorator->priv; - GTask *task; - - while (!g_queue_is_empty (&priv->next_elem_queue)) { - task = g_queue_pop_head (&priv->next_elem_queue); - g_task_return_error (task, g_error_copy (error)); - g_object_unref (task); - } -} - -static void -decorator_notify_empty (TrackerDecorator *decorator) -{ - GError *error; - - error = g_error_new (tracker_decorator_error_quark (), - TRACKER_DECORATOR_ERROR_EMPTY, - "There are no items left"); - decorator_notify_task_error (decorator, error); - g_error_free (error); -} - -static void -decorator_start (TrackerDecorator *decorator) -{ - TrackerDecoratorPrivate *priv = decorator->priv; - - if (priv->processing) - return; - - priv->processing = TRUE; - g_signal_emit (decorator, signals[ITEMS_AVAILABLE], 0); - decorator_update_state (decorator, "Extracting metadata", TRUE); -} - -static void -decorator_finish (TrackerDecorator *decorator) -{ - TrackerDecoratorPrivate *priv = decorator->priv; - - priv->processing = FALSE; - priv->n_remaining_items = priv->n_processed_items = 0; - g_signal_emit (decorator, signals[FINISHED], 0); - decorator_commit_info (decorator); - decorator_notify_empty (decorator); - decorator_update_state (decorator, "Idle", FALSE); -} - -static void -decorator_rebuild_cache (TrackerDecorator *decorator) -{ - TrackerDecoratorPrivate *priv = decorator->priv; - - priv->n_remaining_items = 0; - g_queue_foreach (&priv->item_cache, - (GFunc) tracker_decorator_info_unref, NULL); - g_queue_clear (&priv->item_cache); - - decorator_cache_next_items (decorator); -} - -/* This function is called after the caller has completed the - * GTask given on the TrackerDecoratorInfo, this definitely removes - * the element being processed from queues. - */ -static void -decorator_task_done (GObject *object, - GAsyncResult *result, - gpointer user_data) -{ - TrackerDecorator *decorator = TRACKER_DECORATOR (object); - TrackerDecoratorInfo *info = user_data; - TrackerDecoratorPrivate *priv; - GError *error = NULL; - gchar *sparql; - - priv = decorator->priv; - sparql = g_task_propagate_pointer (G_TASK (result), &error); - - if (!sparql) { - /* Blacklist item */ - decorator_blacklist_add (decorator, info->id); - - if (error) { - g_warning ("Task for '%s' finished with error: %s\n", - info->url, error->message); - g_error_free (error); - } - } else { - SparqlUpdate update; - - /* Add resulting sparql to buffer and check whether flushing */ - update.sparql = sparql; - update.id = info->id; - - if (!priv->sparql_buffer) - priv->sparql_buffer = sparql_buffer_new (); - - g_array_append_val (priv->sparql_buffer, update); - } - - g_hash_table_remove (priv->tasks, result); - - if (priv->n_remaining_items > 0) - priv->n_remaining_items--; - priv->n_processed_items++; - - decorator_check_commit (decorator); - - if (priv->n_remaining_items == 0) { - decorator_finish (decorator); - decorator_rebuild_cache (decorator); - } else if (g_queue_is_empty (&priv->item_cache) && - g_hash_table_size (priv->tasks) == 0 && - (!priv->sparql_buffer || !priv->commit_buffer)) { - decorator_cache_next_items (decorator); - } -} - -static void -decorator_cancel_active_tasks (TrackerDecorator *decorator) -{ - TrackerDecoratorPrivate *priv = decorator->priv; - GHashTableIter iter; - GTask *task; - - g_hash_table_iter_init (&iter, priv->tasks); - - while (g_hash_table_iter_next (&iter, NULL, (gpointer*) &task)) { - g_cancellable_cancel (g_task_get_cancellable (task)); - } - - g_hash_table_remove_all (priv->tasks); -} - -static void -query_append_id (GString *string, - gint id) -{ - if (string->len > 1 && string->str[string->len - 1] != '(') - g_string_append_c (string, ','); - - g_string_append_printf (string, "%d", id); -} - -static void -query_add_blacklisted_filter (TrackerDecorator *decorator, - GString *query) -{ - TrackerDecoratorPrivate *priv = decorator->priv; - GSequenceIter *iter; - - if (g_sequence_get_length (priv->blacklist_items) == 0) - return; - - g_string_append (query, "&& tracker:id(?urn) NOT IN ("); - - iter = g_sequence_get_begin_iter (priv->blacklist_items); - - while (!g_sequence_iter_is_end (iter)) { - query_append_id (query, GPOINTER_TO_INT (g_sequence_get (iter))); - iter = g_sequence_iter_next (iter); - } - - g_string_append (query, ")"); -} - -static void -query_add_update_buffer_ids (GString *query, - GArray *commit_buffer) -{ - SparqlUpdate *update; - gint i; - - for (i = 0; i < commit_buffer->len; i++) { - update = &g_array_index (commit_buffer, SparqlUpdate, i); - query_append_id (query, update->id); - } -} - -static void -query_add_processing_filter (TrackerDecorator *decorator, - GString *query) -{ - TrackerDecoratorPrivate *priv = decorator->priv; - - if ((!priv->sparql_buffer || priv->sparql_buffer->len == 0) && - (!priv->commit_buffer || priv->commit_buffer->len == 0)) - return; - - g_string_append (query, "&& tracker:id(?urn) NOT IN ("); - - if (priv->sparql_buffer && priv->sparql_buffer->len > 0) - query_add_update_buffer_ids (query, priv->sparql_buffer); - if (priv->commit_buffer && priv->commit_buffer->len > 0) - query_add_update_buffer_ids (query, priv->commit_buffer); - - g_string_append (query, ")"); -} - -static void -query_add_id_filter (GString *query, - GArray *ids) -{ - gint i; - - if (!ids || ids->len == 0) - return; - - g_string_append (query, "&& tracker:id(?urn) IN ("); - - for (i = 0; i < ids->len; i++) { - if (i != 0) - g_string_append (query, ","); - - g_string_append_printf (query, "%d", - g_array_index (ids, gint, i)); - } - - g_string_append (query, ")"); -} - -static void -query_append_current_tasks_filter (TrackerDecorator *decorator, - GString *query) -{ - TrackerDecoratorPrivate *priv = decorator->priv; - GHashTableIter iter; - gint i = 0, id; - GTask *task; - - if (g_hash_table_size (priv->tasks) == 0) - return; - - g_string_append (query, "&& tracker:id(?urn) NOT IN ("); - g_hash_table_iter_init (&iter, priv->tasks); - - while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &task)) { - if (i != 0) - g_string_append (query, ","); - - id = GPOINTER_TO_INT (g_task_get_task_data (task)); - g_string_append_printf (query, "%d", id); - i++; - } - - g_string_append (query, ")"); -} - -static gchar * -create_query_string (TrackerDecorator *decorator, - gchar **select_clauses, - gboolean for_prepended) -{ - TrackerDecoratorPrivate *priv = decorator->priv; - ClassInfo *prev = NULL, *cur; - GString *query; - gint i; - - query = g_string_new ("SELECT "); - - for (i = 0; select_clauses[i]; i++) { - g_string_append_printf (query, "%s ", select_clauses[i]); - } - - g_string_append (query, "{ SELECT ?urn WHERE {"); - - for (i = 0; i < priv->classes->len; i++) { - cur = &g_array_index (priv->classes, ClassInfo, i); - - if (!prev || prev->priority != cur->priority) { - if (prev) - g_string_append (query, "))} UNION "); - - g_string_append_printf (query, - "{ ?urn a rdfs:Resource;" - " a ?type ;" - " tracker:available true ." - " FILTER (! EXISTS { ?urn nie:dataSource <%s> } ", - priv->data_source); - - query_add_blacklisted_filter (decorator, query); - query_add_processing_filter (decorator, query); - - if (for_prepended && priv->prepended_ids->len > 0) { - query_add_id_filter (query, priv->prepended_ids); - g_array_set_size (priv->prepended_ids, 0); - } - - query_append_current_tasks_filter (decorator, query); - g_string_append (query, " && ?type IN ("); - } else { - g_string_append (query, ","); - } - - g_string_append_printf (query, "%s", cur->class_name); - prev = cur; - } - - g_string_append_printf (query, "))}} GROUP BY ?urn } LIMIT %d", QUERY_BATCH_SIZE); - - return g_string_free (query, FALSE); -} - -static gchar * -create_remaining_items_query (TrackerDecorator *decorator) -{ - gchar *clauses[] = { - "?urn", - "tracker:id(?urn)", - "nie:url(?urn)", - "nie:mimeType(?urn)", - NULL - }; - - return create_query_string (decorator, clauses, TRUE); -} - -static void -decorator_query_remaining_items_cb (GObject *object, - GAsyncResult *result, - gpointer user_data) -{ - TrackerDecorator *decorator = user_data; - TrackerDecoratorPrivate *priv; - TrackerSparqlCursor *cursor; - GError *error = NULL; - - cursor = tracker_sparql_connection_query_finish (TRACKER_SPARQL_CONNECTION (object), - result, &error); - - if (error || !tracker_sparql_cursor_next (cursor, NULL, &error)) { - decorator_notify_task_error (decorator, error); - g_error_free (error); - return; - } - - priv = decorator->priv; - priv->querying = FALSE; - - priv->n_remaining_items = g_queue_get_length (&priv->item_cache) + - tracker_sparql_cursor_get_integer (cursor, 0); - g_object_unref (cursor); - - g_debug ("Found %" G_GSIZE_FORMAT " items to extract", priv->n_remaining_items); - - if (priv->n_remaining_items > 0) - decorator_cache_next_items (decorator); - else - decorator_finish (decorator); -} - -static void -decorator_query_remaining_items (TrackerDecorator *decorator) -{ - gchar *query, *clauses[] = { "COUNT(?urn)", NULL }; - TrackerSparqlConnection *sparql_conn; - TrackerDecoratorPrivate *priv; - - priv = decorator->priv; - query = create_query_string (decorator, clauses, FALSE); - - if (query) { - sparql_conn = tracker_miner_get_connection (TRACKER_MINER (decorator)); - tracker_sparql_connection_query_async (sparql_conn, query, - priv->cancellable, - decorator_query_remaining_items_cb, - decorator); - g_free (query); - } else { - decorator_notify_empty (decorator); - } -} - -static void -decorator_pair_tasks (TrackerDecorator *decorator) -{ - TrackerDecoratorPrivate *priv = decorator->priv; - TrackerDecoratorInfo *info; - GTask *task; - - while (!g_queue_is_empty (&priv->item_cache) && - !g_queue_is_empty (&priv->next_elem_queue)) { - info = g_queue_pop_head (&priv->item_cache); - task = g_queue_pop_head (&priv->next_elem_queue); - - g_task_set_task_data (task, GINT_TO_POINTER (info->id), NULL); - - /* Pass ownership of info */ - g_task_return_pointer (task, info, - (GDestroyNotify) tracker_decorator_info_unref); - g_object_unref (task); - - /* Store the decorator-side task in the active task pool */ - g_hash_table_add (priv->tasks, info->task); - } -} - -static void -decorator_item_cache_remove (TrackerDecorator *decorator, - gint id) -{ - TrackerDecoratorPrivate *priv = decorator->priv; - GList *item; - - for (item = g_queue_peek_head_link (&priv->item_cache); - item; item = item->next) { - TrackerDecoratorInfo *info = item->data; - - if (info->id != id) - continue; - - g_queue_remove (&priv->item_cache, info); - tracker_decorator_info_unref (info); - } -} - -static void -decorator_cache_items_cb (GObject *object, - GAsyncResult *result, - gpointer user_data) -{ - TrackerDecorator *decorator = user_data; - TrackerDecoratorPrivate *priv; - TrackerSparqlConnection *conn; - TrackerSparqlCursor *cursor; - TrackerDecoratorInfo *info; - GError *error = NULL; - - conn = TRACKER_SPARQL_CONNECTION (object); - cursor = tracker_sparql_connection_query_finish (conn, result, &error); - priv = decorator->priv; - priv->querying = FALSE; - - if (error) { - decorator_notify_task_error (decorator, error); - g_error_free (error); - } else { - while (tracker_sparql_cursor_next (cursor, NULL, NULL)) { - info = tracker_decorator_info_new (decorator, cursor); - g_queue_push_tail (&priv->item_cache, info); - } - } - - if (!g_queue_is_empty (&priv->item_cache) && !priv->processing) { - decorator_start (decorator); - } else if (g_queue_is_empty (&priv->item_cache) && priv->processing) { - decorator_finish (decorator); - } - - decorator_pair_tasks (decorator); - g_object_unref (cursor); -} - -static void -decorator_cache_next_items (TrackerDecorator *decorator) -{ - TrackerDecoratorPrivate *priv = decorator->priv; - - if (priv->querying || - g_hash_table_size (priv->tasks) > 0 || - !g_queue_is_empty (&priv->item_cache)) - return; - - priv->querying = TRUE; - - if (priv->n_remaining_items == 0) { - decorator_query_remaining_items (decorator); - } else { - TrackerSparqlConnection *sparql_conn; - gchar *query; - - sparql_conn = tracker_miner_get_connection (TRACKER_MINER (decorator)); - query = create_remaining_items_query (decorator); - tracker_sparql_connection_query_async (sparql_conn, query, - priv->cancellable, - decorator_cache_items_cb, - decorator); - g_free (query); - } -} - -static void -update_notifier (TrackerDecorator *decorator) -{ - TrackerDecoratorPrivate *priv = decorator->priv; - - g_clear_object (&priv->notifier); - - if (priv->class_names) { - GError *error = NULL; - - priv->notifier = tracker_notifier_new ((const gchar * const *) priv->class_names, - TRACKER_NOTIFIER_FLAG_NOTIFY_UNEXTRACTED, - NULL, &error); - - if (error) { - g_warning ("Could not create notifier: %s\n", - error->message); - g_error_free (error); - } - - g_signal_connect_swapped (priv->notifier, "events", - G_CALLBACK (notifier_events_cb), - decorator); - } -} - -static void -tracker_decorator_get_property (GObject *object, - guint param_id, - GValue *value, - GParamSpec *pspec) -{ - TrackerDecoratorPrivate *priv; - - priv = TRACKER_DECORATOR (object)->priv; - - switch (param_id) { - case PROP_DATA_SOURCE: - g_value_set_string (value, priv->data_source); - break; - case PROP_CLASS_NAMES: - g_value_set_boxed (value, priv->class_names); - break; - case PROP_COMMIT_BATCH_SIZE: - g_value_set_int (value, priv->batch_size); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); - } -} - -static void -decorator_add_class (TrackerDecorator *decorator, - const gchar *class) -{ - TrackerDecoratorPrivate *priv = decorator->priv; - ClassInfo info; - - info.class_name = g_strdup (class); - info.priority = G_PRIORITY_DEFAULT; - g_array_append_val (priv->classes, info); -} - -static void -decorator_set_classes (TrackerDecorator *decorator, - const gchar **classes) -{ - TrackerDecoratorPrivate *priv = decorator->priv; - gint i; - - g_strfreev (priv->class_names); - priv->class_names = g_strdupv ((gchar **) classes); - - if (priv->classes->len > 0) { - g_array_remove_range (priv->classes, 0, - priv->classes->len); - } - - for (i = 0; classes[i]; i++) { - decorator_add_class (decorator, classes[i]); - } - - update_notifier (decorator); -} - -static void -tracker_decorator_set_property (GObject *object, - guint param_id, - const GValue *value, - GParamSpec *pspec) -{ - TrackerDecorator *decorator = TRACKER_DECORATOR (object); - TrackerDecoratorPrivate *priv; - - priv = decorator->priv; - - switch (param_id) { - case PROP_DATA_SOURCE: - priv->data_source = g_value_dup_string (value); - break; - case PROP_CLASS_NAMES: - decorator_set_classes (decorator, g_value_get_boxed (value)); - break; - case PROP_COMMIT_BATCH_SIZE: - priv->batch_size = g_value_get_int (value); - break; - case PROP_PRIORITY_RDF_TYPES: - tracker_decorator_set_priority_rdf_types (decorator, - g_value_get_boxed (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); - } -} - -static void -notifier_events_cb (TrackerDecorator *decorator, - GPtrArray *events, - TrackerNotifier *notifier) -{ - gboolean check_added = FALSE; - gint64 id; - gint i; - - for (i = 0; i < events->len; i++) { - TrackerNotifierEvent *event; - - event = g_ptr_array_index (events, i); - id = tracker_notifier_event_get_id (event); - - switch (tracker_notifier_event_get_event_type (event)) { - case TRACKER_NOTIFIER_EVENT_CREATE: - case TRACKER_NOTIFIER_EVENT_UPDATE: - /* Merely use this as a hint that there is something - * left to be processed. - */ - check_added = TRUE; - break; - case TRACKER_NOTIFIER_EVENT_DELETE: - decorator_item_cache_remove (decorator, id); - decorator_blacklist_remove (decorator, id); - break; - } - } - - if (check_added) - decorator_cache_next_items (decorator); -} - -static gboolean -tracker_decorator_initable_init (GInitable *initable, - GCancellable *cancellable, - GError **error) -{ - TrackerDecorator *decorator; - - if (!parent_initable_iface->init (initable, cancellable, error)) - return FALSE; - - decorator = TRACKER_DECORATOR (initable); - - if (g_cancellable_is_cancelled (cancellable)) - return FALSE; - - update_notifier (decorator); - - decorator_update_state (decorator, "Idle", FALSE); - return TRUE; -} - -static void -tracker_decorator_initable_iface_init (GInitableIface *iface) -{ - parent_initable_iface = g_type_interface_peek_parent (iface); - iface->init = tracker_decorator_initable_init; -} - -static void -tracker_decorator_constructed (GObject *object) -{ - TrackerDecoratorPrivate *priv; - - G_OBJECT_CLASS (tracker_decorator_parent_class)->constructed (object); - - priv = TRACKER_DECORATOR (object)->priv; - g_assert (priv->data_source); -} - -static void -tracker_decorator_finalize (GObject *object) -{ - TrackerDecoratorPrivate *priv; - TrackerDecorator *decorator; - - decorator = TRACKER_DECORATOR (object); - priv = decorator->priv; - - g_cancellable_cancel (priv->cancellable); - g_clear_object (&priv->cancellable); - - g_clear_object (&priv->notifier); - - g_queue_foreach (&priv->item_cache, - (GFunc) tracker_decorator_info_unref, - NULL); - g_queue_clear (&priv->item_cache); - - decorator_cancel_active_tasks (decorator); - decorator_notify_empty (decorator); - - g_strfreev (priv->class_names); - g_hash_table_destroy (priv->tasks); - g_array_unref (priv->classes); - g_array_unref (priv->prepended_ids); - g_clear_pointer (&priv->sparql_buffer, g_array_unref); - g_clear_pointer (&priv->commit_buffer, g_array_unref); - g_sequence_free (priv->blacklist_items); - g_free (priv->data_source); - g_timer_destroy (priv->timer); - - G_OBJECT_CLASS (tracker_decorator_parent_class)->finalize (object); -} - -static void -tracker_decorator_paused (TrackerMiner *miner) -{ - TrackerDecoratorPrivate *priv; - - decorator_cancel_active_tasks (TRACKER_DECORATOR (miner)); - priv = TRACKER_DECORATOR (miner)->priv; - g_timer_stop (priv->timer); -} - -static void -tracker_decorator_resumed (TrackerMiner *miner) -{ - TrackerDecoratorPrivate *priv; - - decorator_cache_next_items (TRACKER_DECORATOR (miner)); - priv = TRACKER_DECORATOR (miner)->priv; - g_timer_continue (priv->timer); -} - -static void -tracker_decorator_stopped (TrackerMiner *miner) -{ - TrackerDecoratorPrivate *priv; - - decorator_cancel_active_tasks (TRACKER_DECORATOR (miner)); - priv = TRACKER_DECORATOR (miner)->priv; - g_timer_stop (priv->timer); -} - -static void -tracker_decorator_started (TrackerMiner *miner) -{ - TrackerDecoratorPrivate *priv; - TrackerDecorator *decorator; - - decorator = TRACKER_DECORATOR (miner); - priv = decorator->priv; - - g_timer_start (priv->timer); - decorator_rebuild_cache (decorator); -} - -static void -tracker_decorator_class_init (TrackerDecoratorClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - TrackerMinerClass *miner_class = TRACKER_MINER_CLASS (klass); - - object_class->get_property = tracker_decorator_get_property; - object_class->set_property = tracker_decorator_set_property; - object_class->constructed = tracker_decorator_constructed; - object_class->finalize = tracker_decorator_finalize; - - miner_class->paused = tracker_decorator_paused; - miner_class->resumed = tracker_decorator_resumed; - miner_class->started = tracker_decorator_started; - miner_class->stopped = tracker_decorator_stopped; - - g_object_class_install_property (object_class, - PROP_DATA_SOURCE, - g_param_spec_string ("data-source", - "Data source URN", - "nie:DataSource to use in this decorator", - NULL, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); - g_object_class_install_property (object_class, - PROP_CLASS_NAMES, - g_param_spec_boxed ("class-names", - "Class names", - "rdfs:Class objects to listen to for changes", - G_TYPE_STRV, - G_PARAM_READWRITE)); - g_object_class_install_property (object_class, - PROP_COMMIT_BATCH_SIZE, - g_param_spec_int ("commit-batch-size", - "Commit batch size", - "Number of items per update batch", - 0, G_MAXINT, DEFAULT_BATCH_SIZE, - G_PARAM_READWRITE)); - g_object_class_install_property (object_class, - PROP_PRIORITY_RDF_TYPES, - g_param_spec_boxed ("priority-rdf-types", - "Priority RDF types", - "rdf:type that needs to be extracted first", - G_TYPE_STRV, - G_PARAM_WRITABLE)); - /** - * TrackerDecorator::items-available: - * @decorator: the #TrackerDecorator - * - * The ::items-available signal will be emitted whenever the - * #TrackerDecorator sees resources that are available for - * extended metadata extraction. - * - * Since: 0.18 - **/ - signals[ITEMS_AVAILABLE] = - g_signal_new ("items-available", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (TrackerDecoratorClass, - items_available), - NULL, NULL, NULL, - G_TYPE_NONE, 0); - /** - * TrackerDecorator::finished: - * @decorator: the #TrackerDecorator - * - * The ::finished signal will be emitted whenever the - * #TrackerDecorator has finished extracted extended metadata - * for resources in the database. - * - * Since: 0.18 - **/ - signals[FINISHED] = - g_signal_new ("finished", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (TrackerDecoratorClass, finished), - NULL, NULL, NULL, - G_TYPE_NONE, 0); -} - -static void -class_info_clear (ClassInfo *info) -{ - g_free (info->class_name); -} - -static void -tracker_decorator_init (TrackerDecorator *decorator) -{ - TrackerDecoratorPrivate *priv; - - decorator->priv = priv = tracker_decorator_get_instance_private (decorator); - priv->classes = g_array_new (FALSE, FALSE, sizeof (ClassInfo)); - g_array_set_clear_func (priv->classes, (GDestroyNotify) class_info_clear); - priv->blacklist_items = g_sequence_new (NULL); - priv->prepended_ids = g_array_new (FALSE, FALSE, sizeof (gint)); - priv->batch_size = DEFAULT_BATCH_SIZE; - priv->timer = g_timer_new (); - priv->cancellable = g_cancellable_new (); - - g_queue_init (&priv->next_elem_queue); - g_queue_init (&priv->item_cache); - priv->tasks = g_hash_table_new (NULL, NULL); -} - -/** - * tracker_decorator_get_data_source: - * @decorator: a #TrackerDecorator. - * - * The unique string identifying this #TrackerDecorator that has - * extracted the extended metadata. This is essentially an identifier - * so it's clear WHO has extracted this extended metadata. - * - * Returns: a const gchar* or #NULL if an error happened. - * - * Since: 0.18 - **/ -const gchar * -tracker_decorator_get_data_source (TrackerDecorator *decorator) -{ - TrackerDecoratorPrivate *priv; - - g_return_val_if_fail (TRACKER_IS_DECORATOR (decorator), NULL); - - priv = decorator->priv; - return priv->data_source; -} - -/** - * tracker_decorator_get_class_names: - * @decorator: a #TrackerDecorator. - * - * This function returns a string list of class names which are being - * updated with extended metadata. An example would be 'nfo:Document'. - * - * Returns: (transfer none): a const gchar** or #NULL. - * - * Since: 0.18 - **/ -const gchar ** -tracker_decorator_get_class_names (TrackerDecorator *decorator) -{ - TrackerDecoratorPrivate *priv; - - g_return_val_if_fail (TRACKER_IS_DECORATOR (decorator), NULL); - - priv = decorator->priv; - return (const gchar **) priv->class_names; -} - -/** - * tracker_decorator_get_n_items: - * @decorator: a #TrackerDecorator - * - * Get the number of items left in the queue to be processed. This - * indicates content that may already exist in Tracker but is waiting - * to be further flurished with metadata with a 2nd pass extraction or - * index. - * - * Returns: the number of items queued to be processed, always >= 0. - * - * Since: 0.18 - **/ -guint -tracker_decorator_get_n_items (TrackerDecorator *decorator) -{ - TrackerDecoratorPrivate *priv; - - g_return_val_if_fail (TRACKER_IS_DECORATOR (decorator), 0); - - priv = decorator->priv; - - return priv->n_remaining_items; -} - -/** - * tracker_decorator_prepend_id: - * @decorator: a #TrackerDecorator. - * @id: the ID of the resource ID. - * @class_name_id: the ID of the resource's class. - * - * Adds resource needing extended metadata extraction to the queue. - * @id is the same IDs emitted by tracker-store when the database is updated for - * consistency. For details, see the GraphUpdated signal. - * - * Since: 0.18 - **/ -void -tracker_decorator_prepend_id (TrackerDecorator *decorator, - gint id, - gint class_name_id) -{ - TrackerDecoratorPrivate *priv; - - g_return_if_fail (TRACKER_IS_DECORATOR (decorator)); - - priv = decorator->priv; - g_array_append_val (priv->prepended_ids, id); - - /* The resource was explicitly requested, remove it from blacklists */ - decorator_blacklist_remove (decorator, id); -} - -/** - * tracker_decorator_delete_id: - * @decorator: a #TrackerDecorator. - * @id: an ID. - * - * Deletes resource needing extended metadata extraction from the - * queue. @id is the same IDs emitted by tracker-store when the database is - * updated for consistency. For details, see the GraphUpdated signal. - * - * Since: 0.18 - **/ -void -tracker_decorator_delete_id (TrackerDecorator *decorator, - gint id) -{ - TrackerDecoratorPrivate *priv; - guint i; - - g_return_if_fail (TRACKER_IS_DECORATOR (decorator)); - - priv = decorator->priv; - - for (i = 0; i < priv->prepended_ids->len; i++) { - if (id == g_array_index (priv->prepended_ids, gint, i)) { - g_array_remove_index (priv->prepended_ids, i); - break; - } - } - - /* Blacklist the item so it's not processed in the future */ - decorator_blacklist_add (decorator, id); -} - -/** - * tracker_decorator_next: - * @decorator: a #TrackerDecorator. - * @cancellable: a #GCancellable. - * @callback: a #GAsyncReadyCallback. - * @user_data: user_data for @callback. - * - * Processes the next resource in the queue to have extended metadata - * extracted. If the item in the queue has been completed already, it - * signals it's completion instead. - * - * This function will give a #GError if the miner is paused at the - * time it is called. - * - * Since: 0.18 - **/ -void -tracker_decorator_next (TrackerDecorator *decorator, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - TrackerDecoratorPrivate *priv; - GTask *task; - - g_return_if_fail (TRACKER_IS_DECORATOR (decorator)); - - priv = decorator->priv; - - task = g_task_new (decorator, cancellable, callback, user_data); - - if (tracker_miner_is_paused (TRACKER_MINER (decorator))) { - GError *error; - - error = g_error_new (tracker_decorator_error_quark (), - TRACKER_DECORATOR_ERROR_PAUSED, - "Decorator is paused"); - g_task_return_error (task, error); - g_object_unref (task); - return; - } - - g_queue_push_tail (&priv->next_elem_queue, task); - decorator_pair_tasks (decorator); -} - -/** - * tracker_decorator_next_finish: - * @decorator: a #TrackerDecorator. - * @result: a #GAsyncResult. - * @error: return location for a #GError, or NULL. - * - * Should be called in the callback function provided to - * tracker_decorator_next() to return the result of the task be it an - * error or not. - * - * Returns: (transfer full): a #TrackerDecoratorInfo on success or - * #NULL on error. Free with tracker_decorator_info_unref(). - * - * Since: 0.18 - **/ -TrackerDecoratorInfo * -tracker_decorator_next_finish (TrackerDecorator *decorator, - GAsyncResult *result, - GError **error) -{ - g_return_val_if_fail (TRACKER_DECORATOR (decorator), NULL); - g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL); - g_return_val_if_fail (!error || !*error, NULL); - - return g_task_propagate_pointer (G_TASK (result), error); -} - -static gint -class_compare_func (const ClassInfo *a, - const ClassInfo *b) -{ - return b->priority - a->priority; -} - -static void -decorator_set_class_priority (TrackerDecorator *decorator, - const gchar *class, - gint priority) -{ - TrackerDecoratorPrivate *priv = decorator->priv; - ClassInfo *info; - gint i; - - for (i = 0; i < priv->classes->len; i++) { - info = &g_array_index (priv->classes, ClassInfo, i); - - if (strcmp (info->class_name, class) != 0) - continue; - - info->priority = priority; - break; - } -} - -/** - * tracker_decorator_set_priority_rdf_types: - * @decorator: a #TrackerDecorator - * @rdf_types: a string array of rdf types - * - * Re-evaluate the priority queues internally to ensure that - * @rdf_types are handled before all other content. This is useful for - * applications that need their content available sooner than the - * standard time it would take to index content. - * - * Since: 0.18 - **/ -void -tracker_decorator_set_priority_rdf_types (TrackerDecorator *decorator, - const gchar * const *rdf_types) -{ - TrackerDecoratorPrivate *priv; - gint i; - - g_return_if_fail (TRACKER_DECORATOR (decorator)); - g_return_if_fail (rdf_types != NULL); - - priv = decorator->priv; - - for (i = 0; rdf_types[i]; i++) { - decorator_set_class_priority (decorator, rdf_types[i], - G_PRIORITY_HIGH); - } - - g_array_sort (priv->classes, (GCompareFunc) class_compare_func); - decorator_rebuild_cache (decorator); -} - -/** - * tracker_decorator_info_get_urn: - * @info: a #TrackerDecoratorInfo. - * - * A URN is a Uniform Resource Name and should be a unique identifier - * for a resource in the database. - * - * Returns: the URN for #TrackerDecoratorInfo on success or #NULL on error. - * - * Since: 0.18 - **/ -const gchar * -tracker_decorator_info_get_urn (TrackerDecoratorInfo *info) -{ - g_return_val_if_fail (info != NULL, NULL); - return info->urn; -} - -/** - * tracker_decorator_info_get_url: - * @info: a #TrackerDecoratorInfo. - * - * A URL is a Uniform Resource Locator and should be a location associated - * with a resource in the database. For example, 'file:///tmp/foo.txt'. - * - * Returns: the URL for #TrackerDecoratorInfo on success or #NULL on error. - * - * Since: 0.18 - **/ -const gchar * -tracker_decorator_info_get_url (TrackerDecoratorInfo *info) -{ - g_return_val_if_fail (info != NULL, NULL); - return info->url; -} - -/** - * tracker_decorator_info_get_mimetype: - * @info: a #TrackerDecoratorInfo. - * - * A MIME¹ type is a way of describing the content type of a file or - * set of data. An example would be 'text/plain' for a clear text - * document or file. - * - * ¹: http://en.wikipedia.org/wiki/MIME - * - * Returns: the MIME type for #TrackerDecoratorInfo on success or #NULL on error. - * - * Since: 0.18 - **/ -const gchar * -tracker_decorator_info_get_mimetype (TrackerDecoratorInfo *info) -{ - g_return_val_if_fail (info != NULL, NULL); - return info->mimetype; -} - - -/** - * tracker_decorator_info_get_task: - * @info: a #TrackerDecoratorInfo. - * - * Get the #GTask associated with retrieving extended metadata and - * information for a URN in Tracker. - * - * The task object's data (accessible with g_task_get_task_data()) is the - * #TrackerSparqlBuilder. Use tracker_decorator_info_complete() to complete - * the task instead of using this object. - * - * Returns: (transfer none): the #GTask for #TrackerDecoratorInfo on - * success or #NULL if there is no existing #GTask. - * - * Since: 0.18 - **/ -GTask * -tracker_decorator_info_get_task (TrackerDecoratorInfo *info) -{ - g_return_val_if_fail (info != NULL, NULL); - return info->task; -} - -/** - * tracker_decorator_info_complete: - * @info: a #TrackerDecoratorInfo - * @sparql: (transfer full): SPARQL string - * - * Completes the task associated to this #TrackerDecoratorInfo. - * Takes ownership of @sparql. - * - * Since: 2.0 - **/ -void -tracker_decorator_info_complete (TrackerDecoratorInfo *info, - gchar *sparql) -{ - g_task_return_pointer (info->task, sparql, g_free); -} - -/** - * tracker_decorator_info_complete_error: - * @info: a #TrackerDecoratorInfo - * @error: (transfer full): An error occurred during SPARQL generation - * - * Completes the task associated to this #TrackerDecoratorInfo, - * returning the given @error happened during SPARQL generation. - * - * Since: 2.0 - **/ -void -tracker_decorator_info_complete_error (TrackerDecoratorInfo *info, - GError *error) -{ - g_task_return_error (info->task, error); -} - -void -_tracker_decorator_invalidate_cache (TrackerDecorator *decorator) -{ - decorator_rebuild_cache (decorator); -} diff --git a/src/libtracker-miner/tracker-decorator.h b/src/libtracker-miner/tracker-decorator.h deleted file mode 100644 index af00d566f..000000000 --- a/src/libtracker-miner/tracker-decorator.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (C) 2014 Carlos Garnacho <carlosg@gnome.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __LIBTRACKER_MINER_DECORATOR_H__ -#define __LIBTRACKER_MINER_DECORATOR_H__ - -#if !defined (__LIBTRACKER_MINER_H_INSIDE__) && !defined (TRACKER_COMPILATION) -#error "Only <libtracker-miner/tracker-miner.h> can be included directly." -#endif - -#include "tracker-miner-object.h" - -G_BEGIN_DECLS - -#define TRACKER_TYPE_DECORATOR (tracker_decorator_get_type()) -#define TRACKER_DECORATOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_DECORATOR, TrackerDecorator)) -#define TRACKER_DECORATOR_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), TRACKER_TYPE_DECORATOR, TrackerDecoratorClass)) -#define TRACKER_IS_DECORATOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_DECORATOR)) -#define TRACKER_IS_DECORATOR_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), TRACKER_TYPE_DECORATOR)) -#define TRACKER_DECORATOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_DECORATOR, TrackerDecoratorClass)) - -typedef struct _TrackerDecorator TrackerDecorator; -typedef struct _TrackerDecoratorClass TrackerDecoratorClass; -typedef struct _TrackerDecoratorInfo TrackerDecoratorInfo; - -/** - * TrackerDecorator: - * - * Abstract miner object for passive extended metadata indexing, i.e. - * data past the basic information such as file name, size, etc. - **/ -struct _TrackerDecorator { - TrackerMiner parent_instance; - gpointer priv; -}; - -/** - * TrackerDecoratorClass: - * @parent_class: parent object class. - * @items_available: Called when there are resources to be processed. - * @finished: Called when all resources have been processed. - * @padding: Reserved for future API improvements. - * - * An implementation that takes care of extracting extra metadata - * specific to file types by talking to tracker-extract. - * - * Based on #TrackerMinerClass. - **/ -struct _TrackerDecoratorClass { - TrackerMinerClass parent_class; - - void (* items_available) (TrackerDecorator *decorator); - void (* finished) (TrackerDecorator *decorator); - - /* <Private> */ - gpointer padding[10]; -}; - - -/** - * TrackerDecoratorError: - * @TRACKER_DECORATOR_ERROR_EMPTY: There is no item to be processed - * next. It is entirely possible to have a ::items_available signal - * emitted and then have this error when calling - * tracker_decorator_next_finish() because the signal may apply to a - * class which we're not interested in. For example, a new nmo:Email - * might have been added to Tracker, but we might only be interested - * in nfo:Document. This case would give this error. - * @TRACKER_DECORATOR_ERROR_PAUSED: No work was done or will be done - * because the miner is currently paused. - * - * Possible errors returned when calling tracker_decorator_next_finish(). - **/ -typedef enum { - TRACKER_DECORATOR_ERROR_EMPTY, - TRACKER_DECORATOR_ERROR_PAUSED -} TrackerDecoratorError; - - -GType tracker_decorator_get_type (void) G_GNUC_CONST; -GQuark tracker_decorator_error_quark (void); - -const gchar * tracker_decorator_get_data_source (TrackerDecorator *decorator); -const gchar** tracker_decorator_get_class_names (TrackerDecorator *decorator); -guint tracker_decorator_get_n_items (TrackerDecorator *decorator); - -void tracker_decorator_prepend_id (TrackerDecorator *decorator, - gint id, - gint class_name_id); -void tracker_decorator_delete_id (TrackerDecorator *decorator, - gint id); - -void tracker_decorator_next (TrackerDecorator *decorator, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); - -TrackerDecoratorInfo * - tracker_decorator_next_finish (TrackerDecorator *decorator, - GAsyncResult *result, - GError **error); - -void tracker_decorator_set_priority_rdf_types (TrackerDecorator *decorator, - const gchar * const *rdf_types); - -GType tracker_decorator_info_get_type (void) G_GNUC_CONST; - -TrackerDecoratorInfo * - tracker_decorator_info_ref (TrackerDecoratorInfo *info); -void tracker_decorator_info_unref (TrackerDecoratorInfo *info); -const gchar * tracker_decorator_info_get_urn (TrackerDecoratorInfo *info); -const gchar * tracker_decorator_info_get_url (TrackerDecoratorInfo *info); -const gchar * tracker_decorator_info_get_mimetype (TrackerDecoratorInfo *info); -GTask * tracker_decorator_info_get_task (TrackerDecoratorInfo *info); -void tracker_decorator_info_complete (TrackerDecoratorInfo *info, - gchar *sparql); -void tracker_decorator_info_complete_error (TrackerDecoratorInfo *info, - GError *error); - -G_END_DECLS - -#endif /* __LIBTRACKER_MINER_DECORATOR_H__ */ diff --git a/src/libtracker-miner/tracker-file-data-provider.c b/src/libtracker-miner/tracker-file-data-provider.c deleted file mode 100644 index 8f983ce33..000000000 --- a/src/libtracker-miner/tracker-file-data-provider.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright (C) 2014, Softathome <contact@softathome.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Author: Martyn Russell <martyn@lanedo.com> - */ - -#include "config.h" - -#include "tracker-file-data-provider.h" - -static void tracker_file_data_provider_file_iface_init (TrackerDataProviderIface *iface); - -struct _TrackerFileDataProvider { - GObject parent_instance; -}; - -/** - * SECTION:tracker-file-data-provider - * @short_description: File based data provider for file:// descendant URIs - * @include: libtracker-miner/miner.h - * - * #TrackerFileDataProvider is a local file implementation of the - * #TrackerDataProvider interface, charged with handling all file:// type URIs. - * - * Underneath it all, this implementation makes use of GIO-based - * #GFileEnumerator<!-- -->s. - * - * Since: 1.2 - **/ - -G_DEFINE_TYPE_WITH_CODE (TrackerFileDataProvider, tracker_file_data_provider, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (TRACKER_TYPE_DATA_PROVIDER, - tracker_file_data_provider_file_iface_init)) - -static void -tracker_file_data_provider_finalize (GObject *object) -{ - G_OBJECT_CLASS (tracker_file_data_provider_parent_class)->finalize (object); -} - -static void -tracker_file_data_provider_class_init (TrackerFileDataProviderClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - gobject_class->finalize = tracker_file_data_provider_finalize; -} - -static void -tracker_file_data_provider_init (TrackerFileDataProvider *fe) -{ -} - -static GFileEnumerator * -file_data_provider_begin (TrackerDataProvider *data_provider, - GFile *url, - const gchar *attributes, - TrackerDirectoryFlags flags, - GCancellable *cancellable, - GError **error) -{ - GFileQueryInfoFlags file_flags; - GFileEnumerator *fe; - GError *local_error = NULL; - - if (g_cancellable_set_error_if_cancelled (cancellable, error)) { - return NULL; - } - - /* We ignore the TRACKER_DIRECTORY_FLAG_NO_STAT here, it makes - * no sense to be at this point with that flag. So we warn - * about it... - */ - if ((flags & TRACKER_DIRECTORY_FLAG_NO_STAT) != 0) { - g_warning ("Did not expect to have TRACKER_DIRECTORY_FLAG_NO_STAT " - "flag in %s(), continuing anyway...", - __FUNCTION__); - } - - file_flags = G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS; - - fe = g_file_enumerate_children (url, - attributes, - file_flags, - cancellable, - &local_error); - - if (local_error) { - gchar *uri; - - uri = g_file_get_uri (url); - - g_warning ("Could not open directory '%s': %s", - uri, local_error->message); - - g_propagate_error (error, local_error); - g_free (uri); - - return NULL; - } - - return fe; -} - -static void -enumerate_children_cb (GObject *source_object, - GAsyncResult *res, - gpointer user_data) -{ - GFile *url = G_FILE (source_object); - GFileEnumerator *enumerator = NULL; - GTask *task = G_TASK (user_data); - GError *error = NULL; - - enumerator = g_file_enumerate_children_finish (url, res, &error); - if (error) { - if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - gchar *uri; - - uri = g_file_get_uri (url); - g_warning ("Could not open directory '%s': %s", - uri, error->message); - g_free (uri); - } - - g_task_return_error (task, error); - } else { - g_task_return_pointer (task, enumerator, (GDestroyNotify) g_object_unref); - } - - g_object_unref (task); -} - -static void -file_data_provider_begin_async (TrackerDataProvider *data_provider, - GFile *url, - const gchar *attributes, - TrackerDirectoryFlags flags, - int io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GFileQueryInfoFlags file_flags; - GTask *task; - - task = g_task_new (data_provider, cancellable, callback, user_data); - - /* We ignore the TRACKER_DIRECTORY_FLAG_NO_STAT here, it makes - * no sense to be at this point with that flag. So we warn - * about it... - */ - if ((flags & TRACKER_DIRECTORY_FLAG_NO_STAT) != 0) { - g_warning ("Did not expect to have TRACKER_DIRECTORY_FLAG_NO_STAT " - "flag in %s(), continuing anyway...", - __FUNCTION__); - } - - file_flags = G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS; - - g_file_enumerate_children_async (url, - attributes, - file_flags, - io_priority, - cancellable, - enumerate_children_cb, - g_object_ref (task)); - - g_object_unref (task); -} - -static GFileEnumerator * -file_data_provider_begin_finish (TrackerDataProvider *data_provider, - GAsyncResult *result, - GError **error) -{ - g_return_val_if_fail (g_task_is_valid (result, data_provider), NULL); - - return g_task_propagate_pointer (G_TASK (result), error); -} - -static void -tracker_file_data_provider_file_iface_init (TrackerDataProviderIface *iface) -{ - iface->begin = file_data_provider_begin; - iface->begin_async = file_data_provider_begin_async; - iface->begin_finish = file_data_provider_begin_finish; -} - -/** - * tracker_file_data_provider_new: - * - * Creates a new TrackerDataProvider which can be used to create new - * #TrackerMinerFS classes. See #TrackerMinerFS for an example of how - * to use your #TrackerDataProvider. - * - * Returns: (transfer full): a #TrackerDataProvider which must be - * unreferenced with g_object_unref(). - * - * Since: 1.2 - **/ -TrackerDataProvider * -tracker_file_data_provider_new (void) -{ - TrackerFileDataProvider *tfdp; - - tfdp = g_object_new (TRACKER_TYPE_FILE_DATA_PROVIDER, NULL); - - return TRACKER_DATA_PROVIDER (tfdp); -} diff --git a/src/libtracker-miner/tracker-file-data-provider.h b/src/libtracker-miner/tracker-file-data-provider.h deleted file mode 100644 index 945eaa0ab..000000000 --- a/src/libtracker-miner/tracker-file-data-provider.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2014, Softathome <contact@softathome.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Author: Martyn Russell <martyn@lanedo.com> - */ - -#ifndef __LIBTRACKER_MINER_FILE_DATA_PROVIDER_H__ -#define __LIBTRACKER_MINER_FILE_DATA_PROVIDER_H__ - -#include <gio/gio.h> - -#include "tracker-data-provider.h" - -G_BEGIN_DECLS - -#define TRACKER_TYPE_FILE_DATA_PROVIDER (tracker_file_data_provider_get_type ()) -#define TRACKER_FILE_DATA_PROVIDER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_FILE_DATA_PROVIDER, TrackerFileDataProvider)) -#define TRACKER_FILE_DATA_PROVIDER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), TRACKER_TYPE_FILE_DATA_PROVIDER, TrackerFileDataProviderClass)) -#define TRACKER_IS_FILE_DATA_PROVIDER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_FILE_DATA_PROVIDER)) -#define TRACKER_IS_FILE_DATA_PROVIDER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), TRACKER_TYPE_FILE_DATA_PROVIDER)) -#define TRACKER_FILE_DATA_PROVIDER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_FILE_DATA_PROVIDER, TrackerFileDataProviderClass)) - -/** - * TrackerFileDataProvider: - * - * An implementation of the #TrackerDataProvider interface. - **/ -typedef struct _TrackerFileDataProvider TrackerFileDataProvider; -typedef struct _TrackerFileDataProviderClass TrackerFileDataProviderClass; -typedef struct _TrackerFileDataProviderPrivate TrackerFileDataProviderPrivate; - -/** - * TrackerFileDataProviderClass: - * @parent_class: Parent object class. - * - * Prototype for the class implementation. - **/ -struct _TrackerFileDataProviderClass { - GObjectClass parent_class; -}; - -GType tracker_file_data_provider_get_type (void) G_GNUC_CONST; -TrackerDataProvider * tracker_file_data_provider_new (void); - -G_END_DECLS - -#endif /* __LIBTRACKERMINER_FILE_DATA_PROVIDER_H__ */ diff --git a/src/libtracker-miner/tracker-file-notifier.c b/src/libtracker-miner/tracker-file-notifier.c deleted file mode 100644 index addb9c5c2..000000000 --- a/src/libtracker-miner/tracker-file-notifier.c +++ /dev/null @@ -1,2184 +0,0 @@ -/* - * Copyright (C) 2011, Nokia <ivan.frade@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Author: Carlos Garnacho <carlos@lanedo.com> - */ - -#include "config.h" - -#include <libtracker-common/tracker-common.h> -#include <libtracker-sparql/tracker-sparql.h> - -#include "tracker-file-notifier.h" -#include "tracker-file-system.h" -#include "tracker-crawler.h" -#include "tracker-monitor.h" - -static GQuark quark_property_iri = 0; -static GQuark quark_property_store_mtime = 0; -static GQuark quark_property_filesystem_mtime = 0; -static gboolean force_check_updated = FALSE; - -enum { - PROP_0, - PROP_INDEXING_TREE, - PROP_DATA_PROVIDER, - PROP_CONNECTION -}; - -enum { - FILE_CREATED, - FILE_UPDATED, - FILE_DELETED, - FILE_MOVED, - DIRECTORY_STARTED, - DIRECTORY_FINISHED, - FINISHED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -typedef struct { - GFile *root; - GFile *current_dir; - GQueue *pending_dirs; - GPtrArray *query_files; - guint flags; - guint directories_found; - guint directories_ignored; - guint files_found; - guint files_ignored; - guint current_dir_content_filtered : 1; - guint ignore_root : 1; -} RootData; - -typedef struct { - TrackerIndexingTree *indexing_tree; - TrackerFileSystem *file_system; - - TrackerSparqlConnection *connection; - GCancellable *cancellable; - - TrackerCrawler *crawler; - TrackerMonitor *monitor; - TrackerDataProvider *data_provider; - - GTimer *timer; - - /* List of pending directory - * trees to get data from - */ - GList *pending_index_roots; - RootData *current_index_root; - - guint stopped : 1; -} TrackerFileNotifierPrivate; - -typedef struct { - TrackerFileNotifier *notifier; - GNode *cur_parent_node; - - /* Canonical copy from priv->file_system */ - GFile *cur_parent; -} DirectoryCrawledData; - -static gboolean crawl_directories_start (TrackerFileNotifier *notifier); -static void sparql_files_query_start (TrackerFileNotifier *notifier, - GFile **files, - guint n_files); - -G_DEFINE_TYPE_WITH_PRIVATE (TrackerFileNotifier, tracker_file_notifier, G_TYPE_OBJECT) - -static void -tracker_file_notifier_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - TrackerFileNotifierPrivate *priv; - - priv = tracker_file_notifier_get_instance_private (TRACKER_FILE_NOTIFIER (object)); - - switch (prop_id) { - case PROP_INDEXING_TREE: - priv->indexing_tree = g_value_dup_object (value); - break; - case PROP_DATA_PROVIDER: - priv->data_provider = g_value_dup_object (value); - break; - case PROP_CONNECTION: - priv->connection = g_value_dup_object (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -tracker_file_notifier_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - TrackerFileNotifierPrivate *priv; - - priv = tracker_file_notifier_get_instance_private (TRACKER_FILE_NOTIFIER (object)); - - switch (prop_id) { - case PROP_INDEXING_TREE: - g_value_set_object (value, priv->indexing_tree); - break; - case PROP_DATA_PROVIDER: - g_value_set_object (value, priv->data_provider); - break; - case PROP_CONNECTION: - g_value_set_object (value, priv->connection); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static RootData * -root_data_new (TrackerFileNotifier *notifier, - GFile *file, - guint flags, - gboolean ignore_root) -{ - RootData *data; - - data = g_new0 (RootData, 1); - data->root = g_object_ref (file); - data->pending_dirs = g_queue_new (); - data->query_files = g_ptr_array_new_with_free_func (g_object_unref); - data->flags = flags; - data->ignore_root = ignore_root; - - g_queue_push_tail (data->pending_dirs, g_object_ref (file)); - - return data; -} - -static void -root_data_free (RootData *data) -{ - g_queue_free_full (data->pending_dirs, (GDestroyNotify) g_object_unref); - g_ptr_array_unref (data->query_files); - if (data->current_dir) { - g_object_unref (data->current_dir); - } - g_object_unref (data->root); - g_free (data); -} - -/* Crawler signal handlers */ -static gboolean -crawler_check_file_cb (TrackerCrawler *crawler, - GFile *file, - gpointer user_data) -{ - TrackerFileNotifierPrivate *priv; - - priv = tracker_file_notifier_get_instance_private (user_data); - - return tracker_indexing_tree_file_is_indexable (priv->indexing_tree, - file, - G_FILE_TYPE_REGULAR); -} - -static gboolean -crawler_check_directory_cb (TrackerCrawler *crawler, - GFile *directory, - gpointer user_data) -{ - TrackerFileNotifierPrivate *priv; - GFile *root, *canonical; - - priv = tracker_file_notifier_get_instance_private (user_data); - g_assert (priv->current_index_root != NULL); - - canonical = tracker_file_system_peek_file (priv->file_system, directory); - root = tracker_indexing_tree_get_root (priv->indexing_tree, directory, NULL); - - /* If it's a config root itself, other than the one - * currently processed, bypass it, it will be processed - * when the time arrives. - */ - if (canonical && root == canonical && - root != priv->current_index_root->root) { - return FALSE; - } - - return tracker_indexing_tree_file_is_indexable (priv->indexing_tree, - directory, - G_FILE_TYPE_DIRECTORY); -} - -static gboolean -crawler_check_directory_contents_cb (TrackerCrawler *crawler, - GFile *parent, - GList *children, - gpointer user_data) -{ - TrackerFileNotifierPrivate *priv; - gboolean process = TRUE; - - priv = tracker_file_notifier_get_instance_private (user_data); - - /* Do not let content filter apply to configured roots themselves. This - * is a measure to trim undesired portions of the filesystem, and if - * the folder is configured to be indexed, it's clearly not undesired. - */ - if (!tracker_indexing_tree_file_is_root (priv->indexing_tree, parent)) { - process = tracker_indexing_tree_parent_is_indexable (priv->indexing_tree, - parent, children); - } - - if (process) { - TrackerDirectoryFlags parent_flags; - gboolean add_monitor; - - tracker_indexing_tree_get_root (priv->indexing_tree, - parent, &parent_flags); - - add_monitor = (parent_flags & TRACKER_DIRECTORY_FLAG_MONITOR) != 0; - - if (add_monitor) { - tracker_monitor_add (priv->monitor, parent); - } else { - tracker_monitor_remove (priv->monitor, parent); - } - } else { - priv->current_index_root->current_dir_content_filtered = TRUE; - } - - return process; -} - -static gboolean -file_notifier_traverse_tree_foreach (GFile *file, - gpointer user_data) -{ - TrackerFileNotifier *notifier; - TrackerFileNotifierPrivate *priv; - guint64 *store_mtime, *disk_mtime; - GFile *current_root; - - notifier = user_data; - priv = tracker_file_notifier_get_instance_private (notifier); - current_root = priv->current_index_root->current_dir; - - store_mtime = tracker_file_system_steal_property (priv->file_system, file, - quark_property_store_mtime); - disk_mtime = tracker_file_system_steal_property (priv->file_system, file, - quark_property_filesystem_mtime); - - /* If we're crawling over a subdirectory of a root index, it's been - * already notified in the crawling op that made it processed, so avoid - * it here again. - */ - if (current_root == file && - (current_root != priv->current_index_root->root || - priv->current_index_root->ignore_root)) { - g_free (store_mtime); - g_free (disk_mtime); - return FALSE; - } - - if (store_mtime && !disk_mtime) { - /* In store but not in disk, delete */ - g_signal_emit (notifier, signals[FILE_DELETED], 0, file); - - g_free (store_mtime); - g_free (disk_mtime); - return TRUE; - } else if (disk_mtime && !store_mtime) { - /* In disk but not in store, create */ - g_signal_emit (notifier, signals[FILE_CREATED], 0, file); - } else if (store_mtime && disk_mtime && *disk_mtime != *store_mtime) { - /* Mtime changed, update */ - g_signal_emit (notifier, signals[FILE_UPDATED], 0, file, FALSE); - } else if (!store_mtime && !disk_mtime) { - /* what are we doing with such file? should happen rarely, - * only with files that we've queried, but we decided not - * to crawl (i.e. embedded root directories, that would - * be processed when that root is being crawled). - */ - if (file != priv->current_index_root->root && - !tracker_indexing_tree_file_is_root (priv->indexing_tree, file)) { - gchar *uri; - - uri = g_file_get_uri (file); - g_debug ("File '%s' has no disk nor store mtime", - uri); - g_free (uri); - } - } - - g_free (store_mtime); - g_free (disk_mtime); - - return FALSE; -} - -static gboolean -notifier_check_next_root (TrackerFileNotifier *notifier) -{ - TrackerFileNotifierPrivate *priv; - - priv = tracker_file_notifier_get_instance_private (notifier); - g_assert (priv->current_index_root == NULL); - - if (priv->pending_index_roots) { - return crawl_directories_start (notifier); - } else { - g_signal_emit (notifier, signals[FINISHED], 0); - return FALSE; - } -} - -static void -file_notifier_traverse_tree (TrackerFileNotifier *notifier) -{ - TrackerFileNotifierPrivate *priv; - GFile *directory; - - priv = tracker_file_notifier_get_instance_private (notifier); - g_assert (priv->current_index_root != NULL); - - directory = priv->current_index_root->current_dir; - - /* We want the directory and its direct contents, hence depth=2 */ - tracker_file_system_traverse (priv->file_system, - directory, - G_LEVEL_ORDER, - file_notifier_traverse_tree_foreach, - 2, notifier); -} - -static gboolean -file_notifier_is_directory_modified (TrackerFileNotifier *notifier, - GFile *file) -{ - TrackerFileNotifierPrivate *priv; - guint64 *store_mtime, *disk_mtime; - - if (G_UNLIKELY (force_check_updated)) - return TRUE; - - priv = tracker_file_notifier_get_instance_private (notifier); - store_mtime = tracker_file_system_get_property (priv->file_system, file, - quark_property_store_mtime); - disk_mtime = tracker_file_system_get_property (priv->file_system, file, - quark_property_filesystem_mtime); - - return (store_mtime && disk_mtime && *disk_mtime != *store_mtime); -} - -static gboolean -file_notifier_add_node_foreach (GNode *node, - gpointer user_data) -{ - DirectoryCrawledData *data = user_data; - TrackerFileNotifierPrivate *priv; - GFileInfo *file_info; - GFile *canonical, *file; - - priv = tracker_file_notifier_get_instance_private (data->notifier); - file = node->data; - - if (node->parent && - node->parent != data->cur_parent_node) { - data->cur_parent_node = node->parent; - data->cur_parent = tracker_file_system_peek_file (priv->file_system, - node->parent->data); - } else { - data->cur_parent_node = NULL; - data->cur_parent = NULL; - } - - file_info = tracker_crawler_get_file_info (priv->crawler, file); - - if (file_info) { - GFileType file_type; - guint64 time, *time_ptr; - - file_type = g_file_info_get_file_type (file_info); - - /* Intern file in filesystem */ - canonical = tracker_file_system_get_file (priv->file_system, - file, file_type, - data->cur_parent); - - if (priv->current_index_root->flags & TRACKER_DIRECTORY_FLAG_CHECK_MTIME) { - time = g_file_info_get_attribute_uint64 (file_info, - G_FILE_ATTRIBUTE_TIME_MODIFIED); - - time_ptr = g_new (guint64, 1); - *time_ptr = time; - - tracker_file_system_set_property (priv->file_system, canonical, - quark_property_filesystem_mtime, - time_ptr); - } - - g_object_unref (file_info); - - if (file_type == G_FILE_TYPE_DIRECTORY && - (priv->current_index_root->flags & TRACKER_DIRECTORY_FLAG_RECURSE) != 0 && - !G_NODE_IS_ROOT (node)) { - /* Queue child dirs for later processing */ - g_assert (node->children == NULL); - g_queue_push_tail (priv->current_index_root->pending_dirs, - g_object_ref (canonical)); - } - - if (file == priv->current_index_root->root || - !tracker_indexing_tree_file_is_root (priv->indexing_tree, file)) { - g_ptr_array_add (priv->current_index_root->query_files, - g_object_ref (canonical)); - } - } - - return FALSE; -} - -static void -crawler_directory_crawled_cb (TrackerCrawler *crawler, - GFile *directory, - GNode *tree, - guint directories_found, - guint directories_ignored, - guint files_found, - guint files_ignored, - gpointer user_data) -{ - TrackerFileNotifier *notifier; - TrackerFileNotifierPrivate *priv; - DirectoryCrawledData data = { 0 }; - - notifier = data.notifier = user_data; - priv = tracker_file_notifier_get_instance_private (notifier); - - g_node_traverse (tree, - G_PRE_ORDER, - G_TRAVERSE_ALL, - -1, - file_notifier_add_node_foreach, - &data); - - priv->current_index_root->directories_found += directories_found; - priv->current_index_root->directories_ignored += directories_ignored; - priv->current_index_root->files_found += files_found; - priv->current_index_root->files_ignored += files_ignored; -} - -static GFile * -_insert_store_info (TrackerFileNotifier *notifier, - GFile *file, - GFileType file_type, - GFile *parent, - const gchar *iri, - guint64 _time) -{ - TrackerFileNotifierPrivate *priv; - GFile *canonical; - - priv = tracker_file_notifier_get_instance_private (notifier); - canonical = tracker_file_system_get_file (priv->file_system, - file, file_type, - parent); - tracker_file_system_set_property (priv->file_system, canonical, - quark_property_iri, - g_strdup (iri)); - tracker_file_system_set_property (priv->file_system, canonical, - quark_property_store_mtime, - g_memdup (&_time, sizeof (guint64))); - return canonical; -} - -static void -sparql_files_query_populate (TrackerFileNotifier *notifier, - TrackerSparqlCursor *cursor, - gboolean check_root) -{ - TrackerFileNotifierPrivate *priv; - GFile *parent = NULL; - - priv = tracker_file_notifier_get_instance_private (notifier); - - while (tracker_sparql_cursor_next (cursor, NULL, NULL)) { - GFile *file, *canonical, *root; - const gchar *time_str, *iri; - GError *error = NULL; - guint64 _time; - - file = g_file_new_for_uri (tracker_sparql_cursor_get_string (cursor, 0, NULL)); - - if (check_root) { - /* If it's a config root itself, other than the one - * currently processed, bypass it, it will be processed - * when the time arrives. - */ - canonical = tracker_file_system_peek_file (priv->file_system, file); - root = tracker_indexing_tree_get_root (priv->indexing_tree, file, NULL); - - if (canonical && root == file && priv->current_index_root && - root != priv->current_index_root->root) { - g_object_unref (file); - continue; - } - } - - /* All files belong to the same directory */ - if (!parent) - parent = tracker_file_system_peek_parent (priv->file_system, file); - - iri = tracker_sparql_cursor_get_string (cursor, 1, NULL); - time_str = tracker_sparql_cursor_get_string (cursor, 2, NULL); - _time = tracker_string_to_date (time_str, NULL, &error); - - if (error) { - /* This should never happen. Assume that file was modified. */ - g_critical ("Getting store mtime: %s", error->message); - g_clear_error (&error); - _time = 0; - } - - _insert_store_info (notifier, file, - G_FILE_TYPE_UNKNOWN, - parent, iri, _time); - g_object_unref (file); - } -} - -static void -sparql_contents_check_deleted (TrackerFileNotifier *notifier, - TrackerSparqlCursor *cursor) -{ - TrackerFileNotifierPrivate *priv; - GFile *file, *canonical, *parent = NULL; - const gchar *iri; - - priv = tracker_file_notifier_get_instance_private (notifier); - - while (tracker_sparql_cursor_next (cursor, NULL, NULL)) { - const gchar *uri; - gboolean is_folder; - GFileType file_type; - - /* Sometimes URI can be NULL when nie:url and - * nfo:belongsToContainer does not have a strictly 1:1 - * relationship, e.g. data containers where there is - * only one nie:url but many nfo:belongsToContainer - * cases. - */ - uri = tracker_sparql_cursor_get_string (cursor, 0, NULL); - if (!uri) { - continue; - } - - file = g_file_new_for_uri (uri); - iri = tracker_sparql_cursor_get_string (cursor, 1, NULL); - is_folder = tracker_sparql_cursor_get_boolean (cursor, 3); - file_type = is_folder ? G_FILE_TYPE_DIRECTORY : G_FILE_TYPE_UNKNOWN; - canonical = tracker_file_system_peek_file (priv->file_system, file); - - /* All files belong to the same directory */ - if (!parent) - parent = tracker_file_system_peek_parent (priv->file_system, file); - - if (!canonical) { - /* The file exists on the store, but not on the - * crawled content, insert temporarily to handle - * the delete event. - */ - canonical = _insert_store_info (notifier, file, - file_type, - parent, iri, 0); - g_signal_emit (notifier, signals[FILE_DELETED], 0, canonical); - } else if (priv->current_index_root->current_dir_content_filtered || - !tracker_indexing_tree_file_is_indexable (priv->indexing_tree, - canonical, - file_type)) { - /* File is there, but is not indexable anymore, remove too */ - g_signal_emit (notifier, signals[FILE_DELETED], 0, canonical); - } - - g_object_unref (file); - } -} - -static gboolean -crawl_directory_in_current_root (TrackerFileNotifier *notifier) -{ - TrackerFileNotifierPrivate *priv; - GFile *directory; - - priv = tracker_file_notifier_get_instance_private (notifier); - - if (!priv->current_index_root) - return FALSE; - - directory = g_queue_pop_head (priv->current_index_root->pending_dirs); - - if (!directory) - return FALSE; - - priv->current_index_root->current_dir = directory; - - if (priv->cancellable) - g_object_unref (priv->cancellable); - priv->cancellable = g_cancellable_new (); - - /* Begin crawling the directory non-recursively. - * - * - We receive ::check-file, ::check-directory and ::check-directory-contents signals - * during the crawl, which control which directories are crawled and which files are - * returned. - * - We receive ::directory-crawled each time a directory crawl completes. This provides - * the list of contents for a directory. - * - We receive ::finished when the crawler completes. - * - */ - if (!tracker_crawler_start (priv->crawler, - directory, - priv->current_index_root->flags)) { - sparql_files_query_start (notifier, &directory, 1); - } - - return TRUE; -} - -static void -finish_current_directory (TrackerFileNotifier *notifier, - gboolean interrupted) -{ - TrackerFileNotifierPrivate *priv; - GFile *directory; - - priv = tracker_file_notifier_get_instance_private (notifier); - directory = priv->current_index_root->current_dir; - priv->current_index_root->current_dir = NULL; - priv->current_index_root->current_dir_content_filtered = FALSE; - - /* If crawling was interrupted, we take all collected info as invalid. - * Otherwise we dispose regular files here, only directories are - * cached once crawling has completed. - */ - tracker_file_system_forget_files (priv->file_system, - directory, - interrupted ? - G_FILE_TYPE_UNKNOWN : - G_FILE_TYPE_REGULAR); - - if (interrupted || !crawl_directory_in_current_root (notifier)) { - /* No more directories left to be crawled in the current - * root, jump to the next one. - */ - g_signal_emit (notifier, signals[DIRECTORY_FINISHED], 0, - priv->current_index_root->root, - priv->current_index_root->directories_found, - priv->current_index_root->directories_ignored, - priv->current_index_root->files_found, - priv->current_index_root->files_ignored); - - g_info (" Notified files after %2.2f seconds", - g_timer_elapsed (priv->timer, NULL)); - g_info (" Found %d directories, ignored %d directories", - priv->current_index_root->directories_found, - priv->current_index_root->directories_ignored); - g_info (" Found %d files, ignored %d files", - priv->current_index_root->files_found, - priv->current_index_root->files_ignored); - - if (!interrupted) { - g_clear_pointer (&priv->current_index_root, root_data_free); - notifier_check_next_root (notifier); - } - } - - g_object_unref (directory); -} - -static gboolean -root_data_remove_directory (RootData *data, - GFile *directory) -{ - GList *l = data->pending_dirs->head, *next; - GFile *file; - - while (l) { - file = l->data; - next = l->next; - - if (g_file_equal (file, directory) || - g_file_has_prefix (file, directory)) { - g_queue_remove (data->pending_dirs, file); - g_object_unref (file); - } - - l = next; - } - - return (g_file_equal (data->current_dir, directory) || - g_file_has_prefix (data->current_dir, directory)); -} - -static void -file_notifier_current_root_check_remove_directory (TrackerFileNotifier *notifier, - GFile *file) -{ - TrackerFileNotifierPrivate *priv; - - priv = tracker_file_notifier_get_instance_private (notifier); - - if (priv->current_index_root && - root_data_remove_directory (priv->current_index_root, file)) { - g_cancellable_cancel (priv->cancellable); - tracker_crawler_stop (priv->crawler); - - if (!crawl_directory_in_current_root (notifier)) { - g_clear_pointer (&priv->current_index_root, root_data_free); - notifier_check_next_root (notifier); - } - } -} - -/* Query for directory contents, used to look for deleted contents in those */ -static void -sparql_contents_query_cb (GObject *object, - GAsyncResult *result, - gpointer user_data) -{ - TrackerFileNotifier *notifier = TRACKER_FILE_NOTIFIER (user_data); - TrackerSparqlCursor *cursor; - GError *error = NULL; - - cursor = tracker_sparql_connection_query_finish (TRACKER_SPARQL_CONNECTION (object), - result, &error); - if (error) { - if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - g_warning ("Could not query directory contents: %s\n", error->message); - finish_current_directory (notifier, TRUE); - } - goto out; - } - - if (cursor) { - sparql_contents_check_deleted (notifier, cursor); - g_object_unref (cursor); - } - - finish_current_directory (notifier, FALSE); - -out: - if (error) { - g_error_free (error); - } -} - -static gchar * -sparql_contents_compose_query (GFile *directory) -{ - gchar *sparql, *uri; - - uri = g_file_get_uri (directory); - sparql = g_strdup_printf ("SELECT ?url ?u ?lastModified ?isFolder " - "FROM <" TRACKER_OWN_GRAPH_URN "> {" - " ?u nfo:belongsToContainer ?f ;" - " nfo:fileLastModified ?lastModified ;" - " nie:url ?url ." - " OPTIONAL { ?u nie:mimeType ?mimeType . " - " BIND (IF (?mimeType = \"inode/directory\", true, false) AS ?isFolder) } ." - " ?f nie:url ?folderUrl ." - " FILTER (?folderUrl = \"%s\")" - "}", uri); - g_free (uri); - - return sparql; -} - -static void -sparql_contents_query_start (TrackerFileNotifier *notifier, - GFile *directory) -{ - TrackerFileNotifierPrivate *priv; - gchar *sparql; - - priv = tracker_file_notifier_get_instance_private (notifier); - - if (G_UNLIKELY (priv->connection == NULL)) { - return; - } - - sparql = sparql_contents_compose_query (directory); - tracker_sparql_connection_query_async (priv->connection, - sparql, - priv->cancellable, - sparql_contents_query_cb, - notifier); - g_free (sparql); -} - -/* Query for file information, used on all elements found during crawling */ -static void -sparql_files_query_cb (GObject *object, - GAsyncResult *result, - gpointer user_data) -{ - TrackerFileNotifier *notifier = user_data; - TrackerFileNotifierPrivate *priv; - TrackerSparqlCursor *cursor; - gboolean directory_modified; - GError *error = NULL; - GFile *directory; - guint flags; - - priv = tracker_file_notifier_get_instance_private (notifier); - cursor = tracker_sparql_connection_query_finish (TRACKER_SPARQL_CONNECTION (object), - result, &error); - if (error) { - if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - g_warning ("Could not query indexed files: %s\n", error->message); - finish_current_directory (notifier, TRUE); - } - - g_clear_error (&error); - return; - } - - if (cursor) { - sparql_files_query_populate (notifier, cursor, TRUE); - g_object_unref (cursor); - } - - directory = priv->current_index_root->current_dir; - flags = priv->current_index_root->flags; - directory_modified = file_notifier_is_directory_modified (notifier, directory); - - file_notifier_traverse_tree (notifier); - - if ((flags & TRACKER_DIRECTORY_FLAG_CHECK_DELETED) != 0 || - priv->current_index_root->current_dir_content_filtered || - directory_modified) { - /* The directory has updated its mtime, this means something - * was either added or removed in the mean time. Crawling - * will always find all newly added files. But still, we - * must check the contents in the store to handle contents - * having been deleted in the directory. - */ - sparql_contents_query_start (notifier, directory); - } else { - finish_current_directory (notifier, FALSE); - } -} - -static gchar * -sparql_files_compose_query (GFile **files, - guint n_files) -{ - GString *str; - gchar *uri; - gint i = 0; - - str = g_string_new ("SELECT ?url ?u ?lastModified " - "FROM <" TRACKER_OWN_GRAPH_URN "> {" - " ?u a rdfs:Resource ;" - " nfo:fileLastModified ?lastModified ;" - " nie:url ?url . " - " FILTER (?url IN ("); - for (i = 0; i < n_files; i++) { - if (i != 0) - g_string_append_c (str, ','); - - uri = g_file_get_uri (files[i]); - g_string_append_printf (str, "\"%s\"", uri); - g_free (uri); - } - - g_string_append (str, "))}"); - - return g_string_free (str, FALSE); -} - -static void -sparql_files_query_start (TrackerFileNotifier *notifier, - GFile **files, - guint n_files) -{ - TrackerFileNotifierPrivate *priv; - gchar *sparql; - - priv = tracker_file_notifier_get_instance_private (notifier); - - if (G_UNLIKELY (priv->connection == NULL)) { - return; - } - - sparql = sparql_files_compose_query (files, n_files); - tracker_sparql_connection_query_async (priv->connection, - sparql, - priv->cancellable, - sparql_files_query_cb, - notifier); - g_free (sparql); -} - -static gboolean -crawl_directories_start (TrackerFileNotifier *notifier) -{ - TrackerFileNotifierPrivate *priv; - TrackerDirectoryFlags flags; - GFile *directory; - - priv = tracker_file_notifier_get_instance_private (notifier); - - if (priv->current_index_root) { - return FALSE; - } - - if (!priv->pending_index_roots) { - return FALSE; - } - - if (priv->stopped) { - return FALSE; - } - - while (priv->pending_index_roots) { - priv->current_index_root = priv->pending_index_roots->data; - priv->pending_index_roots = g_list_delete_link (priv->pending_index_roots, - priv->pending_index_roots); - directory = priv->current_index_root->root; - flags = priv->current_index_root->flags; - - if ((flags & TRACKER_DIRECTORY_FLAG_IGNORE) == 0 && - crawl_directory_in_current_root (notifier)) { - gchar *uri; - - uri = g_file_get_uri (directory); - g_info ("Processing location: '%s'", uri); - g_free (uri); - - g_timer_reset (priv->timer); - g_signal_emit (notifier, signals[DIRECTORY_STARTED], 0, directory); - - return TRUE; - } else { - /* Emit both signals for consistency */ - g_signal_emit (notifier, signals[DIRECTORY_STARTED], 0, directory); - - if ((flags & TRACKER_DIRECTORY_FLAG_PRESERVE) == 0) { - g_signal_emit (notifier, signals[FILE_DELETED], 0, directory); - } - - g_signal_emit (notifier, signals[DIRECTORY_FINISHED], 0, - directory, 0, 0, 0, 0); - } - - g_clear_pointer (&priv->current_index_root, root_data_free); - } - - g_signal_emit (notifier, signals[FINISHED], 0); - - return FALSE; -} - -static void -crawler_finished_cb (TrackerCrawler *crawler, - gboolean was_interrupted, - gpointer user_data) -{ - TrackerFileNotifier *notifier = user_data; - TrackerFileNotifierPrivate *priv; - GFile *directory; - gboolean check_mtime; - - priv = tracker_file_notifier_get_instance_private (notifier); - - g_assert (priv->current_index_root != NULL); - - if (was_interrupted) { - finish_current_directory (notifier, TRUE); - return; - } - - directory = priv->current_index_root->current_dir; - check_mtime = (priv->current_index_root->flags & TRACKER_DIRECTORY_FLAG_CHECK_MTIME); - - if (priv->current_index_root->query_files->len > 0 && check_mtime && - (directory == priv->current_index_root->root || - tracker_file_system_get_property (priv->file_system, - directory, quark_property_iri))) { - sparql_files_query_start (notifier, - (GFile**) priv->current_index_root->query_files->pdata, - priv->current_index_root->query_files->len); - g_ptr_array_set_size (priv->current_index_root->query_files, 0); - } else { - g_ptr_array_set_size (priv->current_index_root->query_files, 0); - if (check_mtime) - file_notifier_traverse_tree (notifier); - finish_current_directory (notifier, FALSE); - } -} - -static gint -find_directory_root (RootData *data, - GFile *file) -{ - if (data->root == file) - return 0; - return -1; -} - -static void -notifier_queue_root (TrackerFileNotifier *notifier, - GFile *file, - TrackerDirectoryFlags flags, - gboolean ignore_root) -{ - TrackerFileNotifierPrivate *priv; - RootData *data; - - priv = tracker_file_notifier_get_instance_private (notifier); - - if (priv->current_index_root && - priv->current_index_root->root == file) - return; - - if (g_list_find_custom (priv->pending_index_roots, file, - (GCompareFunc) find_directory_root)) - return; - - data = root_data_new (notifier, file, flags, ignore_root); - - if (flags & TRACKER_DIRECTORY_FLAG_PRIORITY) { - priv->pending_index_roots = g_list_prepend (priv->pending_index_roots, data); - } else { - priv->pending_index_roots = g_list_append (priv->pending_index_roots, data); - } - - crawl_directories_start (notifier); -} - -/* This function ensures to issue ::file-created for all - * parent folders that are not yet indexed. Shouldn't happen - * often, it is however possible if MONITOR | !CHECK_MTIME is - * given, and file updates happen on a not previously indexed - * directory. - */ -static void -tracker_file_notifier_ensure_parents (TrackerFileNotifier *notifier, - GFile *file) -{ - TrackerFileNotifierPrivate *priv; - GFile *parent, *canonical; - - priv = tracker_file_notifier_get_instance_private (notifier); - parent = g_file_get_parent (file); - - while (parent) { - if (tracker_file_notifier_get_file_iri (notifier, parent, TRUE)) { - g_object_unref (parent); - break; - } - - canonical = tracker_file_system_get_file (priv->file_system, - parent, - G_FILE_TYPE_DIRECTORY, - NULL); - g_object_unref (parent); - - g_signal_emit (notifier, signals[FILE_CREATED], 0, canonical); - - if (tracker_indexing_tree_file_is_root (priv->indexing_tree, canonical)) { - break; - } - - parent = g_file_get_parent (canonical); - } -} - -/* Monitor signal handlers */ -static void -monitor_item_created_cb (TrackerMonitor *monitor, - GFile *file, - gboolean is_directory, - gpointer user_data) -{ - TrackerFileNotifier *notifier = user_data; - TrackerFileNotifierPrivate *priv; - GFileType file_type; - GFile *canonical; - gboolean indexable; - - priv = tracker_file_notifier_get_instance_private (notifier); - file_type = (is_directory) ? G_FILE_TYPE_DIRECTORY : G_FILE_TYPE_REGULAR; - - indexable = tracker_indexing_tree_file_is_indexable (priv->indexing_tree, - file, file_type); - - if (!is_directory) { - gboolean parent_indexable; - GList *children; - GFile *parent; - - parent = g_file_get_parent (file); - - if (parent) { - children = g_list_prepend (NULL, file); - parent_indexable = tracker_indexing_tree_parent_is_indexable (priv->indexing_tree, - parent, - children); - g_list_free (children); - - if (!parent_indexable) { - /* New file triggered a directory content - * filter, remove parent directory altogether - */ - canonical = tracker_file_system_get_file (priv->file_system, - parent, G_FILE_TYPE_DIRECTORY, - NULL); - g_object_unref (parent); - - g_object_ref (canonical); - g_signal_emit (notifier, signals[FILE_DELETED], 0, canonical); - file_notifier_current_root_check_remove_directory (notifier, canonical); - tracker_file_system_forget_files (priv->file_system, canonical, - G_FILE_TYPE_UNKNOWN); - - tracker_monitor_remove_recursively (priv->monitor, canonical); - - g_object_unref (canonical); - return; - } - - g_object_unref (parent); - } - - if (!indexable) - return; - } else { - TrackerDirectoryFlags flags; - - if (!indexable) - return; - - /* If config for the directory is recursive, - * Crawl new entire directory and add monitors - */ - tracker_indexing_tree_get_root (priv->indexing_tree, - file, &flags); - - if (flags & TRACKER_DIRECTORY_FLAG_RECURSE) { - canonical = tracker_file_system_get_file (priv->file_system, - file, - file_type, - NULL); - notifier_queue_root (notifier, canonical, flags, TRUE); - - /* Fall though, we want ::file-created to be emitted - * ASAP so it is ensured to be processed before any - * possible monitor events we might get afterwards. - */ - } - } - - tracker_file_notifier_ensure_parents (notifier, file); - - /* Fetch the interned copy */ - canonical = tracker_file_system_get_file (priv->file_system, - file, file_type, NULL); - - g_signal_emit (notifier, signals[FILE_CREATED], 0, canonical); - - if (!is_directory) { - tracker_file_system_forget_files (priv->file_system, canonical, - G_FILE_TYPE_REGULAR); - } -} - -static void -monitor_item_updated_cb (TrackerMonitor *monitor, - GFile *file, - gboolean is_directory, - gpointer user_data) -{ - TrackerFileNotifier *notifier = user_data; - TrackerFileNotifierPrivate *priv; - GFileType file_type; - GFile *canonical; - - priv = tracker_file_notifier_get_instance_private (notifier); - file_type = (is_directory) ? G_FILE_TYPE_DIRECTORY : G_FILE_TYPE_REGULAR; - - if (!tracker_indexing_tree_file_is_indexable (priv->indexing_tree, - file, file_type)) { - /* File should not be indexed */ - return; - } - - tracker_file_notifier_ensure_parents (notifier, file); - - /* Fetch the interned copy */ - canonical = tracker_file_system_get_file (priv->file_system, - file, file_type, NULL); - g_signal_emit (notifier, signals[FILE_UPDATED], 0, canonical, FALSE); - - if (!is_directory) { - tracker_file_system_forget_files (priv->file_system, canonical, - G_FILE_TYPE_REGULAR); - } -} - -static void -monitor_item_attribute_updated_cb (TrackerMonitor *monitor, - GFile *file, - gboolean is_directory, - gpointer user_data) -{ - TrackerFileNotifier *notifier = user_data; - TrackerFileNotifierPrivate *priv; - GFile *canonical; - GFileType file_type; - - priv = tracker_file_notifier_get_instance_private (notifier); - file_type = (is_directory) ? G_FILE_TYPE_DIRECTORY : G_FILE_TYPE_REGULAR; - - if (!tracker_indexing_tree_file_is_indexable (priv->indexing_tree, - file, file_type)) { - /* File should not be indexed */ - return; - } - - /* Fetch the interned copy */ - canonical = tracker_file_system_get_file (priv->file_system, - file, file_type, NULL); - g_signal_emit (notifier, signals[FILE_UPDATED], 0, canonical, TRUE); - - if (!is_directory) { - tracker_file_system_forget_files (priv->file_system, canonical, - G_FILE_TYPE_REGULAR); - } -} - -static void -monitor_item_deleted_cb (TrackerMonitor *monitor, - GFile *file, - gboolean is_directory, - gpointer user_data) -{ - TrackerFileNotifier *notifier = user_data; - TrackerFileNotifierPrivate *priv; - GFile *canonical; - GFileType file_type; - - priv = tracker_file_notifier_get_instance_private (notifier); - file_type = (is_directory) ? G_FILE_TYPE_DIRECTORY : G_FILE_TYPE_REGULAR; - - /* Remove monitors if any */ - if (is_directory && - tracker_indexing_tree_file_is_root (priv->indexing_tree, file)) { - tracker_monitor_remove_children_recursively (priv->monitor, - file); - } else if (is_directory) { - tracker_monitor_remove_recursively (priv->monitor, file); - } - - if (!is_directory) { - TrackerDirectoryFlags flags; - gboolean indexable; - GList *children; - GFile *parent; - - children = g_list_prepend (NULL, file); - parent = g_file_get_parent (file); - - indexable = tracker_indexing_tree_parent_is_indexable (priv->indexing_tree, - parent, children); - g_list_free (children); - - /* note: This supposedly works, but in practice - * won't ever happen as we don't get monitor events - * from directories triggering a filter of type - * TRACKER_FILTER_PARENT_DIRECTORY. - */ - if (!indexable) { - /* New file was triggering a directory content - * filter, reindex parent directory altogether - */ - canonical = tracker_file_system_get_file (priv->file_system, - parent, - G_FILE_TYPE_DIRECTORY, - NULL); - tracker_indexing_tree_get_root (priv->indexing_tree, - canonical, &flags); - notifier_queue_root (notifier, canonical, flags, FALSE); - return; - } - - g_object_unref (parent); - } - - if (!tracker_indexing_tree_file_is_indexable (priv->indexing_tree, - file, file_type)) { - /* File was not indexed */ - return ; - } - - /* Fetch the interned copy */ - canonical = tracker_file_system_get_file (priv->file_system, - file, file_type, NULL); - - /* tracker_file_system_forget_files() might already have been - * called on this file. In this case, the object might become - * invalid when returning from g_signal_emit(). Take a - * reference in order to prevent that. - */ - g_object_ref (canonical); - g_signal_emit (notifier, signals[FILE_DELETED], 0, canonical); - - file_notifier_current_root_check_remove_directory (notifier, canonical); - - /* Remove the file from the cache (works recursively for directories) */ - tracker_file_system_forget_files (priv->file_system, - canonical, - G_FILE_TYPE_UNKNOWN); - g_object_unref (canonical); -} - -static gboolean -extension_changed (GFile *file1, - GFile *file2) -{ - gchar *basename1, *basename2; - const gchar *ext1, *ext2; - gboolean changed; - - basename1 = g_file_get_basename (file1); - basename2 = g_file_get_basename (file2); - - ext1 = strrchr (basename1, '.'); - ext2 = strrchr (basename2, '.'); - - changed = g_strcmp0 (ext1, ext2) != 0; - - g_free (basename1); - g_free (basename2); - - return changed; -} - -static void -monitor_item_moved_cb (TrackerMonitor *monitor, - GFile *file, - GFile *other_file, - gboolean is_directory, - gboolean is_source_monitored, - gpointer user_data) -{ - TrackerFileNotifier *notifier; - TrackerFileNotifierPrivate *priv; - TrackerDirectoryFlags flags; - - notifier = user_data; - priv = tracker_file_notifier_get_instance_private (notifier); - tracker_indexing_tree_get_root (priv->indexing_tree, other_file, &flags); - - if (!is_source_monitored) { - if (is_directory) { - /* Remove monitors if any */ - tracker_monitor_remove_recursively (priv->monitor, file); - - /* If should recurse, crawl other_file, as content is "new" */ - other_file = tracker_file_system_get_file (priv->file_system, - other_file, - G_FILE_TYPE_DIRECTORY, - NULL); - notifier_queue_root (notifier, other_file, flags, FALSE); - } - /* else, file, do nothing */ - } else { - gboolean source_stored, should_process_other; - GFileType file_type; - GFile *check_file; - - if (is_directory) { - check_file = g_object_ref (file); - } else { - check_file = g_file_get_parent (file); - } - - file_type = (is_directory) ? G_FILE_TYPE_DIRECTORY : G_FILE_TYPE_REGULAR; - - /* If the (parent) directory is in - * the filesystem, file is stored - */ - source_stored = (tracker_file_system_peek_file (priv->file_system, - check_file) != NULL); - should_process_other = tracker_indexing_tree_file_is_indexable (priv->indexing_tree, - other_file, - file_type); - g_object_unref (check_file); - - file = tracker_file_system_get_file (priv->file_system, - file, file_type, - NULL); - other_file = tracker_file_system_get_file (priv->file_system, - other_file, file_type, - NULL); - - /* Ref those so they are safe to use after signal emission */ - g_object_ref (file); - g_object_ref (other_file); - - if (!source_stored) { - /* Destination location should be indexed as if new */ - /* Remove monitors if any */ - if (is_directory) { - tracker_monitor_remove_recursively (priv->monitor, - file); - } - - if (should_process_other) { - gboolean dest_is_recursive; - TrackerDirectoryFlags flags; - - tracker_indexing_tree_get_root (priv->indexing_tree, other_file, &flags); - dest_is_recursive = (flags & TRACKER_DIRECTORY_FLAG_RECURSE) != 0; - - /* Source file was not stored, check dest file as new */ - if (!is_directory || !dest_is_recursive) { - g_signal_emit (notifier, signals[FILE_CREATED], 0, other_file); - } else if (is_directory) { - /* Crawl dest directory */ - notifier_queue_root (notifier, other_file, flags, FALSE); - } - } - /* Else, do nothing else */ - } else if (!should_process_other) { - /* Delete original location as it moves to be non indexable */ - if (is_directory) { - tracker_monitor_remove_recursively (priv->monitor, - file); - } - - g_signal_emit (notifier, signals[FILE_DELETED], 0, file); - file_notifier_current_root_check_remove_directory (notifier, file); - } else { - /* Handle move */ - if (is_directory) { - gboolean dest_is_recursive, source_is_recursive; - TrackerDirectoryFlags source_flags; - - tracker_monitor_move (priv->monitor, - file, other_file); - - tracker_indexing_tree_get_root (priv->indexing_tree, - file, &source_flags); - source_is_recursive = (source_flags & TRACKER_DIRECTORY_FLAG_RECURSE) != 0; - dest_is_recursive = (flags & TRACKER_DIRECTORY_FLAG_RECURSE) != 0; - - if (source_is_recursive && !dest_is_recursive) { - /* A directory is being moved from a - * recursive location to a non-recursive - * one, don't do anything here, and let - * TrackerMinerFS handle it, see item_move(). - */ - } else if (!source_is_recursive && dest_is_recursive) { - /* crawl the folder */ - notifier_queue_root (notifier, other_file, flags, TRUE); - } - } - - g_signal_emit (notifier, signals[FILE_MOVED], 0, file, other_file); - - if (extension_changed (file, other_file)) - g_signal_emit (notifier, signals[FILE_UPDATED], 0, other_file, FALSE); - } - - tracker_file_system_forget_files (priv->file_system, file, - G_FILE_TYPE_REGULAR); - - if (!is_directory) { - tracker_file_system_forget_files (priv->file_system, other_file, - G_FILE_TYPE_REGULAR); - } - - g_object_unref (other_file); - g_object_unref (file); - } -} - -/* Indexing tree signal handlers */ -static void -indexing_tree_directory_added (TrackerIndexingTree *indexing_tree, - GFile *directory, - gpointer user_data) -{ - TrackerFileNotifier *notifier = user_data; - TrackerFileNotifierPrivate *priv; - TrackerDirectoryFlags flags; - - priv = tracker_file_notifier_get_instance_private (notifier); - tracker_indexing_tree_get_root (indexing_tree, directory, &flags); - - directory = tracker_file_system_get_file (priv->file_system, directory, - G_FILE_TYPE_DIRECTORY, NULL); - notifier_queue_root (notifier, directory, flags, FALSE); -} - -static void -indexing_tree_directory_updated (TrackerIndexingTree *indexing_tree, - GFile *directory, - gpointer user_data) -{ - TrackerFileNotifier *notifier = user_data; - TrackerFileNotifierPrivate *priv; - TrackerDirectoryFlags flags; - - priv = tracker_file_notifier_get_instance_private (notifier); - tracker_indexing_tree_get_root (indexing_tree, directory, &flags); - flags |= TRACKER_DIRECTORY_FLAG_CHECK_DELETED; - - directory = tracker_file_system_get_file (priv->file_system, directory, - G_FILE_TYPE_DIRECTORY, NULL); - notifier_queue_root (notifier, directory, flags, FALSE); -} - -static void -indexing_tree_directory_removed (TrackerIndexingTree *indexing_tree, - GFile *directory, - gpointer user_data) -{ - TrackerFileNotifier *notifier = user_data; - TrackerFileNotifierPrivate *priv; - TrackerDirectoryFlags flags; - GList *elem; - - priv = tracker_file_notifier_get_instance_private (notifier); - - /* Flags are still valid at the moment of deletion */ - tracker_indexing_tree_get_root (indexing_tree, directory, &flags); - directory = tracker_file_system_peek_file (priv->file_system, directory); - - if (!directory) { - /* If the dir has no canonical copy, - * it wasn't even told to be indexed. - */ - return; - } - - /* If the folder was being ignored, index/crawl it from scratch */ - if (flags & TRACKER_DIRECTORY_FLAG_IGNORE) { - GFile *parent; - - parent = g_file_get_parent (directory); - - if (parent) { - TrackerDirectoryFlags parent_flags; - - tracker_indexing_tree_get_root (indexing_tree, - parent, - &parent_flags); - - if (parent_flags & TRACKER_DIRECTORY_FLAG_RECURSE) { - notifier_queue_root (notifier, directory, parent_flags, FALSE); - } else if (tracker_indexing_tree_file_is_root (indexing_tree, - parent)) { - g_signal_emit (notifier, signals[FILE_CREATED], - 0, directory); - } - - g_object_unref (parent); - } - return; - } - - if ((flags & TRACKER_DIRECTORY_FLAG_PRESERVE) == 0) { - /* Directory needs to be deleted from the store too */ - g_signal_emit (notifier, signals[FILE_DELETED], 0, directory); - } - - elem = g_list_find_custom (priv->pending_index_roots, directory, - (GCompareFunc) find_directory_root); - - if (elem) { - root_data_free (elem->data); - priv->pending_index_roots = - g_list_delete_link (priv->pending_index_roots, elem); - } - - if (priv->current_index_root && - directory == priv->current_index_root->root) { - /* Directory being currently processed */ - tracker_crawler_stop (priv->crawler); - g_cancellable_cancel (priv->cancellable); - - /* If the crawler was already stopped (eg. we're at the querying - * phase), the current index root won't be cleared. - */ - g_clear_pointer (&priv->current_index_root, root_data_free); - notifier_check_next_root (notifier); - } - - /* Remove monitors if any */ - /* FIXME: How do we handle this with 3rd party data_providers? */ - tracker_monitor_remove_recursively (priv->monitor, directory); - - /* Remove all files from cache */ - tracker_file_system_forget_files (priv->file_system, directory, - G_FILE_TYPE_UNKNOWN); -} - -static void -indexing_tree_child_updated (TrackerIndexingTree *indexing_tree, - GFile *root, - GFile *child, - gpointer user_data) -{ - TrackerFileNotifier *notifier = user_data; - TrackerFileNotifierPrivate *priv; - TrackerDirectoryFlags flags; - GFileType child_type; - GFile *canonical; - - priv = tracker_file_notifier_get_instance_private (notifier); - - child_type = g_file_query_file_type (child, - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, - NULL); - - if (child_type == G_FILE_TYPE_UNKNOWN) - return; - - canonical = tracker_file_system_get_file (priv->file_system, - child, child_type, NULL); - tracker_indexing_tree_get_root (indexing_tree, child, &flags); - - if (child_type == G_FILE_TYPE_DIRECTORY && - (flags & TRACKER_DIRECTORY_FLAG_RECURSE)) { - flags |= TRACKER_DIRECTORY_FLAG_CHECK_DELETED; - - notifier_queue_root (notifier, canonical, flags, FALSE); - } else if (tracker_indexing_tree_file_is_indexable (priv->indexing_tree, - canonical, child_type)) { - g_signal_emit (notifier, signals[FILE_UPDATED], 0, canonical, FALSE); - } -} - -static void -tracker_file_notifier_finalize (GObject *object) -{ - TrackerFileNotifierPrivate *priv; - - priv = tracker_file_notifier_get_instance_private (TRACKER_FILE_NOTIFIER (object)); - - if (priv->indexing_tree) { - g_object_unref (priv->indexing_tree); - } - - if (priv->data_provider) { - g_object_unref (priv->data_provider); - } - - if (priv->cancellable) { - g_cancellable_cancel (priv->cancellable); - g_object_unref (priv->cancellable); - } - - g_object_unref (priv->crawler); - g_object_unref (priv->monitor); - g_object_unref (priv->file_system); - g_clear_object (&priv->connection); - - g_clear_pointer (&priv->current_index_root, root_data_free); - - g_list_foreach (priv->pending_index_roots, (GFunc) root_data_free, NULL); - g_list_free (priv->pending_index_roots); - g_timer_destroy (priv->timer); - - G_OBJECT_CLASS (tracker_file_notifier_parent_class)->finalize (object); -} - -static void -check_disable_monitor (TrackerFileNotifier *notifier) -{ - TrackerFileNotifierPrivate *priv; - TrackerSparqlCursor *cursor; - gint64 folder_count = 0; - GError *error = NULL; - - priv = tracker_file_notifier_get_instance_private (notifier); - cursor = tracker_sparql_connection_query (priv->connection, - "SELECT COUNT(?f) { ?f a nfo:Folder }", - NULL, &error); - - if (!error && tracker_sparql_cursor_next (cursor, NULL, &error)) { - folder_count = tracker_sparql_cursor_get_integer (cursor, 0); - tracker_sparql_cursor_close (cursor); - } - - if (error) { - g_warning ("Could not get folder count: %s\n", error->message); - g_error_free (error); - } else if (folder_count > tracker_monitor_get_limit (priv->monitor)) { - /* If the folder count exceeds the monitor limit, there's - * nothing we can do anyway to prevent possibly out of date - * content. As it is the case no matter what we try, fully - * embrace it instead, and disable monitors until after crawling - * has been performed. This dramatically improves crawling time - * as monitors are inherently expensive. - */ - g_info ("Temporarily disabling monitors until crawling is " - "completed. Too many folders to monitor anyway"); - tracker_monitor_set_enabled (priv->monitor, FALSE); - } - - g_clear_object (&cursor); -} - -static void -tracker_file_notifier_constructed (GObject *object) -{ - TrackerFileNotifierPrivate *priv; - GFile *root; - - G_OBJECT_CLASS (tracker_file_notifier_parent_class)->constructed (object); - - priv = tracker_file_notifier_get_instance_private (TRACKER_FILE_NOTIFIER (object)); - g_assert (priv->indexing_tree); - - /* Initialize filesystem and register properties */ - root = tracker_indexing_tree_get_master_root (priv->indexing_tree); - priv->file_system = tracker_file_system_new (root); - - g_signal_connect (priv->indexing_tree, "directory-added", - G_CALLBACK (indexing_tree_directory_added), object); - g_signal_connect (priv->indexing_tree, "directory-updated", - G_CALLBACK (indexing_tree_directory_updated), object); - g_signal_connect (priv->indexing_tree, "directory-removed", - G_CALLBACK (indexing_tree_directory_removed), object); - g_signal_connect (priv->indexing_tree, "child-updated", - G_CALLBACK (indexing_tree_child_updated), object); - - /* Set up crawler */ - priv->crawler = tracker_crawler_new (priv->data_provider); - tracker_crawler_set_file_attributes (priv->crawler, - G_FILE_ATTRIBUTE_TIME_MODIFIED "," - G_FILE_ATTRIBUTE_STANDARD_TYPE); - - g_signal_connect (priv->crawler, "check-file", - G_CALLBACK (crawler_check_file_cb), - object); - g_signal_connect (priv->crawler, "check-directory", - G_CALLBACK (crawler_check_directory_cb), - object); - g_signal_connect (priv->crawler, "check-directory-contents", - G_CALLBACK (crawler_check_directory_contents_cb), - object); - g_signal_connect (priv->crawler, "directory-crawled", - G_CALLBACK (crawler_directory_crawled_cb), - object); - g_signal_connect (priv->crawler, "finished", - G_CALLBACK (crawler_finished_cb), - object); - - check_disable_monitor (TRACKER_FILE_NOTIFIER (object)); -} - -static void -tracker_file_notifier_real_finished (TrackerFileNotifier *notifier) -{ - TrackerFileNotifierPrivate *priv; - - priv = tracker_file_notifier_get_instance_private (notifier); - - if (!tracker_monitor_get_enabled (priv->monitor)) { - /* If the monitor was disabled on ::constructed (see - * check_disable_monitor()), enable it back again. - * This will lazily create all missing directory - * monitors. - */ - g_info ("Re-enabling directory monitors"); - tracker_monitor_set_enabled (priv->monitor, TRUE); - } -} - -static void -tracker_file_notifier_class_init (TrackerFileNotifierClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = tracker_file_notifier_finalize; - object_class->set_property = tracker_file_notifier_set_property; - object_class->get_property = tracker_file_notifier_get_property; - object_class->constructed = tracker_file_notifier_constructed; - - klass->finished = tracker_file_notifier_real_finished; - - signals[FILE_CREATED] = - g_signal_new ("file-created", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (TrackerFileNotifierClass, - file_created), - NULL, NULL, - NULL, - G_TYPE_NONE, - 1, G_TYPE_FILE); - signals[FILE_UPDATED] = - g_signal_new ("file-updated", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (TrackerFileNotifierClass, - file_updated), - NULL, NULL, - NULL, - G_TYPE_NONE, - 2, G_TYPE_FILE, G_TYPE_BOOLEAN); - signals[FILE_DELETED] = - g_signal_new ("file-deleted", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (TrackerFileNotifierClass, - file_deleted), - NULL, NULL, - NULL, - G_TYPE_NONE, - 1, G_TYPE_FILE); - signals[FILE_MOVED] = - g_signal_new ("file-moved", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (TrackerFileNotifierClass, - file_moved), - NULL, NULL, - NULL, - G_TYPE_NONE, - 2, G_TYPE_FILE, G_TYPE_FILE); - signals[DIRECTORY_STARTED] = - g_signal_new ("directory-started", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (TrackerFileNotifierClass, - directory_started), - NULL, NULL, - NULL, - G_TYPE_NONE, - 1, G_TYPE_FILE); - signals[DIRECTORY_FINISHED] = - g_signal_new ("directory-finished", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (TrackerFileNotifierClass, - directory_finished), - NULL, NULL, - NULL, - G_TYPE_NONE, - 5, G_TYPE_FILE, G_TYPE_UINT, - G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT); - signals[FINISHED] = - g_signal_new ("finished", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (TrackerFileNotifierClass, - finished), - NULL, NULL, - NULL, - G_TYPE_NONE, 0, G_TYPE_NONE); - - g_object_class_install_property (object_class, - PROP_INDEXING_TREE, - g_param_spec_object ("indexing-tree", - "Indexing tree", - "Indexing tree", - TRACKER_TYPE_INDEXING_TREE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); - g_object_class_install_property (object_class, - PROP_DATA_PROVIDER, - g_param_spec_object ("data-provider", - "Data provider", - "Data provider to use to crawl structures populating data, e.g. like GFileEnumerator", - TRACKER_TYPE_DATA_PROVIDER, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); - g_object_class_install_property (object_class, - PROP_CONNECTION, - g_param_spec_object ("connection", - "Connection", - "Connection to use for queries", - TRACKER_SPARQL_TYPE_CONNECTION, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); - - /* Initialize property quarks */ - quark_property_iri = g_quark_from_static_string ("tracker-property-iri"); - tracker_file_system_register_property (quark_property_iri, g_free); - - quark_property_store_mtime = g_quark_from_static_string ("tracker-property-store-mtime"); - tracker_file_system_register_property (quark_property_store_mtime, - g_free); - - quark_property_filesystem_mtime = g_quark_from_static_string ("tracker-property-filesystem-mtime"); - tracker_file_system_register_property (quark_property_filesystem_mtime, - g_free); - - force_check_updated = g_getenv ("TRACKER_MINER_FORCE_CHECK_UPDATED") != NULL; -} - -static void -tracker_file_notifier_init (TrackerFileNotifier *notifier) -{ - TrackerFileNotifierPrivate *priv; - - priv = tracker_file_notifier_get_instance_private (notifier); - priv->timer = g_timer_new (); - priv->stopped = TRUE; - - /* Set up monitor */ - priv->monitor = tracker_monitor_new (); - - g_signal_connect (priv->monitor, "item-created", - G_CALLBACK (monitor_item_created_cb), - notifier); - g_signal_connect (priv->monitor, "item-updated", - G_CALLBACK (monitor_item_updated_cb), - notifier); - g_signal_connect (priv->monitor, "item-attribute-updated", - G_CALLBACK (monitor_item_attribute_updated_cb), - notifier); - g_signal_connect (priv->monitor, "item-deleted", - G_CALLBACK (monitor_item_deleted_cb), - notifier); - g_signal_connect (priv->monitor, "item-moved", - G_CALLBACK (monitor_item_moved_cb), - notifier); -} - -TrackerFileNotifier * -tracker_file_notifier_new (TrackerIndexingTree *indexing_tree, - TrackerDataProvider *data_provider, - TrackerSparqlConnection *connection) -{ - g_return_val_if_fail (TRACKER_IS_INDEXING_TREE (indexing_tree), NULL); - - return g_object_new (TRACKER_TYPE_FILE_NOTIFIER, - "indexing-tree", indexing_tree, - "data-provider", data_provider, - "connection", connection, - NULL); -} - -gboolean -tracker_file_notifier_start (TrackerFileNotifier *notifier) -{ - TrackerFileNotifierPrivate *priv; - - g_return_val_if_fail (TRACKER_IS_FILE_NOTIFIER (notifier), FALSE); - - priv = tracker_file_notifier_get_instance_private (notifier); - - if (priv->stopped) { - priv->stopped = FALSE; - - if (priv->pending_index_roots) { - crawl_directories_start (notifier); - } else { - g_signal_emit (notifier, signals[FINISHED], 0); - } - } - - return TRUE; -} - -void -tracker_file_notifier_stop (TrackerFileNotifier *notifier) -{ - TrackerFileNotifierPrivate *priv; - - g_return_if_fail (TRACKER_IS_FILE_NOTIFIER (notifier)); - - priv = tracker_file_notifier_get_instance_private (notifier); - - if (!priv->stopped) { - tracker_crawler_stop (priv->crawler); - - g_clear_pointer (&priv->current_index_root, root_data_free); - g_cancellable_cancel (priv->cancellable); - priv->stopped = TRUE; - } -} - -gboolean -tracker_file_notifier_is_active (TrackerFileNotifier *notifier) -{ - TrackerFileNotifierPrivate *priv; - - g_return_val_if_fail (TRACKER_IS_FILE_NOTIFIER (notifier), FALSE); - - priv = tracker_file_notifier_get_instance_private (notifier); - return priv->pending_index_roots || priv->current_index_root; -} - -const gchar * -tracker_file_notifier_get_file_iri (TrackerFileNotifier *notifier, - GFile *file, - gboolean force) -{ - TrackerFileNotifierPrivate *priv; - GFile *canonical; - gchar *iri = NULL; - gboolean found; - - g_return_val_if_fail (TRACKER_IS_FILE_NOTIFIER (notifier), NULL); - g_return_val_if_fail (G_IS_FILE (file), NULL); - - priv = tracker_file_notifier_get_instance_private (notifier); - - if (G_UNLIKELY (priv->connection == NULL)) { - return NULL; - } - - canonical = tracker_file_system_get_file (priv->file_system, - file, - G_FILE_TYPE_REGULAR, - NULL); - if (!canonical) { - return NULL; - } - - found = tracker_file_system_get_property_full (priv->file_system, - canonical, - quark_property_iri, - (gpointer *) &iri); - - if (found && !iri) { - /* NULL here mean the file iri was "invalidated", the file - * was inserted by a previous event, so it has an unknown iri, - * and further updates are keeping the file object alive. - * - * When these updates are processed, they'll need fetching the - * file IRI again, so we force here extraction for these cases. - */ - force = TRUE; - } - - if (!iri && force) { - TrackerSparqlCursor *cursor; - const gchar *str; - gchar *sparql; - - /* Fetch data for this file synchronously */ - sparql = sparql_files_compose_query (&file, 1); - cursor = tracker_sparql_connection_query (priv->connection, - sparql, NULL, NULL); - g_free (sparql); - - if (!cursor) - return NULL; - - if (!tracker_sparql_cursor_next (cursor, NULL, NULL)) { - g_object_unref (cursor); - return NULL; - } - - str = tracker_sparql_cursor_get_string (cursor, 1, NULL); - iri = g_strdup (str); - tracker_file_system_set_property (priv->file_system, canonical, - quark_property_iri, iri); - g_object_unref (cursor); - } - - return iri; -} - -static gboolean -file_notifier_invalidate_file_iri_foreach (GFile *file, - gpointer user_data) -{ - TrackerFileSystem *file_system = user_data; - - tracker_file_system_set_property (file_system, - file, - quark_property_iri, - NULL); - - return FALSE; -} - -void -tracker_file_notifier_invalidate_file_iri (TrackerFileNotifier *notifier, - GFile *file, - gboolean recursive) -{ - TrackerFileNotifierPrivate *priv; - GFile *canonical; - - g_return_if_fail (TRACKER_IS_FILE_NOTIFIER (notifier)); - g_return_if_fail (G_IS_FILE (file)); - - priv = tracker_file_notifier_get_instance_private (notifier); - canonical = tracker_file_system_peek_file (priv->file_system, file); - if (!canonical) { - return; - } - - if (!recursive) { - /* Set a NULL iri, so we make sure to look it up afterwards */ - tracker_file_system_set_property (priv->file_system, - canonical, - quark_property_iri, - NULL); - return; - } - - tracker_file_system_traverse (priv->file_system, - canonical, - G_PRE_ORDER, - file_notifier_invalidate_file_iri_foreach, - -1, - priv->file_system); -} - -GFileType -tracker_file_notifier_get_file_type (TrackerFileNotifier *notifier, - GFile *file) -{ - TrackerFileNotifierPrivate *priv; - GFile *canonical; - - g_return_val_if_fail (TRACKER_IS_FILE_NOTIFIER (notifier), G_FILE_TYPE_UNKNOWN); - g_return_val_if_fail (G_IS_FILE (file), G_FILE_TYPE_UNKNOWN); - - priv = tracker_file_notifier_get_instance_private (notifier); - canonical = tracker_file_system_get_file (priv->file_system, - file, - G_FILE_TYPE_REGULAR, - NULL); - if (!canonical) { - return G_FILE_TYPE_UNKNOWN; - } - - return tracker_file_system_get_file_type (priv->file_system, canonical); -} diff --git a/src/libtracker-miner/tracker-file-notifier.h b/src/libtracker-miner/tracker-file-notifier.h deleted file mode 100644 index 592dfee2c..000000000 --- a/src/libtracker-miner/tracker-file-notifier.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2011, Nokia <ivan.frade@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Author: Carlos Garnacho <carlos@lanedo.com> - */ - -#ifndef __TRACKER_FILE_NOTIFIER_H__ -#define __TRACKER_FILE_NOTIFIER_H__ - -#if !defined (__LIBTRACKER_MINER_H_INSIDE__) && !defined (TRACKER_COMPILATION) -#error "Only <libtracker-miner/tracker-miner.h> can be included directly." -#endif - -#include <gio/gio.h> -#include "tracker-indexing-tree.h" -#include "tracker-miner-fs.h" - -G_BEGIN_DECLS - -#define TRACKER_TYPE_FILE_NOTIFIER (tracker_file_notifier_get_type ()) -#define TRACKER_FILE_NOTIFIER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_FILE_NOTIFIER, TrackerFileNotifier)) -#define TRACKER_FILE_NOTIFIER_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), TRACKER_TYPE_FILE_NOTIFIER, TrackerFileNotifierClass)) -#define TRACKER_IS_FILE_NOTIFIER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_FILE_NOTIFIER)) -#define TRACKER_IS_FILE_NOTIFIER_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), TRACKER_TYPE_FILE_NOTIFIER)) -#define TRACKER_FILE_NOTIFIER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_FILE_NOTIFIER, TrackerFileNotifierClass)) - -typedef struct _TrackerFileNotifier TrackerFileNotifier; -typedef struct _TrackerFileNotifierClass TrackerFileNotifierClass; -typedef enum _TrackerFileNotifierType TrackerFileNotifierType; - -struct _TrackerFileNotifier { - GObject parent_instance; -}; - -struct _TrackerFileNotifierClass { - GObjectClass parent_class; - - void (* file_created) (TrackerFileNotifier *notifier, - GFile *file); - void (* file_updated) (TrackerFileNotifier *notifier, - GFile *file, - gboolean attributes_only); - void (* file_deleted) (TrackerFileNotifier *notifier, - GFile *file); - void (* file_moved) (TrackerFileNotifier *notifier, - GFile *from, - GFile *to); - - /* Directory notifications */ - void (* directory_started) (TrackerFileNotifier *notifier, - GFile *directory); - void (* directory_finished) (TrackerFileNotifier *notifier, - GFile *directory, - guint directories_found, - guint directories_ignored, - guint files_found, - guint files_ignored); - - void (* finished) (TrackerFileNotifier *notifier); -}; - -GType tracker_file_notifier_get_type (void) G_GNUC_CONST; - -TrackerFileNotifier * - tracker_file_notifier_new (TrackerIndexingTree *indexing_tree, - TrackerDataProvider *data_provider, - TrackerSparqlConnection *connection); - -gboolean tracker_file_notifier_start (TrackerFileNotifier *notifier); -void tracker_file_notifier_stop (TrackerFileNotifier *notifier); -gboolean tracker_file_notifier_is_active (TrackerFileNotifier *notifier); - -const gchar * tracker_file_notifier_get_file_iri (TrackerFileNotifier *notifier, - GFile *file, - gboolean force); - -void tracker_file_notifier_invalidate_file_iri (TrackerFileNotifier *notifier, - GFile *file, - gboolean recursive); - -GFileType tracker_file_notifier_get_file_type (TrackerFileNotifier *notifier, - GFile *file); - -G_END_DECLS - -#endif /* __TRACKER_FILE_SYSTEM_H__ */ diff --git a/src/libtracker-miner/tracker-file-system.c b/src/libtracker-miner/tracker-file-system.c deleted file mode 100644 index 5e92602f0..000000000 --- a/src/libtracker-miner/tracker-file-system.c +++ /dev/null @@ -1,1056 +0,0 @@ -/* - * Copyright (C) 2011, Nokia <ivan.frade@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Author: Carlos Garnacho <carlos@lanedo.com> - */ - -#include <string.h> -#include <stdlib.h> - -#include "tracker-file-system.h" - -typedef struct _TrackerFileSystemPrivate TrackerFileSystemPrivate; -typedef struct _FileNodeProperty FileNodeProperty; -typedef struct _FileNodeData FileNodeData; -typedef struct _NodeLookupData NodeLookupData; - -static GHashTable *properties = NULL; - -struct _TrackerFileSystemPrivate { - GNode *file_tree; - GFile *root; -}; - -struct _FileNodeProperty { - GQuark prop_quark; - gpointer value; -}; - -struct _FileNodeData { - GFile *file; - gchar *uri_prefix; - GArray *properties; - guint shallow : 1; - guint unowned : 1; - guint file_type : 4; -}; - -struct _NodeLookupData { - TrackerFileSystem *file_system; - GNode *node; -}; - -enum { - PROP_0, - PROP_ROOT, -}; - -static GQuark quark_file_node = 0; - -static void file_weak_ref_notify (gpointer user_data, - GObject *prev_location); - -G_DEFINE_TYPE_WITH_PRIVATE (TrackerFileSystem, tracker_file_system, G_TYPE_OBJECT) - -/* - * TrackerFileSystem is a filesystem abstraction, it mainly serves 2 purposes: - * - Canonicalizes GFiles, so it is possible later to perform pointer - * comparisons on them. - * - Stores data for the GFile lifetime, so it may be used as cache store - * as long as some file is needed. - * - * The TrackerFileSystem holds a reference on each GFile. There are two cases - * when we want to force a cached GFile to be freed: when it no longer exists - * on disk, and once crawling a directory has completed and we only need to - * remember the directories. Objects may persist in the cache even after - * tracker_file_system_forget_files() is called to delete them if there are - * references held on them elsewhere, and they will stay until all references - * are dropped. - */ - - -static void -file_node_data_free (FileNodeData *data, - GNode *node) -{ - guint i; - - if (data->file) { - if (!data->shallow) { - g_object_weak_unref (G_OBJECT (data->file), - file_weak_ref_notify, - node); - } - - if (!data->unowned) { - g_object_unref (data->file); - } - } - - data->file = NULL; - g_free (data->uri_prefix); - - for (i = 0; i < data->properties->len; i++) { - FileNodeProperty *property; - GDestroyNotify destroy_notify; - - property = &g_array_index (data->properties, - FileNodeProperty, i); - - destroy_notify = g_hash_table_lookup (properties, - GUINT_TO_POINTER (property->prop_quark)); - - if (destroy_notify) { - (destroy_notify) (property->value); - } - } - - g_array_free (data->properties, TRUE); - g_slice_free (FileNodeData, data); -} - -static GNode * -file_node_data_new (TrackerFileSystem *file_system, - GFile *file, - GFileType file_type, - gchar *uri_prefix) -{ - FileNodeData *data; - NodeLookupData *lookup_data; - - data = g_slice_new0 (FileNodeData); - data->file = g_object_ref (file); - data->file_type = file_type; - data->uri_prefix = uri_prefix; - data->properties = g_array_new (FALSE, TRUE, sizeof (FileNodeProperty)); - - lookup_data = g_object_get_qdata (G_OBJECT (data->file), - quark_file_node); - - if (!lookup_data) { - lookup_data = g_new0 (NodeLookupData, 1); - g_object_set_qdata_full (G_OBJECT (data->file), - quark_file_node, - lookup_data, g_free); - } - - lookup_data->file_system = file_system; - lookup_data->node = g_node_new (data); - - /* We use weak refs to keep track of files */ - g_object_weak_ref (G_OBJECT (data->file), - file_weak_ref_notify, lookup_data->node); - - return lookup_data->node; -} - -static FileNodeData * -file_node_data_root_new (GFile *root) -{ - FileNodeData *data; - - data = g_slice_new0 (FileNodeData); - data->uri_prefix = g_file_get_uri (root); - data->file = g_object_ref (root); - data->properties = g_array_new (FALSE, TRUE, sizeof (FileNodeProperty)); - data->file_type = G_FILE_TYPE_DIRECTORY; - data->shallow = TRUE; - - return data; -} - -static gboolean -file_node_data_equal_or_child (GNode *node, - gchar *uri_prefix, - gchar **uri_remainder) -{ - FileNodeData *data; - gsize len; - - data = node->data; - len = strlen (data->uri_prefix); - - if (strncmp (uri_prefix, data->uri_prefix, len) == 0) { - uri_prefix += len; - - if (uri_prefix[0] == '/') { - uri_prefix++; - } else if (uri_prefix[0] != '\0' && - (len < 4 || - strcmp (data->uri_prefix + len - 4, ":///") != 0)) { - /* If the first char isn't an uri separator - * nor \0, node represents a similarly named - * file, but not a parent after all. - */ - return FALSE; - } - - if (uri_remainder) { - *uri_remainder = uri_prefix; - } - - return TRUE; - } else { - return FALSE; - } -} - -static GNode * -file_tree_lookup (GNode *tree, - GFile *file, - GNode **parent_node, - gchar **uri_remainder) -{ - GNode *parent, *node_found, *parent_found; - FileNodeData *data; - gchar *uri, *ptr; - - uri = ptr = g_file_get_uri (file); - node_found = parent_found = NULL; - - /* Run through the filesystem tree, comparing chunks of - * uri with the uri prefix in the file nodes, this would - * get us to the closest registered parent, or the file - * itself. - */ - - if (parent_node) { - *parent_node = NULL; - } - - if (uri_remainder) { - *uri_remainder = NULL; - } - - if (!tree) { - return NULL; - } - - if (!G_NODE_IS_ROOT (tree)) { - FileNodeData *parent_data; - gchar *parent_uri; - - parent_data = tree->data; - parent_uri = g_file_get_uri (parent_data->file); - - /* Sanity check */ - if (!g_str_has_prefix (uri, parent_uri)) { - g_free (parent_uri); - return NULL; - } - - ptr += strlen (parent_uri); - - g_assert (ptr[0] == '/'); - ptr++; - - g_free (parent_uri); - } else { - /* First check the root node */ - if (!file_node_data_equal_or_child (tree, uri, &ptr)) { - g_free (uri); - return NULL; - } - - /* Second check there is no basename and if there isn't, - * then this node MUST be the closest registered node - * we can use for the uri. The difference here is that - * we return tree not NULL. - */ - else if (ptr[0] == '\0') { - g_free (uri); - return tree; - } - } - - parent = tree; - - while (parent) { - GNode *child, *next = NULL; - gchar *ret_ptr; - - for (child = g_node_first_child (parent); - child != NULL; - child = g_node_next_sibling (child)) { - data = child->data; - - if (data->uri_prefix[0] != ptr[0]) - continue; - - if (file_node_data_equal_or_child (child, ptr, &ret_ptr)) { - ptr = ret_ptr; - next = child; - break; - } - } - - if (next) { - if (ptr[0] == '\0') { - /* Exact match */ - node_found = next; - parent_found = parent; - break; - } else { - /* Descent down the child */ - parent = next; - } - } else { - parent_found = parent; - break; - } - } - - if (parent_node) { - *parent_node = parent_found; - } - - if (ptr && *ptr && uri_remainder) { - *uri_remainder = g_strdup (ptr); - } - - g_free (uri); - - return node_found; -} - -static gboolean -file_tree_free_node_foreach (GNode *node, - gpointer user_data) -{ - file_node_data_free (node->data, node); - return FALSE; -} - -/* TrackerFileSystem implementation */ - -static void -file_system_finalize (GObject *object) -{ - TrackerFileSystemPrivate *priv; - - priv = tracker_file_system_get_instance_private (TRACKER_FILE_SYSTEM (object)); - - g_node_traverse (priv->file_tree, - G_POST_ORDER, - G_TRAVERSE_ALL, -1, - file_tree_free_node_foreach, - NULL); - g_node_destroy (priv->file_tree); - - if (priv->root) { - g_object_unref (priv->root); - } - - G_OBJECT_CLASS (tracker_file_system_parent_class)->finalize (object); -} - -static void -file_system_constructed (GObject *object) -{ - TrackerFileSystemPrivate *priv; - FileNodeData *root_data; - - G_OBJECT_CLASS (tracker_file_system_parent_class)->constructed (object); - - priv = tracker_file_system_get_instance_private (TRACKER_FILE_SYSTEM (object)); - - if (priv->root == NULL) { - priv->root = g_file_new_for_uri ("file:///"); - } - - root_data = file_node_data_root_new (priv->root); - priv->file_tree = g_node_new (root_data); -} - -static void -file_system_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - TrackerFileSystemPrivate *priv; - - priv = tracker_file_system_get_instance_private (TRACKER_FILE_SYSTEM (object)); - - switch (prop_id) { - case PROP_ROOT: - g_value_set_object (value, priv->root); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -file_system_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - TrackerFileSystemPrivate *priv; - - priv = tracker_file_system_get_instance_private (TRACKER_FILE_SYSTEM (object)); - - switch (prop_id) { - case PROP_ROOT: - priv->root = g_value_dup_object (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -tracker_file_system_class_init (TrackerFileSystemClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = file_system_finalize; - object_class->constructed = file_system_constructed; - object_class->get_property = file_system_get_property; - object_class->set_property = file_system_set_property; - - g_object_class_install_property (object_class, - PROP_ROOT, - g_param_spec_object ("root", - "Root URL", - "The root GFile for the indexing tree", - G_TYPE_FILE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - quark_file_node = - g_quark_from_static_string ("tracker-quark-file-node"); -} -static void -tracker_file_system_init (TrackerFileSystem *file_system) -{ -} - -TrackerFileSystem * -tracker_file_system_new (GFile *root) -{ - return g_object_new (TRACKER_TYPE_FILE_SYSTEM, - "root", root, - NULL); -} - -static void -reparent_child_nodes_to_parent (GNode *node) -{ - FileNodeData *node_data; - GNode *child, *parent; - - parent = node->parent; - node_data = node->data; - child = g_node_first_child (node); - - while (child) { - FileNodeData *data; - gchar *uri_prefix; - GNode *cur; - - cur = child; - data = cur->data; - child = g_node_next_sibling (child); - - uri_prefix = g_strdup_printf ("%s/%s", - node_data->uri_prefix, - data->uri_prefix); - - g_free (data->uri_prefix); - data->uri_prefix = uri_prefix; - - g_node_unlink (cur); - - if (parent) - g_node_prepend (parent, cur); - } - - g_assert (!g_node_first_child (node)); -} - -static void -file_weak_ref_notify (gpointer user_data, - GObject *prev_location) -{ - FileNodeData *data; - GNode *node; - - node = user_data; - data = node->data; - - g_assert (data->file == (GFile *) prev_location); - - data->file = NULL; - reparent_child_nodes_to_parent (node); - - /* Delete node tree here */ - file_node_data_free (data, NULL); - g_node_destroy (node); -} - -static GNode * -file_system_get_node (TrackerFileSystem *file_system, - GFile *file) -{ - TrackerFileSystemPrivate *priv; - NodeLookupData *lookup_data; - - lookup_data = g_object_get_qdata (G_OBJECT (file), quark_file_node); - - if (lookup_data && lookup_data->file_system == file_system) - return lookup_data->node; - - priv = tracker_file_system_get_instance_private (file_system); - return file_tree_lookup (priv->file_tree, file, NULL, NULL); -} - -GFile * -tracker_file_system_get_file (TrackerFileSystem *file_system, - GFile *file, - GFileType file_type, - GFile *parent) -{ - TrackerFileSystemPrivate *priv; - NodeLookupData *lookup_data; - FileNodeData *data; - GNode *node, *parent_node, *lookup_node = NULL; - gchar *uri_prefix = NULL; - GFile *copy = NULL; - - g_return_val_if_fail (G_IS_FILE (file), NULL); - g_return_val_if_fail (TRACKER_IS_FILE_SYSTEM (file_system), NULL); - - priv = tracker_file_system_get_instance_private (file_system); - node = NULL; - lookup_data = g_object_get_qdata (G_OBJECT (file), quark_file_node); - - /* If file is interned somewhere else, get a separate copy of the - * file for this filesystem. - */ - if (lookup_data && lookup_data->file_system != file_system) { - gchar *uri = g_file_get_uri (file); - copy = g_file_new_for_uri (uri); - g_free (uri); - file = copy; - } else if (lookup_data) { - /* Short circuit path, file is already interned */ - return file; - } - - if (parent) { - parent_node = file_system_get_node (file_system, parent); - - if (parent_node) - lookup_node = parent_node; - } - - if (!lookup_node) { - lookup_node = priv->file_tree; - } - - node = file_tree_lookup (lookup_node, file, &parent_node, &uri_prefix); - - if (!node) { - if (!parent_node) { - gchar *uri; - - uri = g_file_get_uri (file); - g_warning ("Could not find parent node for URI:'%s'", uri); - g_warning ("NOTE: URI theme may be outside scheme expected, for example, expecting 'file://' when given 'http://' prefix."); - g_free (uri); - - g_clear_object (©); - - return NULL; - } - - /* Parent was found, add file as child */ - node = file_node_data_new (file_system, file, - file_type, uri_prefix); - - g_node_append (parent_node, node); - data = node->data; - } else { - data = node->data; - g_free (uri_prefix); - - /* Update file type if it was unknown */ - if (data->file_type == G_FILE_TYPE_UNKNOWN) { - data->file_type = file_type; - } - } - - g_clear_object (©); - - return data->file; -} - -GFile * -tracker_file_system_peek_file (TrackerFileSystem *file_system, - GFile *file) -{ - GNode *node; - - g_return_val_if_fail (G_IS_FILE (file), NULL); - g_return_val_if_fail (TRACKER_IS_FILE_SYSTEM (file_system), NULL); - - node = file_system_get_node (file_system, file); - - if (node) { - FileNodeData *data; - - data = node->data; - return data->file; - } - - return NULL; -} - -GFile * -tracker_file_system_peek_parent (TrackerFileSystem *file_system, - GFile *file) -{ - GNode *node; - - g_return_val_if_fail (file != NULL, NULL); - g_return_val_if_fail (TRACKER_IS_FILE_SYSTEM (file_system), NULL); - - node = file_system_get_node (file_system, file); - - if (node) { - FileNodeData *parent_data; - GNode *parent; - - parent = node->parent; - parent_data = parent->data; - - return parent_data->file; - } - - return NULL; -} - -typedef struct { - TrackerFileSystemTraverseFunc func; - gpointer user_data; - GSList *ignore_children; -} TraverseData; - -static gint -node_is_child_of_ignored (gconstpointer a, - gconstpointer b) -{ - if (g_node_is_ancestor ((GNode *) a, (GNode *) b)) - return 0; - - return 1; -} - -static gboolean -traverse_filesystem_func (GNode *node, - gpointer user_data) -{ - TraverseData *data = user_data; - FileNodeData *node_data; - gboolean retval = FALSE; - - node_data = node->data; - - if (!data->ignore_children || - !g_slist_find_custom (data->ignore_children, - node, node_is_child_of_ignored)) { - /* This node isn't a child of an - * ignored one, execute callback - */ - retval = data->func (node_data->file, data->user_data); - } - - /* Avoid recursing within the children of this node */ - if (retval) { - data->ignore_children = g_slist_prepend (data->ignore_children, - node); - } - - return FALSE; -} - -void -tracker_file_system_traverse (TrackerFileSystem *file_system, - GFile *root, - GTraverseType order, - TrackerFileSystemTraverseFunc func, - gint max_depth, - gpointer user_data) -{ - TrackerFileSystemPrivate *priv; - TraverseData data; - GNode *node; - - g_return_if_fail (TRACKER_IS_FILE_SYSTEM (file_system)); - g_return_if_fail (func != NULL); - - priv = tracker_file_system_get_instance_private (file_system); - - if (root) { - node = file_system_get_node (file_system, root); - } else { - node = priv->file_tree; - } - - data.func = func; - data.user_data = user_data; - data.ignore_children = NULL; - - g_node_traverse (node, - order, - G_TRAVERSE_ALL, - max_depth, - traverse_filesystem_func, - &data); - - g_slist_free (data.ignore_children); -} - -void -tracker_file_system_register_property (GQuark prop, - GDestroyNotify destroy_notify) -{ - g_return_if_fail (prop != 0); - - if (!properties) { - properties = g_hash_table_new (NULL, NULL); - } - - if (g_hash_table_contains (properties, GUINT_TO_POINTER (prop))) { - g_warning ("FileSystem: property '%s' has been already registered", - g_quark_to_string (prop)); - return; - } - - g_hash_table_insert (properties, - GUINT_TO_POINTER (prop), - destroy_notify); -} - -static int -search_property_node (gconstpointer key, - gconstpointer item) -{ - const FileNodeProperty *key_prop, *prop; - - key_prop = key; - prop = item; - - if (key_prop->prop_quark < prop->prop_quark) - return -1; - else if (key_prop->prop_quark > prop->prop_quark) - return 1; - - return 0; -} - -void -tracker_file_system_set_property (TrackerFileSystem *file_system, - GFile *file, - GQuark prop, - gpointer prop_data) -{ - FileNodeProperty property, *match; - GDestroyNotify destroy_notify; - FileNodeData *data; - GNode *node; - - g_return_if_fail (TRACKER_IS_FILE_SYSTEM (file_system)); - g_return_if_fail (file != NULL); - g_return_if_fail (prop != 0); - - if (!properties || - !g_hash_table_lookup_extended (properties, - GUINT_TO_POINTER (prop), - NULL, (gpointer *) &destroy_notify)) { - g_warning ("FileSystem: property '%s' is not registered", - g_quark_to_string (prop)); - return; - } - - node = file_system_get_node (file_system, file); - g_return_if_fail (node != NULL); - - data = node->data; - - property.prop_quark = prop; - match = bsearch (&property, data->properties->data, - data->properties->len, sizeof (FileNodeProperty), - search_property_node); - - if (match) { - if (destroy_notify) { - (destroy_notify) (match->value); - } - - match->value = prop_data; - } else { - FileNodeProperty *item; - guint i; - - /* No match, insert new element */ - for (i = 0; i < data->properties->len; i++) { - item = &g_array_index (data->properties, - FileNodeProperty, i); - - if (item->prop_quark > prop) { - break; - } - } - - property.value = prop_data; - - if (i >= data->properties->len) { - g_array_append_val (data->properties, property); - } else { - g_array_insert_val (data->properties, i, property); - } - } -} - -gboolean -tracker_file_system_get_property_full (TrackerFileSystem *file_system, - GFile *file, - GQuark prop, - gpointer *prop_data) -{ - FileNodeData *data; - FileNodeProperty property, *match; - GNode *node; - - g_return_val_if_fail (TRACKER_IS_FILE_SYSTEM (file_system), FALSE); - g_return_val_if_fail (file != NULL, FALSE); - g_return_val_if_fail (prop > 0, FALSE); - - node = file_system_get_node (file_system, file); - g_return_val_if_fail (node != NULL, FALSE); - - data = node->data; - property.prop_quark = prop; - - match = bsearch (&property, data->properties->data, - data->properties->len, sizeof (FileNodeProperty), - search_property_node); - - if (prop_data) - *prop_data = (match) ? match->value : NULL; - - return match != NULL; -} - -gpointer -tracker_file_system_get_property (TrackerFileSystem *file_system, - GFile *file, - GQuark prop) -{ - gpointer data; - - g_return_val_if_fail (TRACKER_IS_FILE_SYSTEM (file_system), NULL); - g_return_val_if_fail (file != NULL, NULL); - g_return_val_if_fail (prop > 0, NULL); - - tracker_file_system_get_property_full (file_system, file, prop, &data); - - return data; -} - -void -tracker_file_system_unset_property (TrackerFileSystem *file_system, - GFile *file, - GQuark prop) -{ - FileNodeData *data; - FileNodeProperty property, *match; - GDestroyNotify destroy_notify = NULL; - GNode *node; - guint index; - - g_return_if_fail (TRACKER_IS_FILE_SYSTEM (file_system)); - g_return_if_fail (file != NULL); - g_return_if_fail (prop > 0); - - if (!properties || - !g_hash_table_lookup_extended (properties, - GUINT_TO_POINTER (prop), - NULL, - (gpointer *) &destroy_notify)) { - g_warning ("FileSystem: property '%s' is not registered", - g_quark_to_string (prop)); - } - - node = file_system_get_node (file_system, file); - g_return_if_fail (node != NULL); - - data = node->data; - property.prop_quark = prop; - - match = bsearch (&property, data->properties->data, - data->properties->len, sizeof (FileNodeProperty), - search_property_node); - - if (!match) { - return; - } - - if (destroy_notify) { - (destroy_notify) (match->value); - } - - /* Find out the index from memory positions */ - index = (guint) ((FileNodeProperty *) match - - (FileNodeProperty *) data->properties->data); - g_assert (index < data->properties->len); - - g_array_remove_index (data->properties, index); -} - -gpointer -tracker_file_system_steal_property (TrackerFileSystem *file_system, - GFile *file, - GQuark prop) -{ - FileNodeData *data; - FileNodeProperty property, *match; - GNode *node; - guint index; - gpointer prop_value; - - g_return_val_if_fail (TRACKER_IS_FILE_SYSTEM (file_system), NULL); - g_return_val_if_fail (file != NULL, NULL); - g_return_val_if_fail (prop > 0, NULL); - - node = file_system_get_node (file_system, file); - g_return_val_if_fail (node != NULL, NULL); - - data = node->data; - property.prop_quark = prop; - - match = bsearch (&property, data->properties->data, - data->properties->len, sizeof (FileNodeProperty), - search_property_node); - - if (!match) { - return NULL; - } - - prop_value = match->value; - - /* Find out the index from memory positions */ - index = (guint) ((FileNodeProperty *) match - - (FileNodeProperty *) data->properties->data); - g_assert (index < data->properties->len); - - g_array_remove_index (data->properties, index); - - return prop_value; -} - -typedef struct { - TrackerFileSystem *file_system; - GList *list; - GFileType file_type; -} ForgetFilesData; - -static gboolean -append_deleted_files (GNode *node, - gpointer user_data) -{ - ForgetFilesData *data; - FileNodeData *node_data; - - data = user_data; - node_data = node->data; - - if (data->file_type == G_FILE_TYPE_UNKNOWN || - node_data->file_type == data->file_type) { - data->list = g_list_prepend (data->list, node_data); - } - - return FALSE; -} - -static void -forget_file (FileNodeData *node_data) -{ - if (!node_data->unowned) { - node_data->unowned = TRUE; - - /* Weak reference handler will remove the file from the tree and - * clean up node_data if this is the final reference. - */ - g_object_unref (node_data->file); - } -} - -void -tracker_file_system_forget_files (TrackerFileSystem *file_system, - GFile *root, - GFileType file_type) -{ - ForgetFilesData data = { file_system, NULL, file_type }; - GNode *node; - - g_return_if_fail (TRACKER_IS_FILE_SYSTEM (file_system)); - g_return_if_fail (G_IS_FILE (root)); - - node = file_system_get_node (file_system, root); - g_return_if_fail (node != NULL); - - /* We need to get the files to delete into a list, so - * the node tree isn't modified during traversal. - */ - g_node_traverse (node, - G_PRE_ORDER, - (file_type == G_FILE_TYPE_REGULAR) ? - G_TRAVERSE_LEAVES : G_TRAVERSE_ALL, - -1, append_deleted_files, - &data); - - g_list_foreach (data.list, (GFunc) forget_file, NULL); - g_list_free (data.list); -} - -GFileType -tracker_file_system_get_file_type (TrackerFileSystem *file_system, - GFile *file) -{ - GFileType file_type = G_FILE_TYPE_UNKNOWN; - GNode *node; - - g_return_val_if_fail (TRACKER_IS_FILE_SYSTEM (file_system), file_type); - g_return_val_if_fail (G_IS_FILE (file), file_type); - - node = file_system_get_node (file_system, file); - - if (node) { - FileNodeData *node_data; - - node_data = node->data; - file_type = node_data->file_type; - } - - return file_type; -} diff --git a/src/libtracker-miner/tracker-file-system.h b/src/libtracker-miner/tracker-file-system.h deleted file mode 100644 index 5da7fbab8..000000000 --- a/src/libtracker-miner/tracker-file-system.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2011, Nokia <ivan.frade@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Author: Carlos Garnacho <carlos@lanedo.com> - */ - -#ifndef __TRACKER_FILE_SYSTEM_H__ -#define __TRACKER_FILE_SYSTEM_H__ - -#if !defined (__LIBTRACKER_MINER_H_INSIDE__) && !defined (TRACKER_COMPILATION) -#error "Only <libtracker-miner/tracker-miner.h> can be included directly." -#endif - -#include <gio/gio.h> - -G_BEGIN_DECLS - -#define TRACKER_TYPE_FILE_SYSTEM (tracker_file_system_get_type()) -#define TRACKER_FILE_SYSTEM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_FILE_SYSTEM, TrackerFileSystem)) -#define TRACKER_FILE_SYSTEM_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), TRACKER_TYPE_FILE_SYSTEM, TrackerFileSystemClass)) -#define TRACKER_IS_FILE_SYSTEM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_FILE_SYSTEM)) -#define TRACKER_IS_FILE_SYSTEM_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), TRACKER_TYPE_FILE_SYSTEM)) -#define TRACKER_FILE_SYSTEM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_FILE_SYSTEM, TrackerFileSystemClass)) - -typedef struct _TrackerFileSystem TrackerFileSystem; -typedef struct _TrackerFileSystemClass TrackerFileSystemClass; - -struct _TrackerFileSystem { - GObject parent_instance; -}; - -struct _TrackerFileSystemClass { - GObjectClass parent_class; -}; - -typedef gboolean (* TrackerFileSystemTraverseFunc) (GFile *file, - gpointer user_data); - -GType tracker_file_system_get_type (void) G_GNUC_CONST; - -TrackerFileSystem * - tracker_file_system_new (GFile *root); - -GFile * tracker_file_system_get_file (TrackerFileSystem *file_system, - GFile *file, - GFileType file_type, - GFile *parent); -GFile * tracker_file_system_peek_file (TrackerFileSystem *file_system, - GFile *file); -GFile * tracker_file_system_peek_parent (TrackerFileSystem *file_system, - GFile *file); - -void tracker_file_system_traverse (TrackerFileSystem *file_system, - GFile *root, - GTraverseType order, - TrackerFileSystemTraverseFunc func, - gint max_depth, - gpointer user_data); - -void tracker_file_system_forget_files (TrackerFileSystem *file_system, - GFile *root, - GFileType file_type); - -GFileType tracker_file_system_get_file_type (TrackerFileSystem *file_system, - GFile *file); -/* properties */ -void tracker_file_system_register_property (GQuark prop, - GDestroyNotify destroy_notify); - -void tracker_file_system_set_property (TrackerFileSystem *file_system, - GFile *file, - GQuark prop, - gpointer prop_data); -gpointer tracker_file_system_get_property (TrackerFileSystem *file_system, - GFile *file, - GQuark prop); -void tracker_file_system_unset_property (TrackerFileSystem *file_system, - GFile *file, - GQuark prop); -gpointer tracker_file_system_steal_property (TrackerFileSystem *file_system, - GFile *file, - GQuark prop); - -gboolean tracker_file_system_get_property_full (TrackerFileSystem *file_system, - GFile *file, - GQuark prop, - gpointer *data); - -G_END_DECLS - -#endif /* __TRACKER_FILE_SYSTEM_H__ */ diff --git a/src/libtracker-miner/tracker-indexing-tree.c b/src/libtracker-miner/tracker-indexing-tree.c deleted file mode 100644 index dfbba4562..000000000 --- a/src/libtracker-miner/tracker-indexing-tree.c +++ /dev/null @@ -1,1230 +0,0 @@ -/* - * Copyright (C) 2011, Nokia <ivan.frade@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Author: Carlos Garnacho <carlos@lanedo.com> - */ - -#include <libtracker-common/tracker-file-utils.h> -#include "tracker-indexing-tree.h" - -/** - * SECTION:tracker-indexing-tree - * @short_description: Indexing tree handling - * - * #TrackerIndexingTree handles the tree of directories configured to be indexed - * by the #TrackerMinerFS. - **/ - -typedef struct _TrackerIndexingTreePrivate TrackerIndexingTreePrivate; -typedef struct _NodeData NodeData; -typedef struct _PatternData PatternData; -typedef struct _FindNodeData FindNodeData; - -struct _NodeData -{ - GFile *file; - guint flags; - guint shallow : 1; - guint removing : 1; -}; - -struct _PatternData -{ - GPatternSpec *pattern; - TrackerFilterType type; - GFile *file; /* Only filled in in absolute paths */ -}; - -struct _FindNodeData -{ - GEqualFunc func; - GNode *node; - GFile *file; -}; - -struct _TrackerIndexingTreePrivate -{ - GNode *config_tree; - GList *filter_patterns; - TrackerFilterPolicy policies[TRACKER_FILTER_PARENT_DIRECTORY + 1]; - - GFile *root; - guint filter_hidden : 1; -}; - -G_DEFINE_TYPE_WITH_PRIVATE (TrackerIndexingTree, tracker_indexing_tree, G_TYPE_OBJECT) - -enum { - PROP_0, - PROP_ROOT, - PROP_FILTER_HIDDEN -}; - -enum { - DIRECTORY_ADDED, - DIRECTORY_REMOVED, - DIRECTORY_UPDATED, - CHILD_UPDATED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -static NodeData * -node_data_new (GFile *file, - guint flags) -{ - NodeData *data; - - data = g_slice_new0 (NodeData); - data->file = g_object_ref (file); - data->flags = flags; - - return data; -} - -static void -node_data_free (NodeData *data) -{ - g_object_unref (data->file); - g_slice_free (NodeData, data); -} - -static gboolean -node_free (GNode *node, - gpointer user_data) -{ - node_data_free (node->data); - return FALSE; -} - -static PatternData * -pattern_data_new (const gchar *glob_string, - guint type) -{ - PatternData *data; - - data = g_slice_new0 (PatternData); - data->pattern = g_pattern_spec_new (glob_string); - data->type = type; - - if (g_path_is_absolute (glob_string)) { - data->file = g_file_new_for_path (glob_string); - } - - return data; -} - -static void -pattern_data_free (PatternData *data) -{ - if (data->file) { - g_object_unref (data->file); - } - - g_pattern_spec_free (data->pattern); - g_slice_free (PatternData, data); -} - -static void -tracker_indexing_tree_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - TrackerIndexingTreePrivate *priv; - - priv = TRACKER_INDEXING_TREE (object)->priv; - - switch (prop_id) { - case PROP_ROOT: - g_value_set_object (value, priv->root); - break; - case PROP_FILTER_HIDDEN: - g_value_set_boolean (value, priv->filter_hidden); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -tracker_indexing_tree_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - TrackerIndexingTree *tree; - TrackerIndexingTreePrivate *priv; - - tree = TRACKER_INDEXING_TREE (object); - priv = tree->priv; - - switch (prop_id) { - case PROP_ROOT: - priv->root = g_value_dup_object (value); - break; - case PROP_FILTER_HIDDEN: - tracker_indexing_tree_set_filter_hidden (tree, - g_value_get_boolean (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -tracker_indexing_tree_constructed (GObject *object) -{ - TrackerIndexingTree *tree; - TrackerIndexingTreePrivate *priv; - NodeData *data; - - G_OBJECT_CLASS (tracker_indexing_tree_parent_class)->constructed (object); - - tree = TRACKER_INDEXING_TREE (object); - priv = tree->priv; - - /* Add a shallow root node */ - if (priv->root == NULL) { - priv->root = g_file_new_for_uri ("file:///"); - } - - data = node_data_new (priv->root, 0); - data->shallow = TRUE; - - priv->config_tree = g_node_new (data); -} - -static void -tracker_indexing_tree_finalize (GObject *object) -{ - TrackerIndexingTreePrivate *priv; - TrackerIndexingTree *tree; - - tree = TRACKER_INDEXING_TREE (object); - priv = tree->priv; - - g_list_foreach (priv->filter_patterns, (GFunc) pattern_data_free, NULL); - g_list_free (priv->filter_patterns); - - g_node_traverse (priv->config_tree, - G_POST_ORDER, - G_TRAVERSE_ALL, - -1, - (GNodeTraverseFunc) node_free, - NULL); - g_node_destroy (priv->config_tree); - - if (priv->root) { - g_object_unref (priv->root); - } - - G_OBJECT_CLASS (tracker_indexing_tree_parent_class)->finalize (object); -} - -static void -tracker_indexing_tree_class_init (TrackerIndexingTreeClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = tracker_indexing_tree_finalize; - object_class->constructed = tracker_indexing_tree_constructed; - object_class->set_property = tracker_indexing_tree_set_property; - object_class->get_property = tracker_indexing_tree_get_property; - - g_object_class_install_property (object_class, - PROP_ROOT, - g_param_spec_object ("root", - "Root URL", - "The root GFile for the indexing tree", - G_TYPE_FILE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property (object_class, - PROP_FILTER_HIDDEN, - g_param_spec_boolean ("filter-hidden", - "Filter hidden", - "Whether hidden resources are filtered", - FALSE, - G_PARAM_READWRITE)); - /** - * TrackerIndexingTree::directory-added: - * @indexing_tree: a #TrackerIndexingTree - * @directory: a #GFile - * - * the ::directory-added signal is emitted when a new - * directory is added to the list of other directories which - * are to be considered for indexing. Typically this is - * signalled when the tracker_indexing_tree_add() API is - * called. - * - * Since: 0.14 - **/ - signals[DIRECTORY_ADDED] = - g_signal_new ("directory-added", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (TrackerIndexingTreeClass, - directory_added), - NULL, NULL, - NULL, - G_TYPE_NONE, 1, G_TYPE_FILE); - - /** - * TrackerIndexingTree::directory-removed: - * @indexing_tree: a #TrackerIndexingTree - * @directory: a #GFile - * - * the ::directory-removed signal is emitted when a - * directory is removed from the list of other directories - * which are to be considered for indexing. Typically this is - * signalled when the tracker_indexing_tree_remove() API is - * called. - * - * Since: 0.14 - **/ - signals[DIRECTORY_REMOVED] = - g_signal_new ("directory-removed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (TrackerIndexingTreeClass, - directory_removed), - NULL, NULL, - NULL, - G_TYPE_NONE, 1, G_TYPE_FILE); - - /** - * TrackerIndexingTree::directory-updated: - * @indexing_tree: a #TrackerIndexingTree - * @directory: a #GFile - * - * The ::directory-updated signal is emitted on a root - * when either its indexing flags change (e.g. due to consecutive - * calls to tracker_indexing_tree_add()), or anytime an update is - * requested through tracker_indexing_tree_notify_update(). - * - * Since: 0.14 - **/ - signals[DIRECTORY_UPDATED] = - g_signal_new ("directory-updated", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (TrackerIndexingTreeClass, - directory_updated), - NULL, NULL, - NULL, - G_TYPE_NONE, 1, G_TYPE_FILE); - - /** - * TrackerIndexingTree::child-updated: - * @indexing_tree: a #TrackerIndexingTree - * @root: the root of this child - * @child: the updated child - * - * The ::child-updated signal may be emitted to notify - * about possible changes on children of a root. - * - * #TrackerIndexingTree does not emit those by itself, - * those may be triggered through tracker_indexing_tree_notify_update(). - * - * Since: 1.10 - **/ - signals[CHILD_UPDATED] = - g_signal_new ("child-updated", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (TrackerIndexingTreeClass, - child_updated), - NULL, NULL, - NULL, - G_TYPE_NONE, 2, G_TYPE_FILE, G_TYPE_FILE); -} - -static void -tracker_indexing_tree_init (TrackerIndexingTree *tree) -{ - TrackerIndexingTreePrivate *priv; - gint i; - - priv = tree->priv = tracker_indexing_tree_get_instance_private (tree); - - for (i = TRACKER_FILTER_FILE; i <= TRACKER_FILTER_PARENT_DIRECTORY; i++) { - priv->policies[i] = TRACKER_FILTER_POLICY_ACCEPT; - } -} - -/** - * tracker_indexing_tree_new: - * - * Returns a newly created #TrackerIndexingTree - * - * Returns: a newly allocated #TrackerIndexingTree - * - * Since: 0.14 - **/ -TrackerIndexingTree * -tracker_indexing_tree_new (void) -{ - return g_object_new (TRACKER_TYPE_INDEXING_TREE, NULL); -} - -/** - * tracker_indexing_tree_new_with_root: - * @root: The top level URL - * - * If @root is %NULL, the default value is 'file:///'. Using %NULL - * here is the equivalent to calling tracker_indexing_tree_new() which - * takes no @root argument. - * - * Returns: a newly allocated #TrackerIndexingTree - * - * Since: 1.2.2 - **/ -TrackerIndexingTree * -tracker_indexing_tree_new_with_root (GFile *root) -{ - return g_object_new (TRACKER_TYPE_INDEXING_TREE, - "root", root, - NULL); -} - -#ifdef PRINT_INDEXING_TREE -static gboolean -print_node_foreach (GNode *node, - gpointer user_data) -{ - NodeData *node_data = node->data; - gchar *uri; - - uri = g_file_get_uri (node_data->file); - g_debug ("%*s %s", g_node_depth (node), "-", uri); - g_free (uri); - - return FALSE; -} - -static void -print_tree (GNode *node) -{ - g_debug ("Printing modified tree..."); - g_node_traverse (node, - G_PRE_ORDER, - G_TRAVERSE_ALL, - -1, - print_node_foreach, - NULL); -} - -#endif /* PRINT_INDEXING_TREE */ - -static gboolean -find_node_foreach (GNode *node, - gpointer user_data) -{ - FindNodeData *data = user_data; - NodeData *node_data = node->data; - - if ((data->func) (data->file, node_data->file)) { - data->node = node; - return TRUE; - } - - return FALSE; -} - -static GNode * -find_directory_node (GNode *node, - GFile *file, - GEqualFunc func) -{ - FindNodeData data; - - data.file = file; - data.node = NULL; - data.func = func; - - g_node_traverse (node, - G_POST_ORDER, - G_TRAVERSE_ALL, - -1, - find_node_foreach, - &data); - - return data.node; -} - -static void -check_reparent_node (GNode *node, - gpointer user_data) -{ - GNode *new_node = user_data; - NodeData *new_node_data, *node_data; - - new_node_data = new_node->data; - node_data = node->data; - - if (g_file_has_prefix (node_data->file, - new_node_data->file)) { - g_node_unlink (node); - g_node_append (new_node, node); - } -} - -/** - * tracker_indexing_tree_add: - * @tree: a #TrackerIndexingTree - * @directory: #GFile pointing to a directory - * @flags: Configuration flags for the directory - * - * Adds a directory to the indexing tree with the - * given configuration flags. - **/ -void -tracker_indexing_tree_add (TrackerIndexingTree *tree, - GFile *directory, - TrackerDirectoryFlags flags) -{ - TrackerIndexingTreePrivate *priv; - GNode *parent, *node; - NodeData *data; - - g_return_if_fail (TRACKER_IS_INDEXING_TREE (tree)); - g_return_if_fail (G_IS_FILE (directory)); - - priv = tree->priv; - node = find_directory_node (priv->config_tree, directory, - (GEqualFunc) g_file_equal); - - if (node) { - /* Node already existed */ - data = node->data; - data->shallow = FALSE; - - /* Overwrite flags if they are different */ - if (data->flags != flags) { - gchar *uri; - - uri = g_file_get_uri (directory); - g_message ("Overwriting flags for directory '%s'", uri); - g_free (uri); - - data->flags = flags; - g_signal_emit (tree, signals[DIRECTORY_UPDATED], 0, - data->file); - } - return; - } - - /* Find out the parent */ - parent = find_directory_node (priv->config_tree, directory, - (GEqualFunc) g_file_has_prefix); - - /* Create node, move children of parent that - * could be children of this new node now. - */ - data = node_data_new (directory, flags); - node = g_node_new (data); - - g_node_children_foreach (parent, G_TRAVERSE_ALL, - check_reparent_node, node); - - /* Add the new node underneath the parent */ - g_node_append (parent, node); - - g_signal_emit (tree, signals[DIRECTORY_ADDED], 0, directory); - -#ifdef PRINT_INDEXING_TREE - /* Print tree */ - print_tree (priv->config_tree); -#endif /* PRINT_INDEXING_TREE */ -} - -/** - * tracker_indexing_tree_remove: - * @tree: a #TrackerIndexingTree - * @directory: #GFile pointing to a directory - * - * Removes @directory from the indexing tree, note that - * only directories previously added with tracker_indexing_tree_add() - * can be effectively removed. - **/ -void -tracker_indexing_tree_remove (TrackerIndexingTree *tree, - GFile *directory) -{ - TrackerIndexingTreePrivate *priv; - GNode *node, *parent; - NodeData *data; - - g_return_if_fail (TRACKER_IS_INDEXING_TREE (tree)); - g_return_if_fail (G_IS_FILE (directory)); - - priv = tree->priv; - node = find_directory_node (priv->config_tree, directory, - (GEqualFunc) g_file_equal); - if (!node) { - return; - } - - data = node->data; - - if (data->removing) { - return; - } - - data->removing = TRUE; - - if (!node->parent) { - /* Node is the config tree - * root, mark as shallow again - */ - data->shallow = TRUE; - return; - } - - g_signal_emit (tree, signals[DIRECTORY_REMOVED], 0, data->file); - - parent = node->parent; - g_node_unlink (node); - - /* Move children to parent */ - g_node_children_foreach (node, G_TRAVERSE_ALL, - check_reparent_node, parent); - - node_data_free (node->data); - g_node_destroy (node); -} - -/** - * tracker_indexing_tree_notify_update: - * @tree: a #TrackerIndexingTree - * @file: a #GFile - * @recursive: Whether contained indexing roots are affected by the update - * - * Signals either #TrackerIndexingTree::directory-updated or - * #TrackerIndexingTree::child-updated on the given file and - * returns #TRUE. If @file is not indexed according to the - * #TrackerIndexingTree, #FALSE is returned. - * - * If @recursive is #TRUE, #TrackerIndexingTree::directory-updated - * will be emitted on the indexing roots that are contained in @file. - * - * Returns: #TRUE if a signal is emitted. - * - * Since: 1.10 - **/ -gboolean -tracker_indexing_tree_notify_update (TrackerIndexingTree *tree, - GFile *file, - gboolean recursive) -{ - TrackerDirectoryFlags flags; - gboolean emitted = FALSE; - GFile *root; - - g_return_val_if_fail (TRACKER_IS_INDEXING_TREE (tree), FALSE); - g_return_val_if_fail (G_IS_FILE (file), FALSE); - - root = tracker_indexing_tree_get_root (tree, file, &flags); - - if (tracker_indexing_tree_file_is_root (tree, file)) { - g_signal_emit (tree, signals[DIRECTORY_UPDATED], 0, root); - emitted = TRUE; - } else if (root && - ((flags & TRACKER_DIRECTORY_FLAG_RECURSE) || - g_file_has_parent (file, root))) { - g_signal_emit (tree, signals[CHILD_UPDATED], 0, root, file); - emitted = TRUE; - } - - if (recursive) { - GList *roots, *l; - - roots = tracker_indexing_tree_list_roots (tree); - - for (l = roots; l; l = l->next) { - if (!g_file_has_prefix (l->data, file)) - continue; - - g_signal_emit (tree, signals[DIRECTORY_UPDATED], 0, l->data); - emitted = TRUE; - } - - g_list_free (roots); - } - - return emitted; -} - -/** - * tracker_indexing_tree_add_filter: - * @tree: a #TrackerIndexingTree - * @filter: filter type - * @glob_string: glob-style string for the filter - * - * Adds a new filter for basenames. - **/ -void -tracker_indexing_tree_add_filter (TrackerIndexingTree *tree, - TrackerFilterType filter, - const gchar *glob_string) -{ - TrackerIndexingTreePrivate *priv; - PatternData *data; - - g_return_if_fail (TRACKER_IS_INDEXING_TREE (tree)); - g_return_if_fail (glob_string != NULL); - - priv = tree->priv; - - data = pattern_data_new (glob_string, filter); - priv->filter_patterns = g_list_prepend (priv->filter_patterns, data); -} - -/** - * tracker_indexing_tree_clear_filters: - * @tree: a #TrackerIndexingTree - * @type: filter type to clear - * - * Clears all filters of a given type. - **/ -void -tracker_indexing_tree_clear_filters (TrackerIndexingTree *tree, - TrackerFilterType type) -{ - TrackerIndexingTreePrivate *priv; - GList *l; - - g_return_if_fail (TRACKER_IS_INDEXING_TREE (tree)); - - priv = tree->priv; - - for (l = priv->filter_patterns; l; l = l->next) { - PatternData *data = l->data; - - if (data->type == type) { - /* When we delete the link 'l', we point back - * to the beginning of the list to make sure - * we don't miss anything. - */ - l = priv->filter_patterns = g_list_delete_link (priv->filter_patterns, l); - pattern_data_free (data); - } - } -} - -/** - * tracker_indexing_tree_file_matches_filter: - * @tree: a #TrackerIndexingTree - * @type: filter type - * @file: a #GFile - * - * Returns %TRUE if @file matches any filter of the given filter type. - * - * Returns: %TRUE if @file is filtered. - **/ -gboolean -tracker_indexing_tree_file_matches_filter (TrackerIndexingTree *tree, - TrackerFilterType type, - GFile *file) -{ - TrackerIndexingTreePrivate *priv; - GList *filters; - gchar *basename, *str, *reverse; - gboolean match = FALSE; - gint len; - - g_return_val_if_fail (TRACKER_IS_INDEXING_TREE (tree), FALSE); - g_return_val_if_fail (G_IS_FILE (file), FALSE); - - priv = tree->priv; - filters = priv->filter_patterns; - basename = g_file_get_basename (file); - - str = g_utf8_make_valid (basename, -1); - len = strlen (str); - reverse = g_utf8_strreverse (str, len); - - while (filters) { - PatternData *data = filters->data; - - filters = filters->next; - - if (data->type != type) - continue; - - if (data->file && - (g_file_equal (file, data->file) || - g_file_has_prefix (file, data->file))) { - match = TRUE; - break; - } - - if (g_pattern_match (data->pattern, len, str, reverse)) { - match = TRUE; - break; - } - } - - g_free (basename); - g_free (str); - g_free (reverse); - - return match; -} - -static gboolean -parent_or_equals (GFile *file1, - GFile *file2) -{ - return (file1 == file2 || - g_file_equal (file1, file2) || - g_file_has_prefix (file1, file2)); -} - -static gboolean -indexing_tree_file_is_filtered (TrackerIndexingTree *tree, - TrackerFilterType filter, - GFile *file) -{ - TrackerIndexingTreePrivate *priv; - - priv = tree->priv; - - if (tracker_indexing_tree_file_matches_filter (tree, filter, file)) { - if (priv->policies[filter] == TRACKER_FILTER_POLICY_ACCEPT) { - /* Filter blocks otherwise accepted - * (by the default policy) file - */ - return TRUE; - } - } else { - if (priv->policies[filter] == TRACKER_FILTER_POLICY_DENY) { - /* No match, and the default policy denies it */ - return TRUE; - } - } - - return FALSE; -} - -/** - * tracker_indexing_tree_file_is_indexable: - * @tree: a #TrackerIndexingTree - * @file: a #GFile - * @file_type: a #GFileType - * - * returns %TRUE if @file should be indexed according to the - * parameters given through tracker_indexing_tree_add() and - * tracker_indexing_tree_add_filter(). - * - * If @file_type is #G_FILE_TYPE_UNKNOWN, file type will be queried to the - * file system. - * - * Returns: %TRUE if @file should be indexed. - **/ -gboolean -tracker_indexing_tree_file_is_indexable (TrackerIndexingTree *tree, - GFile *file, - GFileType file_type) -{ - TrackerFilterType filter; - TrackerDirectoryFlags config_flags; - GFile *config_file; - - g_return_val_if_fail (TRACKER_IS_INDEXING_TREE (tree), FALSE); - g_return_val_if_fail (G_IS_FILE (file), FALSE); - - config_file = tracker_indexing_tree_get_root (tree, file, &config_flags); - if (!config_file) { - /* Not under an added dir */ - return FALSE; - } - - /* Don't check file type if _NO_STAT is given in flags */ - if (file_type == G_FILE_TYPE_UNKNOWN && - (config_flags & TRACKER_DIRECTORY_FLAG_NO_STAT) != 0) { - GFileQueryInfoFlags file_flags; - - file_flags = G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS; - - file_type = g_file_query_file_type (file, file_flags, NULL); - - filter = (file_type == G_FILE_TYPE_DIRECTORY) ? - TRACKER_FILTER_DIRECTORY : TRACKER_FILTER_FILE; - - if (indexing_tree_file_is_filtered (tree, filter, file)) { - return FALSE; - } - } else if (file_type != G_FILE_TYPE_UNKNOWN) { - filter = (file_type == G_FILE_TYPE_DIRECTORY) ? - TRACKER_FILTER_DIRECTORY : TRACKER_FILTER_FILE; - - if (indexing_tree_file_is_filtered (tree, filter, file)) { - return FALSE; - } - } - - /* FIXME: Shouldn't we only do this for file_type == G_FILE_TYPE_DIRECTORY ? */ - if (config_flags & TRACKER_DIRECTORY_FLAG_IGNORE) { - return FALSE; - } - - if (g_file_equal (file, config_file)) { - return TRUE; - } else { - if ((config_flags & TRACKER_DIRECTORY_FLAG_RECURSE) == 0 && - !g_file_has_parent (file, config_file)) { - /* Non direct child in a non-recursive dir, ignore */ - return FALSE; - } - - if (tracker_indexing_tree_get_filter_hidden (tree) && - tracker_file_is_hidden (file)) { - return FALSE; - } - - return TRUE; - } -} - -/** - * tracker_indexing_tree_parent_is_indexable: - * @tree: a #TrackerIndexingTree - * @parent: parent directory - * @children: (element-type GFile): children within @parent - * - * returns %TRUE if @parent should be indexed based on its contents. - * - * Returns: %TRUE if @parent should be indexed. - **/ -gboolean -tracker_indexing_tree_parent_is_indexable (TrackerIndexingTree *tree, - GFile *parent, - GList *children) -{ - TrackerIndexingTreePrivate *priv; - gboolean has_match = FALSE; - - g_return_val_if_fail (TRACKER_IS_INDEXING_TREE (tree), FALSE); - g_return_val_if_fail (G_IS_FILE (parent), FALSE); - - priv = tree->priv; - - if (!tracker_indexing_tree_file_is_indexable (tree, - parent, - G_FILE_TYPE_DIRECTORY)) { - return FALSE; - } - - while (children && !has_match) { - has_match = tracker_indexing_tree_file_matches_filter (tree, - TRACKER_FILTER_PARENT_DIRECTORY, - children->data); - children = children->next; - } - - if (priv->policies[TRACKER_FILTER_PARENT_DIRECTORY] == TRACKER_FILTER_POLICY_ACCEPT) - return !has_match; - else - return has_match; -} - -/** - * tracker_indexing_tree_get_filter_hidden: - * @tree: a #TrackerIndexingTree - * - * Describes if the @tree should index hidden content. To change this - * setting, see tracker_indexing_tree_set_filter_hidden(). - * - * Returns: %FALSE if hidden files are indexed, otherwise %TRUE. - * - * Since: 0.18 - **/ -gboolean -tracker_indexing_tree_get_filter_hidden (TrackerIndexingTree *tree) -{ - TrackerIndexingTreePrivate *priv; - - g_return_val_if_fail (TRACKER_IS_INDEXING_TREE (tree), FALSE); - - priv = tree->priv; - return priv->filter_hidden; -} - -/** - * tracker_indexing_tree_set_filter_hidden: - * @tree: a #TrackerIndexingTree - * @filter_hidden: a boolean - * - * When indexing content, sometimes it is preferable to ignore hidden - * content, for example, files prefixed with ".". This is - * common for files in a home directory which are usually config - * files. - * - * Sets the indexing policy for @tree with hidden files and content. - * To ignore hidden files, @filter_hidden should be %TRUE, otherwise - * %FALSE. - * - * Since: 0.18 - **/ -void -tracker_indexing_tree_set_filter_hidden (TrackerIndexingTree *tree, - gboolean filter_hidden) -{ - TrackerIndexingTreePrivate *priv; - - g_return_if_fail (TRACKER_IS_INDEXING_TREE (tree)); - - priv = tree->priv; - priv->filter_hidden = filter_hidden; - - g_object_notify (G_OBJECT (tree), "filter-hidden"); -} - -/** - * tracker_indexing_tree_set_default_policy: - * @tree: a #TrackerIndexingTree - * @filter: a #TrackerFilterType - * @policy: a #TrackerFilterPolicy - * - * Set the default @policy (to allow or deny) for content in @tree - * based on the type - in this case @filter. Here, @filter is a file - * or directory and there are some other options too. - * - * For example, you can (by default), disable indexing all directories - * using this function. - * - * Since: 0.18 - **/ -void -tracker_indexing_tree_set_default_policy (TrackerIndexingTree *tree, - TrackerFilterType filter, - TrackerFilterPolicy policy) -{ - TrackerIndexingTreePrivate *priv; - - g_return_if_fail (TRACKER_IS_INDEXING_TREE (tree)); - g_return_if_fail (filter >= TRACKER_FILTER_FILE && filter <= TRACKER_FILTER_PARENT_DIRECTORY); - - priv = tree->priv; - priv->policies[filter] = policy; -} - -/** - * tracker_indexing_tree_get_default_policy: - * @tree: a #TrackerIndexingTree - * @filter: a #TrackerFilterType - * - * Get the default filtering policies for @tree when indexing content. - * Some content is black listed or white listed and the default policy - * for that is returned here. The @filter allows specific type of - * policies to be returned, for example, the default policy for files - * (#TRACKER_FILTER_FILE). - * - * Returns: Either #TRACKER_FILTER_POLICY_DENY or - * #TRACKER_FILTER_POLICY_ACCEPT. - * - * Since: 0.18 - **/ -TrackerFilterPolicy -tracker_indexing_tree_get_default_policy (TrackerIndexingTree *tree, - TrackerFilterType filter) -{ - TrackerIndexingTreePrivate *priv; - - g_return_val_if_fail (TRACKER_IS_INDEXING_TREE (tree), - TRACKER_FILTER_POLICY_DENY); - g_return_val_if_fail (filter >= TRACKER_FILTER_FILE && - filter <= TRACKER_FILTER_PARENT_DIRECTORY, - TRACKER_FILTER_POLICY_DENY); - - priv = tree->priv; - return priv->policies[filter]; -} - -/** - * tracker_indexing_tree_get_root: - * @tree: a #TrackerIndexingTree - * @file: a #GFile - * @directory_flags: (out): return location for the applying #TrackerDirectoryFlags - * - * Returns the #GFile that was previously added through tracker_indexing_tree_add() - * and would equal or contain @file, or %NULL if none applies. - * - * If the return value is non-%NULL, @directory_flags would contain the - * #TrackerDirectoryFlags applying to @file. - * - * Returns: (transfer none): the effective parent in @tree, or %NULL - **/ -GFile * -tracker_indexing_tree_get_root (TrackerIndexingTree *tree, - GFile *file, - TrackerDirectoryFlags *directory_flags) -{ - TrackerIndexingTreePrivate *priv; - NodeData *data; - GNode *parent; - - if (directory_flags) { - *directory_flags = TRACKER_DIRECTORY_FLAG_NONE; - } - - g_return_val_if_fail (TRACKER_IS_INDEXING_TREE (tree), NULL); - g_return_val_if_fail (G_IS_FILE (file), NULL); - - priv = tree->priv; - parent = find_directory_node (priv->config_tree, file, - (GEqualFunc) parent_or_equals); - if (!parent) { - return NULL; - } - - data = parent->data; - - if (!data->shallow && - (file == data->file || - g_file_equal (file, data->file) || - g_file_has_prefix (file, data->file))) { - if (directory_flags) { - *directory_flags = data->flags; - } - - return data->file; - } - - return NULL; -} - -/** - * tracker_indexing_tree_get_master_root: - * @tree: a #TrackerIndexingTree - * - * Returns the #GFile that represents the master root location for all - * indexing locations. For example, if - * <filename>file:///etc</filename> is an indexed path and so was - * <filename>file:///home/user</filename>, the master root is - * <filename>file:///</filename>. Only one scheme per @tree can be - * used, so you can not mix <filename>http</filename> and - * <filename>file</filename> roots in @tree. - * - * The return value should <emphasis>NEVER</emphasis> be %NULL. In - * cases where no root is given, we fallback to - * <filename>file:///</filename>. - * - * Roots explained: - * - * - master root = top most level root node, - * e.g. file:/// - * - * - config root = a root node from GSettings, - * e.g. file:///home/martyn/Documents - * - * - root = ANY root, normally config root, but it can also apply to - * roots added for devices, which technically are not a config root or a - * master root. - * - * Returns: (transfer none): the effective root for all locations, or - * %NULL on error. The root is owned by @tree and should not be freed. - * It can be referenced using g_object_ref(). - * - * Since: 1.2 - **/ -GFile * -tracker_indexing_tree_get_master_root (TrackerIndexingTree *tree) -{ - TrackerIndexingTreePrivate *priv; - - g_return_val_if_fail (TRACKER_IS_INDEXING_TREE (tree), NULL); - - priv = tree->priv; - - return priv->root; -} - -/** - * tracker_indexing_tree_file_is_root: - * @tree: a #TrackerIndexingTree - * @file: a #GFile to compare - * - * Evaluates if the URL represented by @file is the same of that for - * the root of the @tree. - * - * Returns: %TRUE if @file matches the URL canonically, otherwise %FALSE. - * - * Since: 1.2 - **/ -gboolean -tracker_indexing_tree_file_is_root (TrackerIndexingTree *tree, - GFile *file) -{ - TrackerIndexingTreePrivate *priv; - GNode *node; - - g_return_val_if_fail (TRACKER_IS_INDEXING_TREE (tree), FALSE); - g_return_val_if_fail (G_IS_FILE (file), FALSE); - - priv = tree->priv; - node = find_directory_node (priv->config_tree, file, - (GEqualFunc) g_file_equal); - return node != NULL; -} - -static gboolean -prepend_config_root (GNode *node, - gpointer user_data) -{ - GList **list = user_data; - NodeData *data = node->data; - - if (!data->shallow && !data->removing) - *list = g_list_prepend (*list, data->file); - return FALSE; -} - -/** - * tracker_indexing_tree_list_roots: - * @tree: a #TrackerIndexingTree - * - * Returns the list of indexing roots in @tree - * - * Returns: (transfer container) (element-type GFile): The list - * of roots, the list itself must be freed with g_list_free(), - * the list elements are owned by @tree and should not be - * freed. - **/ -GList * -tracker_indexing_tree_list_roots (TrackerIndexingTree *tree) -{ - TrackerIndexingTreePrivate *priv; - GList *nodes = NULL; - - g_return_val_if_fail (TRACKER_IS_INDEXING_TREE (tree), NULL); - - priv = tree->priv; - g_node_traverse (priv->config_tree, - G_POST_ORDER, - G_TRAVERSE_ALL, - -1, - prepend_config_root, - &nodes); - return nodes; -} diff --git a/src/libtracker-miner/tracker-indexing-tree.h b/src/libtracker-miner/tracker-indexing-tree.h deleted file mode 100644 index aa2112893..000000000 --- a/src/libtracker-miner/tracker-indexing-tree.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (C) 2011, Nokia <ivan.frade@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Author: Carlos Garnacho <carlos@lanedo.com> - */ - -#ifndef __TRACKER_INDEXING_TREE_H__ -#define __TRACKER_INDEXING_TREE_H__ - -#if !defined (__LIBTRACKER_MINER_H_INSIDE__) && !defined (TRACKER_COMPILATION) -#error "Only <libtracker-miner/tracker-miner.h> can be included directly." -#endif - -#include <gio/gio.h> -#include "tracker-miner-enums.h" - -G_BEGIN_DECLS - -#define TRACKER_TYPE_INDEXING_TREE (tracker_indexing_tree_get_type()) -#define TRACKER_INDEXING_TREE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_INDEXING_TREE, TrackerIndexingTree)) -#define TRACKER_INDEXING_TREE_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), TRACKER_TYPE_INDEXING_TREE, TrackerIndexingTreeClass)) -#define TRACKER_IS_INDEXING_TREE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_INDEXING_TREE)) -#define TRACKER_IS_INDEXING_TREE_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), TRACKER_TYPE_INDEXING_TREE)) -#define TRACKER_INDEXING_TREE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_INDEXING_TREE, TrackerIndexingTreeClass)) - -/** - * TrackerIndexingTree: - * - * Base object used to configure indexing within #TrackerMinerFS items. - */ - -typedef struct _TrackerIndexingTree TrackerIndexingTree; - -struct _TrackerIndexingTree { - GObject parent_instance; - gpointer priv; -}; - -/** - * TrackerIndexingTreeClass: - * @parent_class: parent object class - * @directory_added: Called when a directory is added. - * @directory_removed: Called when a directory is removed. - * @directory_updated: Called when a directory is updated. - * @child_updated: Called when a file inside a directory is updated. - * @padding: Reserved for future API improvements. - * - * Class for the #TrackerIndexingTree. - */ -typedef struct { - GObjectClass parent_class; - - void (* directory_added) (TrackerIndexingTree *indexing_tree, - GFile *directory); - void (* directory_removed) (TrackerIndexingTree *indexing_tree, - GFile *directory); - void (* directory_updated) (TrackerIndexingTree *indexing_tree, - GFile *directory); - void (* child_updated) (TrackerIndexingTree *indexing_tree, - GFile *root, - GFile *child); - /* <Private> */ - gpointer padding[9]; -} TrackerIndexingTreeClass; - -GType tracker_indexing_tree_get_type (void) G_GNUC_CONST; - -TrackerIndexingTree * tracker_indexing_tree_new (void); - -TrackerIndexingTree * tracker_indexing_tree_new_with_root (GFile *root); - -void tracker_indexing_tree_add (TrackerIndexingTree *tree, - GFile *directory, - TrackerDirectoryFlags flags); -void tracker_indexing_tree_remove (TrackerIndexingTree *tree, - GFile *directory); -gboolean tracker_indexing_tree_notify_update (TrackerIndexingTree *tree, - GFile *file, - gboolean recursive); - -void tracker_indexing_tree_add_filter (TrackerIndexingTree *tree, - TrackerFilterType filter, - const gchar *glob_string); -void tracker_indexing_tree_clear_filters (TrackerIndexingTree *tree, - TrackerFilterType type); -gboolean tracker_indexing_tree_file_matches_filter (TrackerIndexingTree *tree, - TrackerFilterType type, - GFile *file); - -gboolean tracker_indexing_tree_file_is_indexable (TrackerIndexingTree *tree, - GFile *file, - GFileType file_type); -gboolean tracker_indexing_tree_parent_is_indexable (TrackerIndexingTree *tree, - GFile *parent, - GList *children); - -gboolean tracker_indexing_tree_get_filter_hidden (TrackerIndexingTree *tree); -void tracker_indexing_tree_set_filter_hidden (TrackerIndexingTree *tree, - gboolean filter_hidden); - -TrackerFilterPolicy tracker_indexing_tree_get_default_policy (TrackerIndexingTree *tree, - TrackerFilterType filter); -void tracker_indexing_tree_set_default_policy (TrackerIndexingTree *tree, - TrackerFilterType filter, - TrackerFilterPolicy policy); - -GFile * tracker_indexing_tree_get_root (TrackerIndexingTree *tree, - GFile *file, - TrackerDirectoryFlags *directory_flags); -GFile * tracker_indexing_tree_get_master_root (TrackerIndexingTree *tree); - -gboolean tracker_indexing_tree_file_is_root (TrackerIndexingTree *tree, - GFile *file); - -GList * tracker_indexing_tree_list_roots (TrackerIndexingTree *tree); - - -G_END_DECLS - -#endif /* __TRACKER_INDEXING_TREE_H__ */ diff --git a/src/libtracker-miner/tracker-miner-2.map b/src/libtracker-miner/tracker-miner-2.map deleted file mode 100644 index b29fc4bd9..000000000 --- a/src/libtracker-miner/tracker-miner-2.map +++ /dev/null @@ -1,13 +0,0 @@ -{ -global: - tracker_data_provider_*; - tracker_miner_*; - tracker_indexing_tree_*; - tracker_directory_flags_*; - tracker_filter_type_*; - tracker_filter_policy_*; - tracker_network_type_*; - tracker_decorator_*; -local: - *; -}; diff --git a/src/libtracker-miner/tracker-miner-enum-types.c.template b/src/libtracker-miner/tracker-miner-enum-types.c.template deleted file mode 100644 index c946de1c8..000000000 --- a/src/libtracker-miner/tracker-miner-enum-types.c.template +++ /dev/null @@ -1,44 +0,0 @@ -/*** BEGIN file-header ***/ -#include <config.h> - -#include "tracker-miner-enum-types.h" - -/*** END file-header ***/ - -/*** BEGIN file-production ***/ -/* enumerations from "@basename@" */ -#include "@filename@" -/*** END file-production ***/ - - -/*** BEGIN value-header ***/ -GType -@enum_name@_get_type (void) -{ - static volatile gsize g_define_type_id__volatile = 0; - - if (g_once_init_enter (&g_define_type_id__volatile)) { - static const G@Type@Value values[] = { -/*** END value-header ***/ - -/*** BEGIN value-production ***/ - { @VALUENAME@, "@VALUENAME@", "@valuenick@" }, -/*** END value-production ***/ - -/*** BEGIN value-tail ***/ - { 0, NULL, NULL } - }; - GType g_define_type_id = - g_@type@_register_static (g_intern_static_string ("@EnumName@"), values); - - g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); - } - - return g_define_type_id__volatile; -} - -/*** END value-tail ***/ - -/*** BEGIN file-tail ***/ - -/*** END file-tail ***/ diff --git a/src/libtracker-miner/tracker-miner-enum-types.h.template b/src/libtracker-miner/tracker-miner-enum-types.h.template deleted file mode 100644 index b13e839f1..000000000 --- a/src/libtracker-miner/tracker-miner-enum-types.h.template +++ /dev/null @@ -1,26 +0,0 @@ -/*** BEGIN file-header ***/ - -#ifndef __TRACKER_MINER_ENUM_TYPES_H__ -#define __TRACKER_MINER_ENUM_TYPES_H__ - -#include <glib-object.h> -#include "tracker-miner-enums.h" - -G_BEGIN_DECLS -/*** END file-header ***/ - -/*** BEGIN file-production ***/ - -/* enumerations from "@basename@" */ -/*** END file-production ***/ - -/*** BEGIN value-header ***/ -GType @enum_name@_get_type (void) G_GNUC_CONST; -#define TRACKER_TYPE_@ENUMSHORT@ (@enum_name@_get_type ()) -/*** END value-header ***/ - -/*** BEGIN file-tail ***/ -G_END_DECLS - -#endif /* __TRACKER_ENUMS_TYPES_H__ */ -/*** END file-tail ***/ diff --git a/src/libtracker-miner/tracker-miner-enums.h b/src/libtracker-miner/tracker-miner-enums.h deleted file mode 100644 index b5b552bc1..000000000 --- a/src/libtracker-miner/tracker-miner-enums.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (C) 2011, Nokia <ivan.frade@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Author: Carlos Garnacho <carlos@lanedo.com> - */ - -#ifndef __TRACKER_MINER_ENUMS_H__ -#define __TRACKER_MINER_ENUMS_H__ - -G_BEGIN_DECLS - -/** - * SECTION:tracker-miner-enums - * @title: Enumerations - * @short_description: Common enumerations - * @include: libtracker-miner/tracker-miner-enums.h - * - * Common enumeration types used in libtracker-miner. - **/ - -/** - * TrackerDirectoryFlags: - * @TRACKER_DIRECTORY_FLAG_NONE: No flags. - * @TRACKER_DIRECTORY_FLAG_RECURSE: Should recurse in the directory. - * @TRACKER_DIRECTORY_FLAG_CHECK_MTIME: Should check mtimes of items - * in the directory. - * @TRACKER_DIRECTORY_FLAG_MONITOR: Should setup monitors in the items - * found in the directory. - * @TRACKER_DIRECTORY_FLAG_IGNORE: Should ignore the directory - * contents. - * @TRACKER_DIRECTORY_FLAG_PRESERVE: Should preserve items in the - * directory even if the directory gets removed. - * @TRACKER_DIRECTORY_FLAG_PRIORITY: Internally a priority queue is - * used and this flag makes sure the directory is given a priority - * over other directories queued. - * @TRACKER_DIRECTORY_FLAG_NO_STAT: For cases where the content being - * crawled by the enumerator is not local (e.g. it's on a - * server somewhere), use the #TRACKER_DIRECTORY_FLAG_NO_STAT flag. - * The default is to use stat() and assume we're mining a local or - * mounted file system. - * @TRACKER_DIRECTORY_FLAG_CHECK_DELETED: Forces checks on deleted - * contents. This is most usually optimized away unless directory - * mtime changes indicate there could be deleted content. - * - * Flags used when adding a new directory to be indexed in the - * #TrackerIndexingTree and #TrackerDataProvider. - */ -typedef enum { - TRACKER_DIRECTORY_FLAG_NONE = 0, - TRACKER_DIRECTORY_FLAG_RECURSE = 1 << 1, - TRACKER_DIRECTORY_FLAG_CHECK_MTIME = 1 << 2, - TRACKER_DIRECTORY_FLAG_MONITOR = 1 << 3, - TRACKER_DIRECTORY_FLAG_IGNORE = 1 << 4, - TRACKER_DIRECTORY_FLAG_PRESERVE = 1 << 5, - TRACKER_DIRECTORY_FLAG_PRIORITY = 1 << 6, - TRACKER_DIRECTORY_FLAG_NO_STAT = 1 << 7, - TRACKER_DIRECTORY_FLAG_CHECK_DELETED = 1 << 8, -} TrackerDirectoryFlags; - -/** - * TrackerFilterType: - * @TRACKER_FILTER_FILE: All files matching this filter will be filtered out. - * @TRACKER_FILTER_DIRECTORY: All directories matching this filter will be filtered out. - * @TRACKER_FILTER_PARENT_DIRECTORY: All files in directories matching this filter will be filtered out. - * - * Flags used when adding a new filter in the #TrackerIndexingTree. - */ -typedef enum { - TRACKER_FILTER_FILE, - TRACKER_FILTER_DIRECTORY, - TRACKER_FILTER_PARENT_DIRECTORY -} TrackerFilterType; - -/** - * TrackerFilterPolicy: - * @TRACKER_FILTER_POLICY_DENY: Items matching the filter will be skipped. - * @TRACKER_FILTER_POLICY_ACCEPT: Items matching the filter will be accepted. - * - * Flags used when defining default filter policy in the #TrackerIndexingTree. - */ -typedef enum { - TRACKER_FILTER_POLICY_DENY, - TRACKER_FILTER_POLICY_ACCEPT -} TrackerFilterPolicy; - -/** - * TrackerNetworkType: - * @TRACKER_NETWORK_TYPE_NONE: Network is disconnected - * @TRACKER_NETWORK_TYPE_UNKNOWN: Network status is unknown - * @TRACKER_NETWORK_TYPE_GPRS: Network is connected over a GPRS - * connection - * @TRACKER_NETWORK_TYPE_EDGE: Network is connected over an EDGE - * connection - * @TRACKER_NETWORK_TYPE_3G: Network is connected over a 3G or - * faster (HSDPA, UMTS, ...) connection - * @TRACKER_NETWORK_TYPE_LAN: Network is connected over a local - * network connection. This can be ethernet, wifi, etc. - * - * Enumerates the different types of connections that the device might - * use when connected to internet. Note that not all providers might - * provide this information. - * - * Since: 0.18 - **/ -typedef enum { - TRACKER_NETWORK_TYPE_NONE, - TRACKER_NETWORK_TYPE_UNKNOWN, - TRACKER_NETWORK_TYPE_GPRS, - TRACKER_NETWORK_TYPE_EDGE, - TRACKER_NETWORK_TYPE_3G, - TRACKER_NETWORK_TYPE_LAN -} TrackerNetworkType; - -G_END_DECLS - -#endif /* __TRACKER_MINER_ENUMS_H__ */ diff --git a/src/libtracker-miner/tracker-miner-fs.c b/src/libtracker-miner/tracker-miner-fs.c deleted file mode 100644 index 51f435fb1..000000000 --- a/src/libtracker-miner/tracker-miner-fs.c +++ /dev/null @@ -1,2659 +0,0 @@ -/* - * Copyright (C) 2009, Nokia <ivan.frade@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "config.h" - -#include <libtracker-common/tracker-common.h> - -#include "tracker-crawler.h" -#include "tracker-miner-fs.h" -#include "tracker-monitor.h" -#include "tracker-utils.h" -#include "tracker-priority-queue.h" -#include "tracker-task-pool.h" -#include "tracker-sparql-buffer.h" -#include "tracker-file-notifier.h" - -/* If defined will print push/pop actions on queues */ -#ifdef EVENT_QUEUE_ENABLE_TRACE -#warning Event Queue traces enabled -#define EVENT_QUEUE_LOG_PREFIX "[Event Queues] " -#define EVENT_QUEUE_STATUS_TIMEOUT_SECS 30 -#define trace_eq(message, ...) g_message (EVENT_QUEUE_LOG_PREFIX message, ##__VA_ARGS__) -#define trace_eq_event(event) \ - do { \ - const gchar *event_type_name[] = { "CREATED", "UPDATED", "DELETED", "MOVED" }; \ - gchar *uri1 = g_file_get_uri (event->file); \ - gchar *uri2 = event->dest_file ? g_file_get_uri (event->dest_file) : NULL; \ - g_message ("%s New %s event: %s%s%s%s", \ - EVENT_QUEUE_LOG_PREFIX, \ - event_type_name[event->type], \ - event->attributes_update ? "(attributes only) " : "", \ - uri1, \ - uri2 ? "->" : "", \ - uri2 ? uri2 : ""); \ - g_free (uri1); \ - g_free (uri2); \ - } while (0) -#else -#define trace_eq(...) -#define trace_eq_event(...) -#endif /* EVENT_QUEUE_ENABLE_TRACE */ - -/* Default processing pool limits to be set */ -#define DEFAULT_WAIT_POOL_LIMIT 1 -#define DEFAULT_READY_POOL_LIMIT 1 - -/* Put tasks processing at a lower priority so other events - * (timeouts, monitor events, etc...) are guaranteed to be - * dispatched promptly. - */ -#define TRACKER_TASK_PRIORITY G_PRIORITY_DEFAULT_IDLE + 10 - -#define MAX_SIMULTANEOUS_ITEMS 64 - -/** - * SECTION:tracker-miner-fs - * @short_description: Abstract base class for filesystem miners - * @include: libtracker-miner/tracker-miner.h - * - * #TrackerMinerFS is an abstract base class for miners that collect data - * from a filesystem where parent/child relationships need to be - * inserted into the database correctly with queue management. - * - * All the filesystem crawling and monitoring is abstracted away, - * leaving to implementations the decisions of what directories/files - * should it process, and the actual data extraction. - * - * Example creating a TrackerMinerFS with our own file system root and - * data provider. - * - * First create our class and base it on TrackerMinerFS: - * |[ - * G_DEFINE_TYPE_WITH_CODE (MyMinerFiles, my_miner_files, TRACKER_TYPE_MINER_FS, - * G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, - * my_miner_files_initable_iface_init)) - * ]| - * - * Later in our class creation function, we are supplying the - * arguments we want. In this case, the 'root' is a #GFile pointing to - * a root URI location (for example 'file:///') and 'data_provider' is a - * #TrackerDataProvider used to enumerate 'root' and return children it - * finds. If 'data_provider' is %NULL (the default), then a - * #TrackerFileDataProvider is created automatically. - * |[ - * // Note that only 'name' is mandatory - * miner = g_initable_new (MY_TYPE_MINER_FILES, - * NULL, - * error, - * "name", "MyMinerFiles", - * "root", root, - * "data-provider", data_provider, - * "processing-pool-wait-limit", 10, - * "processing-pool-ready-limit", 100, - * NULL); - * ]| - **/ - -typedef struct { - guint16 type; - guint attributes_update : 1; - GFile *file; - GFile *dest_file; -} QueueEvent; - -typedef struct { - GFile *file; - gchar *urn; - gint priority; - GCancellable *cancellable; - TrackerMiner *miner; -} UpdateProcessingTaskContext; - -struct _TrackerMinerFSPrivate { - TrackerPriorityQueue *items; - - guint item_queues_handler_id; - GFile *item_queue_blocker; - - /* Root / tree / index */ - GFile *root; - TrackerIndexingTree *indexing_tree; - TrackerFileNotifier *file_notifier; - TrackerDataProvider *data_provider; - - /* Sparql insertion tasks */ - TrackerTaskPool *task_pool; - TrackerSparqlBuffer *sparql_buffer; - guint sparql_buffer_limit; - - /* File properties */ - GQuark quark_recursive_removal; - - /* Properties */ - gdouble throttle; - - /* Status */ - GTimer *timer; - GTimer *extraction_timer; - - guint been_started : 1; /* TRUE if miner has been started */ - guint been_crawled : 1; /* TRUE if initial crawling has been - * done */ - guint shown_totals : 1; /* TRUE if totals have been shown */ - guint is_paused : 1; /* TRUE if miner is paused */ - - guint timer_stopped : 1; /* TRUE if main timer is stopped */ - guint extraction_timer_stopped : 1; /* TRUE if the extraction - * timer is stopped */ - - GHashTable *roots_to_notify; /* Used to signal indexing - * trees finished */ - - /* - * Statistics - */ - - /* How many we found during crawling and how many were black - * listed (ignored). Reset to 0 when processing stops. */ - guint total_directories_found; - guint total_directories_ignored; - guint total_files_found; - guint total_files_ignored; - - /* How many we indexed and how many had errors indexing. */ - guint total_files_processed; - guint total_files_notified; - guint total_files_notified_error; -}; - -typedef enum { - QUEUE_NONE, - QUEUE_CREATED, - QUEUE_UPDATED, - QUEUE_DELETED, - QUEUE_MOVED, - QUEUE_WAIT, -} QueueState; - -typedef enum { - QUEUE_ACTION_NONE = 0, - QUEUE_ACTION_DELETE_FIRST = 1 << 0, - QUEUE_ACTION_DELETE_SECOND = 1 << 1, -} QueueCoalesceAction; - -enum { - PROCESS_FILE, - PROCESS_FILE_ATTRIBUTES, - FINISHED, - FINISHED_ROOT, - REMOVE_FILE, - REMOVE_CHILDREN, - MOVE_FILE, - LAST_SIGNAL -}; - -enum { - PROP_0, - PROP_THROTTLE, - PROP_ROOT, - PROP_WAIT_POOL_LIMIT, - PROP_READY_POOL_LIMIT, - PROP_DATA_PROVIDER -}; - -static void miner_fs_initable_iface_init (GInitableIface *iface); - -static void fs_finalize (GObject *object); -static void fs_constructed (GObject *object); -static void fs_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void fs_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); - -static void miner_started (TrackerMiner *miner); -static void miner_stopped (TrackerMiner *miner); -static void miner_paused (TrackerMiner *miner); -static void miner_resumed (TrackerMiner *miner); - -static void indexing_tree_directory_removed (TrackerIndexingTree *indexing_tree, - GFile *directory, - gpointer user_data); -static void file_notifier_file_created (TrackerFileNotifier *notifier, - GFile *file, - gpointer user_data); -static void file_notifier_file_deleted (TrackerFileNotifier *notifier, - GFile *file, - gpointer user_data); -static void file_notifier_file_updated (TrackerFileNotifier *notifier, - GFile *file, - gboolean attributes_only, - gpointer user_data); -static void file_notifier_file_moved (TrackerFileNotifier *notifier, - GFile *source, - GFile *dest, - gpointer user_data); -static void file_notifier_directory_started (TrackerFileNotifier *notifier, - GFile *directory, - gpointer user_data); -static void file_notifier_directory_finished (TrackerFileNotifier *notifier, - GFile *directory, - guint directories_found, - guint directories_ignored, - guint files_found, - guint files_ignored, - gpointer user_data); -static void file_notifier_finished (TrackerFileNotifier *notifier, - gpointer user_data); - -static void item_queue_handlers_set_up (TrackerMinerFS *fs); - -static void task_pool_cancel_foreach (gpointer data, - gpointer user_data); -static void task_pool_limit_reached_notify_cb (GObject *object, - GParamSpec *pspec, - gpointer user_data); - -static void miner_fs_queue_event (TrackerMinerFS *fs, - QueueEvent *event, - guint priority); - -static GQuark quark_last_queue_event = 0; -static GInitableIface* miner_fs_initable_parent_iface; -static guint signals[LAST_SIGNAL] = { 0, }; - -/** - * tracker_miner_fs_error_quark: - * - * Gives the caller the #GQuark used to identify #TrackerMinerFS errors - * in #GError structures. The #GQuark is used as the domain for the error. - * - * Returns: the #GQuark used for the domain of a #GError. - * - * Since: 1.2 - **/ -G_DEFINE_QUARK (TrackerMinerFSError, tracker_miner_fs_error) - -G_DEFINE_ABSTRACT_TYPE_WITH_CODE (TrackerMinerFS, tracker_miner_fs, TRACKER_TYPE_MINER, - G_ADD_PRIVATE (TrackerMinerFS) - G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, - miner_fs_initable_iface_init)); - -static void -tracker_miner_fs_class_init (TrackerMinerFSClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - TrackerMinerClass *miner_class = TRACKER_MINER_CLASS (klass); - - object_class->finalize = fs_finalize; - object_class->constructed = fs_constructed; - object_class->set_property = fs_set_property; - object_class->get_property = fs_get_property; - - miner_class->started = miner_started; - miner_class->stopped = miner_stopped; - miner_class->paused = miner_paused; - miner_class->resumed = miner_resumed; - - g_object_class_install_property (object_class, - PROP_THROTTLE, - g_param_spec_double ("throttle", - "Throttle", - "Modifier for the indexing speed, 0 is max speed", - 0, 1, 0, - G_PARAM_READWRITE)); - g_object_class_install_property (object_class, - PROP_ROOT, - g_param_spec_object ("root", - "Root", - "Top level URI for our indexing tree and file notify clases", - G_TYPE_FILE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - g_object_class_install_property (object_class, - PROP_WAIT_POOL_LIMIT, - g_param_spec_uint ("processing-pool-wait-limit", - "Processing pool limit for WAIT tasks", - "Maximum number of files that can be concurrently " - "processed by the upper layer", - 1, G_MAXUINT, DEFAULT_WAIT_POOL_LIMIT, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - g_object_class_install_property (object_class, - PROP_READY_POOL_LIMIT, - g_param_spec_uint ("processing-pool-ready-limit", - "Processing pool limit for READY tasks", - "Maximum number of SPARQL updates that can be merged " - "in a single connection to the store", - 1, G_MAXUINT, DEFAULT_READY_POOL_LIMIT, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - g_object_class_install_property (object_class, - PROP_DATA_PROVIDER, - g_param_spec_object ("data-provider", - "Data provider", - "Data provider populating data, e.g. like GFileEnumerator", - TRACKER_TYPE_DATA_PROVIDER, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - /** - * TrackerMinerFS::process-file: - * @miner_fs: the #TrackerMinerFS - * @file: a #GFile - * @builder: a #TrackerSparqlBuilder - * @cancellable: a #GCancellable - * - * The ::process-file signal is emitted whenever a file should - * be processed, and it's metadata extracted. - * - * @builder is the #TrackerSparqlBuilder where all sparql updates - * to be performed for @file will be appended. - * - * This signal allows both synchronous and asynchronous extraction, - * in the synchronous case @cancellable can be safely ignored. In - * either case, on successful metadata extraction, implementations - * must call tracker_miner_fs_notify_finish() to indicate that - * processing has finished on @file, so the miner can execute - * the SPARQL updates and continue processing other files. - * - * Returns: %TRUE if the file is accepted for processing, - * %FALSE if the file should be ignored. - * - * Since: 0.8 - **/ - signals[PROCESS_FILE] = - g_signal_new ("process-file", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (TrackerMinerFSClass, process_file), - NULL, NULL, - NULL, - G_TYPE_BOOLEAN, - 2, G_TYPE_FILE, G_TYPE_TASK); - - /** - * TrackerMinerFS::process-file-attributes: - * @miner_fs: the #TrackerMinerFS - * @file: a #GFile - * @builder: a #TrackerSparqlBuilder - * @cancellable: a #GCancellable - * - * The ::process-file-attributes signal is emitted whenever a file should - * be processed, but only the attribute-related metadata extracted. - * - * @builder is the #TrackerSparqlBuilder where all sparql updates - * to be performed for @file will be appended. For the properties being - * updated, the DELETE statements should be included as well. - * - * This signal allows both synchronous and asynchronous extraction, - * in the synchronous case @cancellable can be safely ignored. In - * either case, on successful metadata extraction, implementations - * must call tracker_miner_fs_notify_finish() to indicate that - * processing has finished on @file, so the miner can execute - * the SPARQL updates and continue processing other files. - * - * Returns: %TRUE if the file is accepted for processing, - * %FALSE if the file should be ignored. - * - * Since: 0.10 - **/ - signals[PROCESS_FILE_ATTRIBUTES] = - g_signal_new ("process-file-attributes", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (TrackerMinerFSClass, process_file_attributes), - NULL, NULL, - NULL, - G_TYPE_BOOLEAN, - 2, G_TYPE_FILE, G_TYPE_TASK); - - /** - * TrackerMinerFS::finished: - * @miner_fs: the #TrackerMinerFS - * @elapsed: elapsed time since mining was started - * @directories_found: number of directories found - * @directories_ignored: number of ignored directories - * @files_found: number of files found - * @files_ignored: number of ignored files - * - * The ::finished signal is emitted when @miner_fs has finished - * all pending processing. - * - * Since: 0.8 - **/ - signals[FINISHED] = - g_signal_new ("finished", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (TrackerMinerFSClass, finished), - NULL, NULL, - NULL, - G_TYPE_NONE, - 5, - G_TYPE_DOUBLE, - G_TYPE_UINT, - G_TYPE_UINT, - G_TYPE_UINT, - G_TYPE_UINT); - - /** - * TrackerMinerFS::finished-root: - * @miner_fs: the #TrackerMinerFS - * @file: a #GFile - * - * The ::finished-crawl signal is emitted when @miner_fs has - * finished finding all resources that need to be indexed - * with the root location of @file. At this point, it's likely - * many are still in the queue to be added to the database, - * but this gives some indication that a location is - * processed. - * - * Since: 1.2 - **/ - signals[FINISHED_ROOT] = - g_signal_new ("finished-root", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (TrackerMinerFSClass, finished_root), - NULL, NULL, - NULL, - G_TYPE_NONE, - 1, - G_TYPE_FILE); - - /** - * TrackerMinerFS::remove-file: - * @miner_fs: the #TrackerMinerFS - * @file: a #GFile - * @children_only: #TRUE if only the children of @file are to be deleted - * @builder: a #TrackerSparqlBuilder - * - * The ::remove-file signal will be emitted on files that need removal - * according to the miner configuration (either the files themselves are - * deleted, or the directory/contents no longer need inspection according - * to miner configuration and their location. - * - * This operation is always assumed to be recursive, the @children_only - * argument will be %TRUE if for any reason the topmost directory needs - * to stay (e.g. moved from a recursively indexed directory tree to a - * non-recursively indexed location). - * - * The @builder argument can be used to provide additional SPARQL - * deletes and updates necessary around the deletion of those items. If - * the return value of this signal is %TRUE, @builder is expected to - * contain all relevant deletes for this operation. - * - * If the return value of this signal is %FALSE, the miner will apply - * its default behavior, which is deleting all triples that correspond - * to the affected URIs. - * - * Returns: %TRUE if @builder contains all the necessary operations to - * delete the affected resources, %FALSE to let the miner - * implicitly handle the deletion. - * - * Since: 1.8 - **/ - signals[REMOVE_FILE] = - g_signal_new ("remove-file", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (TrackerMinerFSClass, remove_file), - NULL, NULL, NULL, - G_TYPE_STRING, - 1, G_TYPE_FILE); - - signals[REMOVE_CHILDREN] = - g_signal_new ("remove-children", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (TrackerMinerFSClass, remove_children), - NULL, NULL, NULL, - G_TYPE_STRING, - 1, G_TYPE_FILE); - - signals[MOVE_FILE] = - g_signal_new ("move-file", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (TrackerMinerFSClass, move_file), - NULL, NULL, NULL, - G_TYPE_STRING, - 3, G_TYPE_FILE, G_TYPE_FILE, G_TYPE_BOOLEAN); - - quark_last_queue_event = g_quark_from_static_string ("tracker-last-queue-event"); -} - -static void -tracker_miner_fs_init (TrackerMinerFS *object) -{ - TrackerMinerFSPrivate *priv; - - object->priv = tracker_miner_fs_get_instance_private (object); - - priv = object->priv; - - priv->timer = g_timer_new (); - priv->extraction_timer = g_timer_new (); - - g_timer_stop (priv->timer); - g_timer_stop (priv->extraction_timer); - - priv->timer_stopped = TRUE; - priv->extraction_timer_stopped = TRUE; - - priv->items = tracker_priority_queue_new (); - - /* Create processing pools */ - priv->task_pool = tracker_task_pool_new (DEFAULT_WAIT_POOL_LIMIT); - g_signal_connect (priv->task_pool, "notify::limit-reached", - G_CALLBACK (task_pool_limit_reached_notify_cb), object); - - priv->quark_recursive_removal = g_quark_from_static_string ("tracker-recursive-removal"); - - priv->roots_to_notify = g_hash_table_new_full (g_file_hash, - (GEqualFunc) g_file_equal, - g_object_unref, - NULL); -} - -static gboolean -miner_fs_initable_init (GInitable *initable, - GCancellable *cancellable, - GError **error) -{ - TrackerMinerFSPrivate *priv; - guint limit; - - if (!miner_fs_initable_parent_iface->init (initable, cancellable, error)) { - return FALSE; - } - - priv = TRACKER_MINER_FS (initable)->priv; - - g_object_get (initable, "processing-pool-ready-limit", &limit, NULL); - priv->sparql_buffer = tracker_sparql_buffer_new (tracker_miner_get_connection (TRACKER_MINER (initable)), - limit); - - if (!priv->sparql_buffer) { - g_set_error (error, - tracker_miner_fs_error_quark (), - TRACKER_MINER_FS_ERROR_INIT, - "Could not create TrackerSparqlBuffer needed to process resources"); - return FALSE; - } - - g_signal_connect (priv->sparql_buffer, "notify::limit-reached", - G_CALLBACK (task_pool_limit_reached_notify_cb), - initable); - - if (!priv->indexing_tree) { - g_set_error (error, - tracker_miner_fs_error_quark (), - TRACKER_MINER_FS_ERROR_INIT, - "Could not create TrackerIndexingTree needed to manage content indexed"); - return FALSE; - } - - g_signal_connect (priv->indexing_tree, "directory-removed", - G_CALLBACK (indexing_tree_directory_removed), - initable); - - /* Create the file notifier */ - priv->file_notifier = tracker_file_notifier_new (priv->indexing_tree, - priv->data_provider, - tracker_miner_get_connection (TRACKER_MINER (initable))); - - if (!priv->file_notifier) { - g_set_error (error, - tracker_miner_fs_error_quark (), - TRACKER_MINER_FS_ERROR_INIT, - "Could not create TrackerFileNotifier needed to signal new resources to be indexed"); - return FALSE; - } - - g_signal_connect (priv->file_notifier, "file-created", - G_CALLBACK (file_notifier_file_created), - initable); - g_signal_connect (priv->file_notifier, "file-updated", - G_CALLBACK (file_notifier_file_updated), - initable); - g_signal_connect (priv->file_notifier, "file-deleted", - G_CALLBACK (file_notifier_file_deleted), - initable); - g_signal_connect (priv->file_notifier, "file-moved", - G_CALLBACK (file_notifier_file_moved), - initable); - g_signal_connect (priv->file_notifier, "directory-started", - G_CALLBACK (file_notifier_directory_started), - initable); - g_signal_connect (priv->file_notifier, "directory-finished", - G_CALLBACK (file_notifier_directory_finished), - initable); - g_signal_connect (priv->file_notifier, "finished", - G_CALLBACK (file_notifier_finished), - initable); - - return TRUE; -} - -static void -miner_fs_initable_iface_init (GInitableIface *iface) -{ - miner_fs_initable_parent_iface = g_type_interface_peek_parent (iface); - iface->init = miner_fs_initable_init; -} - -static QueueEvent * -queue_event_new (TrackerMinerFSEventType type, - GFile *file) -{ - QueueEvent *event; - - g_assert (type != TRACKER_MINER_FS_EVENT_MOVED); - - event = g_new0 (QueueEvent, 1); - event->type = type; - g_set_object (&event->file, file); - - return event; -} - -static QueueEvent * -queue_event_moved_new (GFile *source, - GFile *dest) -{ - QueueEvent *event; - - event = g_new0 (QueueEvent, 1); - event->type = TRACKER_MINER_FS_EVENT_MOVED; - g_set_object (&event->dest_file, dest); - g_set_object (&event->file, source); - - return event; -} - -static GList * -queue_event_get_last_event_node (QueueEvent *event) -{ - return g_object_get_qdata (G_OBJECT (event->file), - quark_last_queue_event); -} - -static void -queue_event_save_node (QueueEvent *event, - GList *node) -{ - g_assert (node->data == event); - g_object_set_qdata (G_OBJECT (event->file), - quark_last_queue_event, node); -} - -static void -queue_event_dispose_node (QueueEvent *event) -{ - GList *node; - - node = queue_event_get_last_event_node (event); - - if (node && node->data == event) { - g_object_steal_qdata (G_OBJECT (event->file), - quark_last_queue_event); - } -} - -static void -queue_event_free (QueueEvent *event) -{ - queue_event_dispose_node (event); - - g_clear_object (&event->dest_file); - g_clear_object (&event->file); - g_free (event); -} - -static QueueCoalesceAction -queue_event_coalesce (const QueueEvent *first, - const QueueEvent *second, - QueueEvent **replacement) -{ - *replacement = NULL; - - if (first->type == TRACKER_MINER_FS_EVENT_CREATED) { - if ((second->type == TRACKER_MINER_FS_EVENT_UPDATED || - second->type == TRACKER_MINER_FS_EVENT_CREATED) && - first->file == second->file) { - return QUEUE_ACTION_DELETE_SECOND; - } else if (second->type == TRACKER_MINER_FS_EVENT_MOVED && - first->file == second->file) { - *replacement = queue_event_new (TRACKER_MINER_FS_EVENT_CREATED, - second->dest_file); - return (QUEUE_ACTION_DELETE_FIRST | - QUEUE_ACTION_DELETE_SECOND); - } else if (second->type == TRACKER_MINER_FS_EVENT_DELETED && - first->file == second->file) { - /* We can't be sure that "create" is replacing a file - * here. Preserve the second event just in case. - */ - return QUEUE_ACTION_DELETE_FIRST; - } - } else if (first->type == TRACKER_MINER_FS_EVENT_UPDATED) { - if (second->type == TRACKER_MINER_FS_EVENT_UPDATED && - first->file == second->file) { - if (first->attributes_update && !second->attributes_update) - return QUEUE_ACTION_DELETE_FIRST; - else - return QUEUE_ACTION_DELETE_SECOND; - } else if (second->type == TRACKER_MINER_FS_EVENT_DELETED && - first->file == second->file) { - return QUEUE_ACTION_DELETE_FIRST; - } - } else if (first->type == TRACKER_MINER_FS_EVENT_MOVED) { - if (second->type == TRACKER_MINER_FS_EVENT_MOVED && - first->dest_file == second->file) { - if (first->file != second->dest_file) { - *replacement = queue_event_moved_new (first->file, - second->dest_file); - } - - return (QUEUE_ACTION_DELETE_FIRST | - QUEUE_ACTION_DELETE_SECOND); - } else if (second->type == TRACKER_MINER_FS_EVENT_DELETED && - first->dest_file == second->file) { - *replacement = queue_event_new (TRACKER_MINER_FS_EVENT_DELETED, - first->file); - return (QUEUE_ACTION_DELETE_FIRST | - QUEUE_ACTION_DELETE_SECOND); - } - } else if (first->type == TRACKER_MINER_FS_EVENT_DELETED && - second->type == TRACKER_MINER_FS_EVENT_DELETED) { - return QUEUE_ACTION_DELETE_SECOND; - } - - return QUEUE_ACTION_NONE; -} - -static gboolean -queue_event_is_descendant (QueueEvent *event, - GFile *prefix) -{ - return g_file_has_prefix (event->file, prefix); -} - -static gboolean -queue_event_is_equal_or_descendant (QueueEvent *event, - GFile *prefix) -{ - return (g_file_equal (event->file, prefix) || - g_file_has_prefix (event->file, prefix)); -} - -static void -fs_finalize (GObject *object) -{ - TrackerMinerFSPrivate *priv; - - priv = TRACKER_MINER_FS (object)->priv; - - g_timer_destroy (priv->timer); - g_timer_destroy (priv->extraction_timer); - - if (priv->item_queues_handler_id) { - g_source_remove (priv->item_queues_handler_id); - priv->item_queues_handler_id = 0; - } - - if (priv->item_queue_blocker) { - g_object_unref (priv->item_queue_blocker); - } - - if (priv->file_notifier) { - tracker_file_notifier_stop (priv->file_notifier); - } - - /* Cancel every pending task */ - tracker_task_pool_foreach (priv->task_pool, - task_pool_cancel_foreach, - NULL); - g_object_unref (priv->task_pool); - - if (priv->sparql_buffer) { - g_object_unref (priv->sparql_buffer); - } - - tracker_priority_queue_foreach (priv->items, - (GFunc) queue_event_free, - NULL); - tracker_priority_queue_unref (priv->items); - - g_object_unref (priv->root); - - if (priv->indexing_tree) { - g_object_unref (priv->indexing_tree); - } - - if (priv->file_notifier) { - g_object_unref (priv->file_notifier); - } - - if (priv->roots_to_notify) { - g_hash_table_unref (priv->roots_to_notify); - - /* Just in case we end up using this AFTER finalize, not expected */ - priv->roots_to_notify = NULL; - } - - G_OBJECT_CLASS (tracker_miner_fs_parent_class)->finalize (object); -} - -static void -fs_constructed (GObject *object) -{ - TrackerMinerFSPrivate *priv; - - /* NOTE: We have to do this in this order because initables - * are called _AFTER_ constructed and for subclasses that are - * not initables we don't have any other way than to chain - * constructed and root/indexing tree must exist at that - * point. - * - * If priv->indexing_tree is NULL after this function, the - * initiable functions will fail and this class will not be - * created anyway. - */ - G_OBJECT_CLASS (tracker_miner_fs_parent_class)->constructed (object); - - priv = TRACKER_MINER_FS (object)->priv; - - /* Create root if one didn't exist */ - if (priv->root == NULL) { - /* We default to file:/// */ - priv->root = g_file_new_for_uri ("file:///"); - } - - /* Create indexing tree */ - priv->indexing_tree = tracker_indexing_tree_new_with_root (priv->root); -} - -static void -fs_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - TrackerMinerFS *fs = TRACKER_MINER_FS (object); - - switch (prop_id) { - case PROP_THROTTLE: - tracker_miner_fs_set_throttle (TRACKER_MINER_FS (object), - g_value_get_double (value)); - break; - case PROP_ROOT: - /* We expect this to only occur once, on object construct */ - fs->priv->root = g_value_dup_object (value); - break; - case PROP_WAIT_POOL_LIMIT: - tracker_task_pool_set_limit (fs->priv->task_pool, - g_value_get_uint (value)); - break; - case PROP_READY_POOL_LIMIT: - fs->priv->sparql_buffer_limit = g_value_get_uint (value); - - if (fs->priv->sparql_buffer) { - tracker_task_pool_set_limit (TRACKER_TASK_POOL (fs->priv->sparql_buffer), - fs->priv->sparql_buffer_limit); - } - break; - case PROP_DATA_PROVIDER: - fs->priv->data_provider = g_value_dup_object (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -fs_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - TrackerMinerFS *fs; - - fs = TRACKER_MINER_FS (object); - - switch (prop_id) { - case PROP_THROTTLE: - g_value_set_double (value, fs->priv->throttle); - break; - case PROP_ROOT: - g_value_set_object (value, fs->priv->root); - break; - case PROP_WAIT_POOL_LIMIT: - g_value_set_uint (value, tracker_task_pool_get_limit (fs->priv->task_pool)); - break; - case PROP_READY_POOL_LIMIT: - g_value_set_uint (value, fs->priv->sparql_buffer_limit); - break; - case PROP_DATA_PROVIDER: - g_value_set_object (value, fs->priv->data_provider); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -task_pool_limit_reached_notify_cb (GObject *object, - GParamSpec *pspec, - gpointer user_data) -{ - if (!tracker_task_pool_limit_reached (TRACKER_TASK_POOL (object))) { - item_queue_handlers_set_up (TRACKER_MINER_FS (user_data)); - } -} - -static void -miner_started (TrackerMiner *miner) -{ - TrackerMinerFS *fs; - - fs = TRACKER_MINER_FS (miner); - - fs->priv->been_started = TRUE; - - g_info ("Initializing"); - - g_object_set (miner, - "progress", 0.0, - "status", "Initializing", - "remaining-time", 0, - NULL); - - tracker_file_notifier_start (fs->priv->file_notifier); -} - -static void -miner_stopped (TrackerMiner *miner) -{ - g_info ("Idle"); - - g_object_set (miner, - "progress", 1.0, - "status", "Idle", - "remaining-time", -1, - NULL); -} - -static void -miner_paused (TrackerMiner *miner) -{ - TrackerMinerFS *fs; - - fs = TRACKER_MINER_FS (miner); - - fs->priv->is_paused = TRUE; - - tracker_file_notifier_stop (fs->priv->file_notifier); - - if (fs->priv->item_queues_handler_id) { - g_source_remove (fs->priv->item_queues_handler_id); - fs->priv->item_queues_handler_id = 0; - } -} - -static void -miner_resumed (TrackerMiner *miner) -{ - TrackerMinerFS *fs; - - fs = TRACKER_MINER_FS (miner); - - fs->priv->is_paused = FALSE; - - tracker_file_notifier_start (fs->priv->file_notifier); - - /* Only set up queue handler if we have items waiting to be - * processed. - */ - if (tracker_miner_fs_has_items_to_process (fs)) { - item_queue_handlers_set_up (fs); - } -} - -static void -notify_roots_finished (TrackerMinerFS *fs, - gboolean check_queues) -{ - GHashTableIter iter; - gpointer key, value; - - if (check_queues && - fs->priv->roots_to_notify && - g_hash_table_size (fs->priv->roots_to_notify) < 2) { - /* Technically, if there is only one root, it's - * pointless to do anything before the FINISHED (not - * FINISHED_ROOT) signal is emitted. In that - * situation we calls function first anyway with - * check_queues=FALSE so we still notify roots. This - * is really just for efficiency. - */ - return; - } else if (fs->priv->roots_to_notify == NULL || - g_hash_table_size (fs->priv->roots_to_notify) < 1) { - /* Nothing to do */ - return; - } - - g_hash_table_iter_init (&iter, fs->priv->roots_to_notify); - while (g_hash_table_iter_next (&iter, &key, &value)) { - GFile *root = key; - - /* Check if any content for root is still in the queue - * to be processed. This is only called each time a - * container/folder has been added to Tracker (so not - * too frequently) - */ - if (check_queues && - tracker_priority_queue_find (fs->priv->items, NULL, (GEqualFunc) queue_event_is_descendant, root)) { - continue; - } - - /* Signal root is finished */ - g_signal_emit (fs, signals[FINISHED_ROOT], 0, root); - - /* Remove from hash table */ - g_hash_table_iter_remove (&iter); - } -} - -static void -process_print_stats (TrackerMinerFS *fs) -{ - /* Only do this the first time, otherwise the results are - * likely to be inaccurate. Devices can be added or removed so - * we can't assume stats are correct. - */ - if (!fs->priv->shown_totals) { - fs->priv->shown_totals = TRUE; - - g_info ("--------------------------------------------------"); - g_info ("Total directories : %d (%d ignored)", - fs->priv->total_directories_found, - fs->priv->total_directories_ignored); - g_info ("Total files : %d (%d ignored)", - fs->priv->total_files_found, - fs->priv->total_files_ignored); -#if 0 - g_info ("Total monitors : %d", - tracker_monitor_get_count (fs->priv->monitor)); -#endif - g_info ("Total processed : %d (%d notified, %d with error)", - fs->priv->total_files_processed, - fs->priv->total_files_notified, - fs->priv->total_files_notified_error); - g_info ("--------------------------------------------------\n"); - } -} - -static void -process_stop (TrackerMinerFS *fs) -{ - /* Now we have finished crawling, print stats and enable monitor events */ - process_print_stats (fs); - - g_timer_stop (fs->priv->timer); - g_timer_stop (fs->priv->extraction_timer); - - fs->priv->timer_stopped = TRUE; - fs->priv->extraction_timer_stopped = TRUE; - - g_info ("Idle"); - - g_object_set (fs, - "progress", 1.0, - "status", "Idle", - "remaining-time", 0, - NULL); - - /* Make sure we signal _ALL_ roots as finished before the - * main FINISHED signal - */ - notify_roots_finished (fs, FALSE); - - g_signal_emit (fs, signals[FINISHED], 0, - g_timer_elapsed (fs->priv->timer, NULL), - fs->priv->total_directories_found, - fs->priv->total_directories_ignored, - fs->priv->total_files_found, - fs->priv->total_files_ignored); - - g_timer_stop (fs->priv->timer); - g_timer_stop (fs->priv->extraction_timer); - - fs->priv->total_directories_found = 0; - fs->priv->total_directories_ignored = 0; - fs->priv->total_files_found = 0; - fs->priv->total_files_ignored = 0; - - fs->priv->been_crawled = TRUE; -} - -static gboolean -item_queue_is_blocked_by_file (TrackerMinerFS *fs, - GFile *file) -{ - g_return_val_if_fail (G_IS_FILE (file), FALSE); - - if (fs->priv->item_queue_blocker != NULL && - (fs->priv->item_queue_blocker == file || - g_file_equal (fs->priv->item_queue_blocker, file))) { - return TRUE; - } - - return FALSE; -} - -static void -sparql_buffer_task_finished_cb (GObject *object, - GAsyncResult *result, - gpointer user_data) -{ - TrackerMinerFS *fs; - TrackerMinerFSPrivate *priv; - TrackerTask *task; - GFile *task_file; - gboolean recursive; - GError *error = NULL; - - fs = user_data; - priv = fs->priv; - - task = tracker_sparql_buffer_push_finish (TRACKER_SPARQL_BUFFER (object), - result, &error); - - if (error) { - g_critical ("Could not execute sparql: %s", error->message); - priv->total_files_notified_error++; - g_error_free (error); - } - - task_file = tracker_task_get_file (task); - - recursive = GPOINTER_TO_INT (g_object_steal_qdata (G_OBJECT (task_file), - priv->quark_recursive_removal)); - tracker_file_notifier_invalidate_file_iri (priv->file_notifier, task_file, recursive); - - if (item_queue_is_blocked_by_file (fs, task_file)) { - g_object_unref (priv->item_queue_blocker); - priv->item_queue_blocker = NULL; - } - - if (priv->item_queue_blocker != NULL) { - if (tracker_task_pool_get_size (TRACKER_TASK_POOL (object)) > 0) { - tracker_sparql_buffer_flush (TRACKER_SPARQL_BUFFER (object), - "Item queue still blocked after flush"); - - /* Check if we've finished inserting for given prefixes ... */ - notify_roots_finished (fs, TRUE); - } - } else { - item_queue_handlers_set_up (fs); - } - - tracker_task_unref (task); -} - -static UpdateProcessingTaskContext * -update_processing_task_context_new (TrackerMiner *miner, - gint priority, - const gchar *urn, - GCancellable *cancellable) -{ - UpdateProcessingTaskContext *ctxt; - - ctxt = g_slice_new0 (UpdateProcessingTaskContext); - ctxt->miner = miner; - ctxt->urn = g_strdup (urn); - ctxt->priority = priority; - - if (cancellable) { - ctxt->cancellable = g_object_ref (cancellable); - } - - return ctxt; -} - -static void -update_processing_task_context_free (UpdateProcessingTaskContext *ctxt) -{ - g_free (ctxt->urn); - - if (ctxt->cancellable) { - g_object_unref (ctxt->cancellable); - } - - g_slice_free (UpdateProcessingTaskContext, ctxt); -} - -static void -on_signal_gtask_complete (GObject *source, - GAsyncResult *res, - gpointer user_data) -{ - TrackerMinerFS *fs = TRACKER_MINER_FS (source); - TrackerTask *task, *sparql_task = NULL; - UpdateProcessingTaskContext *ctxt; - GError *error = NULL; - GFile *file = user_data; - gchar *uri, *sparql; - - sparql = g_task_propagate_pointer (G_TASK (res), &error); - g_object_unref (res); - - task = tracker_task_pool_find (fs->priv->task_pool, file); - g_assert (task != NULL); - - ctxt = tracker_task_get_data (task); - uri = g_file_get_uri (file); - - if (error) { - g_message ("Could not process '%s': %s", uri, error->message); - g_error_free (error); - - fs->priv->total_files_notified_error++; - } else { - fs->priv->total_files_notified++; - - if (ctxt->urn) { - /* The SPARQL builder will already contain the necessary - * DELETE statements for the properties being updated */ - g_debug ("Updating item '%s' with urn '%s'", - uri, - ctxt->urn); - } else { - g_debug ("Creating new item '%s'", uri); - } - - sparql_task = tracker_sparql_task_new_take_sparql_str (file, sparql); - } - - if (sparql_task) { - tracker_sparql_buffer_push (fs->priv->sparql_buffer, - sparql_task, - ctxt->priority, - sparql_buffer_task_finished_cb, - fs); - - if (item_queue_is_blocked_by_file (fs, file)) { - tracker_sparql_buffer_flush (fs->priv->sparql_buffer, "Current file is blocking item queue"); - - /* Check if we've finished inserting for given prefixes ... */ - notify_roots_finished (fs, TRUE); - } - - /* We can let go of our reference here because the - * sparql buffer takes its own reference when adding - * it to the task pool. - */ - tracker_task_unref (sparql_task); - } else { - if (item_queue_is_blocked_by_file (fs, file)) { - /* Make sure that we don't stall the item queue, although we could - * expect the file to be reenqueued until the loop detector makes - * us drop it since we were specifically waiting for it to complete. - */ - g_object_unref (fs->priv->item_queue_blocker); - fs->priv->item_queue_blocker = NULL; - item_queue_handlers_set_up (fs); - } - } - - /* Last reference is kept by the pool, removing the task from - * the pool cleans up the task too! - * - * NOTE that calling this any earlier actually causes invalid - * reads because the task frees up the - * UpdateProcessingTaskContext and GFile. - */ - tracker_task_pool_remove (fs->priv->task_pool, task); - - if (tracker_miner_fs_has_items_to_process (fs) == FALSE && - tracker_task_pool_get_size (TRACKER_TASK_POOL (fs->priv->task_pool)) == 0) { - /* We need to run this one more time to trigger process_stop() */ - item_queue_handlers_set_up (fs); - } - - g_free (uri); -} - -static gboolean -item_add_or_update (TrackerMinerFS *fs, - GFile *file, - gint priority, - gboolean attributes_update) -{ - TrackerMinerFSPrivate *priv; - UpdateProcessingTaskContext *ctxt; - GCancellable *cancellable; - gboolean processing; - TrackerTask *task; - const gchar *urn; - gchar *uri; - GTask *gtask; - - priv = fs->priv; - - cancellable = g_cancellable_new (); - g_object_ref (file); - - urn = tracker_file_notifier_get_file_iri (fs->priv->file_notifier, - file, FALSE); - - /* Create task and add it to the pool as a WAIT task (we need to extract - * the file metadata and such) */ - ctxt = update_processing_task_context_new (TRACKER_MINER (fs), - priority, - urn, - cancellable); - task = tracker_task_new (file, ctxt, - (GDestroyNotify) update_processing_task_context_free); - - tracker_task_pool_add (priv->task_pool, task); - tracker_task_unref (task); - - /* Call ::process-file to see if we handle this resource or not */ - uri = g_file_get_uri (file); - - gtask = g_task_new (fs, ctxt->cancellable, on_signal_gtask_complete, file); - - if (!attributes_update) { - g_debug ("Processing file '%s'...", uri); - g_signal_emit (fs, signals[PROCESS_FILE], 0, - file, gtask, - &processing); - } else { - g_debug ("Processing attributes in file '%s'...", uri); - g_signal_emit (fs, signals[PROCESS_FILE_ATTRIBUTES], 0, - file, gtask, - &processing); - } - - if (!processing) { - GError *error; - - error = g_error_new (tracker_miner_fs_error_quark (), - TRACKER_MINER_FS_ERROR_INIT, - "TrackerMinerFS::process-file returned FALSE"); - g_task_return_error (gtask, error); - } else { - fs->priv->total_files_processed++; - } - - g_free (uri); - g_object_unref (file); - g_object_unref (cancellable); - - return !tracker_task_pool_limit_reached (priv->task_pool); -} - -static gboolean -item_remove (TrackerMinerFS *fs, - GFile *file, - gboolean only_children, - GString *task_sparql) -{ - gchar *uri, *sparql; - guint signal_num; - - uri = g_file_get_uri (file); - - g_debug ("Removing item: '%s' (Deleted from filesystem or no longer monitored)", - uri); - - g_object_set_qdata (G_OBJECT (file), - fs->priv->quark_recursive_removal, - GINT_TO_POINTER (TRUE)); - - /* Call the implementation to generate a SPARQL update for the removal. */ - signal_num = only_children ? REMOVE_CHILDREN : REMOVE_FILE; - g_signal_emit (fs, signals[signal_num], 0, file, &sparql); - - if (sparql && sparql[0] != '\0') { - g_string_append (task_sparql, sparql); - g_string_append (task_sparql, ";\n"); - } - - g_free (sparql); - g_free (uri); - - return TRUE; -} - -static gboolean -item_move (TrackerMinerFS *fs, - GFile *dest_file, - GFile *source_file, - GString *dest_task_sparql, - GString *source_task_sparql) -{ - gchar *uri, *source_uri, *sparql; - GFileInfo *file_info; - const gchar *source_iri; - gboolean source_exists; - TrackerDirectoryFlags source_flags, flags; - gboolean recursive; - - uri = g_file_get_uri (dest_file); - source_uri = g_file_get_uri (source_file); - - /* FIXME: Should check the _NO_STAT on TrackerDirectoryFlags first! */ - file_info = g_file_query_info (dest_file, - G_FILE_ATTRIBUTE_STANDARD_TYPE, - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, - NULL, NULL); - - /* Get 'source' ID */ - source_iri = tracker_file_notifier_get_file_iri (fs->priv->file_notifier, - source_file, TRUE); - source_exists = (source_iri != NULL); - - if (!file_info) { - gboolean retval; - - if (source_exists) { - /* Destination file has gone away, ignore dest file and remove source if any */ - retval = item_remove (fs, source_file, FALSE, source_task_sparql); - } else { - /* Destination file went away, and source wasn't indexed either */ - retval = TRUE; - } - - g_free (source_uri); - g_free (uri); - - return retval; - } else if (!source_exists) { - gboolean retval; - - /* The source file might not be indexed yet (eg. temporary save - * files that are immediately renamed to the definitive path). - * Deal with those as newly added items. - */ - g_debug ("Source file '%s' not yet in store, indexing '%s' " - "from scratch", source_uri, uri); - - retval = item_add_or_update (fs, dest_file, G_PRIORITY_DEFAULT, FALSE); - - g_free (source_uri); - g_free (uri); - g_object_unref (file_info); - - return retval; - } - - g_debug ("Moving item from '%s' to '%s'", - source_uri, - uri); - - tracker_indexing_tree_get_root (fs->priv->indexing_tree, source_file, &source_flags); - tracker_indexing_tree_get_root (fs->priv->indexing_tree, dest_file, &flags); - recursive = ((source_flags & TRACKER_DIRECTORY_FLAG_RECURSE) != 0 && - (flags & TRACKER_DIRECTORY_FLAG_RECURSE) != 0 && - g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY); - - /* Delete destination item from store if any */ - item_remove (fs, dest_file, FALSE, dest_task_sparql); - - /* If the original location is recursive, but the destination location - * is not, remove all children. - */ - if (!recursive && - (source_flags & TRACKER_DIRECTORY_FLAG_RECURSE) != 0) - item_remove (fs, source_file, TRUE, source_task_sparql); - - g_signal_emit (fs, signals[MOVE_FILE], 0, dest_file, source_file, recursive, &sparql); - - if (sparql && sparql[0] != '\0') { - /* This is treated as a task on dest_file */ - g_string_append (dest_task_sparql, sparql); - g_string_append (dest_task_sparql, ";\n"); - } - - g_free (sparql); - g_free (uri); - g_free (source_uri); - g_object_unref (file_info); - - return TRUE; -} - -static gboolean -should_wait (TrackerMinerFS *fs, - GFile *file) -{ - GFile *parent; - - /* Is the item already being processed? */ - if (tracker_task_pool_find (fs->priv->task_pool, file) || - tracker_task_pool_find (TRACKER_TASK_POOL (fs->priv->sparql_buffer), file)) { - /* Yes, a previous event on same item currently - * being processed */ - fs->priv->item_queue_blocker = g_object_ref (file); - return TRUE; - } - - /* Is the item's parent being processed right now? */ - parent = g_file_get_parent (file); - if (parent) { - if (tracker_task_pool_find (fs->priv->task_pool, parent) || - tracker_task_pool_find (TRACKER_TASK_POOL (fs->priv->sparql_buffer), parent)) { - /* Yes, a previous event on the parent of this item - * currently being processed */ - fs->priv->item_queue_blocker = parent; - return TRUE; - } - - g_object_unref (parent); - } - return FALSE; -} - -static gboolean -item_queue_get_next_file (TrackerMinerFS *fs, - GFile **file, - GFile **source_file, - TrackerMinerFSEventType *type, - gint *priority_out, - gboolean *attributes_update) -{ - QueueEvent *event; - gint priority; - - *file = NULL; - *source_file = NULL; - - if (tracker_file_notifier_is_active (fs->priv->file_notifier) || - tracker_task_pool_limit_reached (fs->priv->task_pool) || - tracker_task_pool_limit_reached (TRACKER_TASK_POOL (fs->priv->sparql_buffer))) { - if (tracker_task_pool_get_size (fs->priv->task_pool) == 0) { - fs->priv->extraction_timer_stopped = TRUE; - g_timer_stop (fs->priv->extraction_timer); - } - - /* There are still pending items to crawl, - * or extract pool limit is reached - */ - return FALSE; - } - - event = tracker_priority_queue_peek (fs->priv->items, &priority); - - if (event) { - if (should_wait (fs, event->file) || - (event->dest_file && should_wait (fs, event->dest_file))) { - return FALSE; - } - - if (event->type == TRACKER_MINER_FS_EVENT_MOVED) { - g_set_object (file, event->dest_file); - g_set_object (source_file, event->file); - } else { - g_set_object (file, event->file); - } - - *type = event->type; - *priority_out = priority; - *attributes_update = event->attributes_update; - - queue_event_free (event); - tracker_priority_queue_pop (fs->priv->items, NULL); - } - - return TRUE; -} - -static gdouble -item_queue_get_progress (TrackerMinerFS *fs, - guint *n_items_processed, - guint *n_items_remaining) -{ - guint items_to_process = 0; - guint items_total = 0; - - items_to_process += tracker_priority_queue_get_length (fs->priv->items); - - items_total += fs->priv->total_directories_found; - items_total += fs->priv->total_files_found; - - if (n_items_processed) { - *n_items_processed = ((items_total >= items_to_process) ? - (items_total - items_to_process) : 0); - } - - if (n_items_remaining) { - *n_items_remaining = items_to_process; - } - - if (items_total == 0 || - items_to_process == 0 || - items_to_process > items_total) { - return 1.0; - } - - return (gdouble) (items_total - items_to_process) / items_total; -} - -/* Add a task to the processing pool to update stored information on 'file'. - * - * This function takes ownership of the 'sparql' string. - */ -static void -push_task (TrackerMinerFS *fs, - GFile *file, - gchar *sparql) -{ - TrackerTask *task; - - task = tracker_sparql_task_new_take_sparql_str (file, sparql); - tracker_sparql_buffer_push (fs->priv->sparql_buffer, - task, - G_PRIORITY_DEFAULT, - sparql_buffer_task_finished_cb, - fs); - tracker_task_unref (task); -} - -static gboolean -miner_handle_next_item (TrackerMinerFS *fs) -{ - GFile *file = NULL; - GFile *source_file = NULL; - GFile *parent; - GTimeVal time_now; - static GTimeVal time_last = { 0 }; - gboolean keep_processing = TRUE; - gboolean attributes_update = FALSE; - TrackerMinerFSEventType type; - gint priority = 0; - GString *task_sparql = NULL; - GString *source_task_sparql = NULL; - - if (fs->priv->timer_stopped) { - g_timer_start (fs->priv->timer); - fs->priv->timer_stopped = FALSE; - } - - if (tracker_task_pool_limit_reached (TRACKER_TASK_POOL (fs->priv->sparql_buffer))) { - /* Task pool is full, give it a break */ - return FALSE; - } - - if (!item_queue_get_next_file (fs, &file, &source_file, &type, &priority, &attributes_update)) { - /* We should flush the processing pool buffer here, because - * if there was a previous task on the same file we want to - * process now, we want it to get finished before we can go - * on with the queues... */ - tracker_sparql_buffer_flush (fs->priv->sparql_buffer, - "Queue handlers WAIT"); - - /* Check if we've finished inserting for given prefixes ... */ - notify_roots_finished (fs, TRUE); - - /* Items are still being processed, so wait until - * the processing pool is cleared before starting with - * the next directories batch. - */ - return FALSE; - } - - if (file == NULL) { - g_timer_stop (fs->priv->extraction_timer); - fs->priv->extraction_timer_stopped = TRUE; - } else if (fs->priv->extraction_timer_stopped) { - g_timer_continue (fs->priv->extraction_timer); - fs->priv->extraction_timer_stopped = FALSE; - } - - /* Update progress, but don't spam it. */ - g_get_current_time (&time_now); - - if ((time_now.tv_sec - time_last.tv_sec) >= 1) { - guint items_processed, items_remaining; - gdouble progress_now; - static gdouble progress_last = 0.0; - static gint info_last = 0; - gdouble seconds_elapsed, extraction_elapsed; - - time_last = time_now; - - /* Update progress? */ - progress_now = item_queue_get_progress (fs, - &items_processed, - &items_remaining); - seconds_elapsed = g_timer_elapsed (fs->priv->timer, NULL); - extraction_elapsed = g_timer_elapsed (fs->priv->extraction_timer, NULL); - - if (!tracker_file_notifier_is_active (fs->priv->file_notifier)) { - gchar *status; - gint remaining_time; - - g_object_get (fs, "status", &status, NULL); - - /* Compute remaining time */ - remaining_time = (gint)tracker_seconds_estimate (extraction_elapsed, - items_processed, - items_remaining); - - /* CLAMP progress so it doesn't go back below - * 2% (which we use for crawling) - */ - if (g_strcmp0 (status, "Processing…") != 0) { - /* Don't spam this */ - g_info ("Processing…"); - g_object_set (fs, - "status", "Processing…", - "progress", CLAMP (progress_now, 0.02, 1.00), - "remaining-time", remaining_time, - NULL); - } else { - g_object_set (fs, - "progress", CLAMP (progress_now, 0.02, 1.00), - "remaining-time", remaining_time, - NULL); - } - - g_free (status); - } - - if (++info_last >= 5 && - (gint) (progress_last * 100) != (gint) (progress_now * 100)) { - gchar *str1, *str2; - - info_last = 0; - progress_last = progress_now; - - /* Log estimated remaining time */ - str1 = tracker_seconds_estimate_to_string (extraction_elapsed, - TRUE, - items_processed, - items_remaining); - str2 = tracker_seconds_to_string (seconds_elapsed, TRUE); - - g_info ("Processed %u/%u, estimated %s left, %s elapsed", - items_processed, - items_processed + items_remaining, - str1, - str2); - - g_free (str2); - g_free (str1); - } - } - - if (file == NULL) { - if (!tracker_file_notifier_is_active (fs->priv->file_notifier) && - tracker_task_pool_get_size (fs->priv->task_pool) == 0) { - if (tracker_task_pool_get_size (TRACKER_TASK_POOL (fs->priv->sparql_buffer)) == 0) { - /* Print stats and signal finished */ - process_stop (fs); - } else { - /* Flush any possible pending update here */ - tracker_sparql_buffer_flush (fs->priv->sparql_buffer, - "Queue handlers NONE"); - - /* Check if we've finished inserting for given prefixes ... */ - notify_roots_finished (fs, TRUE); - } - } - - /* No more files left to process */ - return FALSE; - } - - /* Handle queues */ - switch (type) { - case TRACKER_MINER_FS_EVENT_MOVED: - task_sparql = g_string_new (""); - source_task_sparql = g_string_new (""); - keep_processing = item_move (fs, file, source_file, task_sparql, source_task_sparql); - break; - case TRACKER_MINER_FS_EVENT_DELETED: - task_sparql = g_string_new (""); - keep_processing = item_remove (fs, file, FALSE, task_sparql); - break; - case TRACKER_MINER_FS_EVENT_CREATED: - case TRACKER_MINER_FS_EVENT_UPDATED: - parent = g_file_get_parent (file); - - if (!parent || - tracker_indexing_tree_file_is_root (fs->priv->indexing_tree, file) || - !tracker_indexing_tree_get_root (fs->priv->indexing_tree, file, NULL) || - tracker_file_notifier_get_file_iri (fs->priv->file_notifier, parent, TRUE)) { - keep_processing = item_add_or_update (fs, file, priority, attributes_update); - } else { - gchar *uri; - - /* We got an event on a file that has not its parent indexed - * even though it should. Given item_queue_get_next_file() - * above should return FALSE whenever the parent file is - * being processed, this means the parent is neither - * being processed nor indexed, no good. - * - * Bail out in these cases by removing all queued files - * inside the missing file. Whatever it was, it shall - * hopefully be fixed on next index. - */ - uri = g_file_get_uri (parent); - g_warning ("Parent '%s' not indexed yet", uri); - g_free (uri); - - tracker_priority_queue_foreach_remove (fs->priv->items, - (GEqualFunc) queue_event_is_equal_or_descendant, - parent, - (GDestroyNotify) queue_event_free); - keep_processing = TRUE; - } - - if (parent) { - g_object_unref (parent); - } - - break; - default: - g_assert_not_reached (); - } - - if (source_task_sparql) { - if (source_task_sparql->len == 0) { - g_string_free (source_task_sparql, TRUE); - } else { - push_task (fs, source_file, g_string_free (source_task_sparql, FALSE)); - } - } - - if (task_sparql) { - if (task_sparql->len == 0) { - g_string_free (task_sparql, TRUE); - } else { - push_task (fs, file, g_string_free (task_sparql, FALSE)); - } - } - - if (!tracker_task_pool_limit_reached (TRACKER_TASK_POOL (fs->priv->sparql_buffer))) { - item_queue_handlers_set_up (fs); - } - - if (file) { - g_object_unref (file); - } - - if (source_file) { - g_object_unref (source_file); - } - - return keep_processing; -} - -static gboolean -item_queue_handlers_cb (gpointer user_data) -{ - TrackerMinerFS *fs = user_data; - gboolean retval = FALSE; - gint i; - - for (i = 0; i < MAX_SIMULTANEOUS_ITEMS; i++) { - retval = miner_handle_next_item (fs); - if (retval == FALSE) - break; - } - - if (retval == FALSE) { - fs->priv->item_queues_handler_id = 0; - } - - return retval; -} - -static guint -_tracker_idle_add (TrackerMinerFS *fs, - GSourceFunc func, - gpointer user_data) -{ - guint interval; - - interval = TRACKER_CRAWLER_MAX_TIMEOUT_INTERVAL * fs->priv->throttle; - - if (interval == 0) { - return g_idle_add_full (TRACKER_TASK_PRIORITY, func, user_data, NULL); - } else { - return g_timeout_add_full (TRACKER_TASK_PRIORITY, interval, func, user_data, NULL); - } -} - -static void -item_queue_handlers_set_up (TrackerMinerFS *fs) -{ - trace_eq ("Setting up queue handlers..."); - if (fs->priv->item_queues_handler_id != 0) { - trace_eq (" cancelled: already one active"); - return; - } - - if (fs->priv->is_paused) { - trace_eq (" cancelled: paused"); - return; - } - - if (fs->priv->item_queue_blocker) { - trace_eq (" cancelled: item queue blocked waiting for file '%s'", - g_file_get_uri (fs->priv->item_queue_blocker)); - return; - } - - /* Already processing max number of sparql updates */ - if (tracker_task_pool_limit_reached (fs->priv->task_pool)) { - trace_eq (" cancelled: pool limit reached (tasks: %u (max %u)", - tracker_task_pool_get_size (fs->priv->task_pool), - tracker_task_pool_get_limit (fs->priv->task_pool)); - return; - } - - if (tracker_task_pool_limit_reached (TRACKER_TASK_POOL (fs->priv->sparql_buffer))) { - trace_eq (" cancelled: pool limit reached (sparql buffer: %u)", - tracker_task_pool_get_limit (TRACKER_TASK_POOL (fs->priv->sparql_buffer))); - return; - } - - if (!tracker_file_notifier_is_active (fs->priv->file_notifier)) { - gchar *status; - gdouble progress; - - g_object_get (fs, - "progress", &progress, - "status", &status, - NULL); - - /* Don't spam this */ - if (progress > 0.01 && g_strcmp0 (status, "Processing…") != 0) { - g_info ("Processing…"); - g_object_set (fs, "status", "Processing…", NULL); - } - - g_free (status); - } - - trace_eq (" scheduled in idle"); - fs->priv->item_queues_handler_id = - _tracker_idle_add (fs, - item_queue_handlers_cb, - fs); -} - -static gboolean -should_check_file (TrackerMinerFS *fs, - GFile *file, - gboolean is_dir) -{ - GFileType file_type; - - file_type = (is_dir) ? G_FILE_TYPE_DIRECTORY : G_FILE_TYPE_REGULAR; - return tracker_indexing_tree_file_is_indexable (fs->priv->indexing_tree, - file, file_type); -} - -static gint -miner_fs_get_queue_priority (TrackerMinerFS *fs, - GFile *file) -{ - TrackerDirectoryFlags flags; - - tracker_indexing_tree_get_root (fs->priv->indexing_tree, - file, &flags); - - return (flags & TRACKER_DIRECTORY_FLAG_PRIORITY) ? - G_PRIORITY_HIGH : G_PRIORITY_DEFAULT; -} - -static void -miner_fs_queue_event (TrackerMinerFS *fs, - QueueEvent *event, - guint priority) -{ - GList *old = NULL, *link = NULL; - - if (event->type == TRACKER_MINER_FS_EVENT_MOVED) { - /* Remove all children of the dest location from being processed. */ - tracker_priority_queue_foreach_remove (fs->priv->items, - (GEqualFunc) queue_event_is_equal_or_descendant, - event->dest_file, - (GDestroyNotify) queue_event_free); - } - - old = queue_event_get_last_event_node (event); - - if (old) { - QueueCoalesceAction action; - QueueEvent *replacement = NULL; - - action = queue_event_coalesce (old->data, event, &replacement); - - if (action & QUEUE_ACTION_DELETE_FIRST) { - queue_event_free (old->data); - tracker_priority_queue_remove_node (fs->priv->items, - old); - } - - if (action & QUEUE_ACTION_DELETE_SECOND) { - queue_event_free (event); - event = NULL; - } - - if (replacement) - event = replacement; - } - - if (event) { - if (event->type == TRACKER_MINER_FS_EVENT_DELETED) { - /* Remove all children of this file from being processed. */ - tracker_priority_queue_foreach_remove (fs->priv->items, - (GEqualFunc) queue_event_is_equal_or_descendant, - event->file, - (GDestroyNotify) queue_event_free); - } - - /* Ensure IRI is cached */ - tracker_file_notifier_get_file_iri (fs->priv->file_notifier, - event->file, TRUE); - - trace_eq_event (event); - - link = tracker_priority_queue_add (fs->priv->items, event, priority); - queue_event_save_node (event, link); - item_queue_handlers_set_up (fs); - } -} - -static gboolean -filter_event (TrackerMinerFS *fs, - TrackerMinerFSEventType type, - GFile *file, - GFile *source_file) -{ - TrackerMinerFSClass *klass = TRACKER_MINER_FS_GET_CLASS (fs); - - if (!klass->filter_event) - return FALSE; - - return klass->filter_event (fs, type, file, source_file); -} - -static void -file_notifier_file_created (TrackerFileNotifier *notifier, - GFile *file, - gpointer user_data) -{ - TrackerMinerFS *fs = user_data; - QueueEvent *event; - - if (filter_event (fs, TRACKER_MINER_FS_EVENT_CREATED, file, NULL)) - return; - - event = queue_event_new (TRACKER_MINER_FS_EVENT_CREATED, file); - miner_fs_queue_event (fs, event, miner_fs_get_queue_priority (fs, file)); -} - -static void -file_notifier_file_deleted (TrackerFileNotifier *notifier, - GFile *file, - gpointer user_data) -{ - TrackerMinerFS *fs = user_data; - QueueEvent *event; - - if (filter_event (fs, TRACKER_MINER_FS_EVENT_DELETED, file, NULL)) - return; - - if (tracker_file_notifier_get_file_type (notifier, file) == G_FILE_TYPE_DIRECTORY) { - /* Cancel all pending tasks on files inside the path given by file */ - tracker_task_pool_foreach (fs->priv->task_pool, - task_pool_cancel_foreach, - file); - } - - event = queue_event_new (TRACKER_MINER_FS_EVENT_DELETED, file); - miner_fs_queue_event (fs, event, miner_fs_get_queue_priority (fs, file)); -} - -static void -file_notifier_file_updated (TrackerFileNotifier *notifier, - GFile *file, - gboolean attributes_only, - gpointer user_data) -{ - TrackerMinerFS *fs = user_data; - QueueEvent *event; - - if (!attributes_only && - filter_event (fs, TRACKER_MINER_FS_EVENT_UPDATED, file, NULL)) - return; - - event = queue_event_new (TRACKER_MINER_FS_EVENT_UPDATED, file); - event->attributes_update = attributes_only; - miner_fs_queue_event (fs, event, miner_fs_get_queue_priority (fs, file)); -} - -static void -file_notifier_file_moved (TrackerFileNotifier *notifier, - GFile *source, - GFile *dest, - gpointer user_data) -{ - TrackerMinerFS *fs = user_data; - QueueEvent *event; - - if (filter_event (fs, TRACKER_MINER_FS_EVENT_MOVED, dest, source)) - return; - - event = queue_event_moved_new (source, dest); - miner_fs_queue_event (fs, event, miner_fs_get_queue_priority (fs, source)); -} - -static void -file_notifier_directory_started (TrackerFileNotifier *notifier, - GFile *directory, - gpointer user_data) -{ - TrackerMinerFS *fs = user_data; - TrackerDirectoryFlags flags; - gchar *str, *uri; - - uri = g_file_get_uri (directory); - tracker_indexing_tree_get_root (fs->priv->indexing_tree, - directory, &flags); - - if ((flags & TRACKER_DIRECTORY_FLAG_RECURSE) != 0) { - str = g_strdup_printf ("Crawling recursively directory '%s'", uri); - } else { - str = g_strdup_printf ("Crawling single directory '%s'", uri); - } - - if (fs->priv->timer_stopped) { - g_timer_start (fs->priv->timer); - fs->priv->timer_stopped = FALSE; - } - - if (fs->priv->extraction_timer_stopped) { - g_timer_start (fs->priv->timer); - fs->priv->extraction_timer_stopped = FALSE; - } - - /* Always set the progress here to at least 1%, and the remaining time - * to -1 as we cannot guess during crawling (we don't know how many directories - * we will find) */ - g_object_set (fs, - "progress", 0.01, - "status", str, - "remaining-time", -1, - NULL); - g_free (str); - g_free (uri); -} - -static void -file_notifier_directory_finished (TrackerFileNotifier *notifier, - GFile *directory, - guint directories_found, - guint directories_ignored, - guint files_found, - guint files_ignored, - gpointer user_data) -{ - TrackerMinerFS *fs = user_data; - gchar *str, *uri; - - /* Update stats */ - fs->priv->total_directories_found += directories_found; - fs->priv->total_directories_ignored += directories_ignored; - fs->priv->total_files_found += files_found; - fs->priv->total_files_ignored += files_ignored; - - uri = g_file_get_uri (directory); - str = g_strdup_printf ("Crawl finished for directory '%s'", uri); - - g_object_set (fs, - "progress", 0.01, - "status", str, - "remaining-time", -1, - NULL); - - g_free (str); - g_free (uri); - - if (directories_found == 0 && - files_found == 0) { - /* Signal now because we have nothing to index */ - g_signal_emit (fs, signals[FINISHED_ROOT], 0, directory); - } else { - /* Add root to list we want to be notified about when - * finished indexing! */ - g_hash_table_replace (fs->priv->roots_to_notify, - g_object_ref (directory), - GUINT_TO_POINTER(time(NULL))); - } -} - -static void -file_notifier_finished (TrackerFileNotifier *notifier, - gpointer user_data) -{ - TrackerMinerFS *fs = user_data; - - if (!tracker_miner_fs_has_items_to_process (fs)) { - g_info ("Finished all tasks"); - process_stop (fs); - } else { - item_queue_handlers_set_up (fs); - } -} - -static void -task_pool_cancel_foreach (gpointer data, - gpointer user_data) -{ - TrackerTask *task = data; - GFile *file = user_data; - GFile *task_file; - UpdateProcessingTaskContext *ctxt; - - ctxt = tracker_task_get_data (task); - task_file = tracker_task_get_file (task); - - if (ctxt && - ctxt->cancellable && - (!file || - (g_file_equal (task_file, file) || - g_file_has_prefix (task_file, file)))) { - g_cancellable_cancel (ctxt->cancellable); - } -} - -static void -indexing_tree_directory_removed (TrackerIndexingTree *indexing_tree, - GFile *directory, - gpointer user_data) -{ - TrackerMinerFS *fs = user_data; - TrackerMinerFSPrivate *priv = fs->priv; - GTimer *timer = g_timer_new (); - - /* Cancel all pending tasks on files inside the path given by file */ - tracker_task_pool_foreach (priv->task_pool, - task_pool_cancel_foreach, - directory); - - g_debug (" Cancelled processing pool tasks at %f\n", g_timer_elapsed (timer, NULL)); - - /* Remove anything contained in the removed directory - * from all relevant processing queues. - */ - tracker_priority_queue_foreach_remove (priv->items, - (GEqualFunc) queue_event_is_equal_or_descendant, - directory, - (GDestroyNotify) queue_event_free); - - g_debug (" Removed files at %f\n", g_timer_elapsed (timer, NULL)); - g_timer_destroy (timer); -} - -static gboolean -check_file_parents (TrackerMinerFS *fs, - GFile *file) -{ - GFile *parent, *root; - GList *parents = NULL, *p; - QueueEvent *event; - - parent = g_file_get_parent (file); - - if (!parent) { - return FALSE; - } - - root = tracker_indexing_tree_get_root (fs->priv->indexing_tree, - parent, NULL); - if (!root) { - g_object_unref (parent); - return FALSE; - } - - /* Add parent directories until we're past the config dir */ - while (parent && - !g_file_has_prefix (root, parent)) { - parents = g_list_prepend (parents, parent); - parent = g_file_get_parent (parent); - } - - /* Last parent fetched is not added to the list */ - if (parent) { - g_object_unref (parent); - } - - for (p = parents; p; p = p->next) { - event = queue_event_new (TRACKER_MINER_FS_EVENT_UPDATED, p->data); - miner_fs_queue_event (fs, event, miner_fs_get_queue_priority (fs, p->data)); - g_object_unref (p->data); - } - - g_list_free (parents); - - return TRUE; -} - -/** - * tracker_miner_fs_check_file: - * @fs: a #TrackerMinerFS - * @file: #GFile for the file to check - * @priority: the priority of the check task - * @check_parents: whether to check parents and eligibility or not - * - * Tells the filesystem miner to check and index a file at - * a given priority, this file must be part of the usual - * crawling directories of #TrackerMinerFS. See - * tracker_indexing_tree_add(). - * - * Since: 0.10 - **/ -void -tracker_miner_fs_check_file (TrackerMinerFS *fs, - GFile *file, - gint priority, - gboolean check_parents) -{ - gboolean should_process = TRUE; - QueueEvent *event; - gchar *uri; - - g_return_if_fail (TRACKER_IS_MINER_FS (fs)); - g_return_if_fail (G_IS_FILE (file)); - - if (check_parents) { - should_process = should_check_file (fs, file, FALSE); - } - - uri = g_file_get_uri (file); - - g_debug ("%s:'%s' (FILE) (requested by application)", - should_process ? "Found " : "Ignored", - uri); - - if (should_process) { - if (check_parents && !check_file_parents (fs, file)) { - return; - } - - tracker_file_notifier_get_file_iri (fs->priv->file_notifier, - file, TRUE); - - event = queue_event_new (TRACKER_MINER_FS_EVENT_UPDATED, file); - trace_eq_event (event); - miner_fs_queue_event (fs, event, priority); - } - - g_free (uri); -} - -/** - * tracker_miner_fs_notify_finish: - * @fs: a #TrackerMinerFS - * @task: a #GTask obtained in a #TrackerMinerFS signal/vmethod - * @sparql: (nullable): Resulting sparql for the given operation, or %NULL if - * there is an error - * @error: a #GError with the error that happened during processing, or %NULL. - * - * Notifies @fs that all processing on @file has been finished, if any error - * happened during file data processing, it should be passed in @error, else - * @sparql should contain correct SPARQL representing the operation in - * particular. - * - * This function is expected to be called in reaction to all #TrackerMinerFS - * signals - **/ -void -tracker_miner_fs_notify_finish (TrackerMinerFS *fs, - GTask *task, - const gchar *sparql, - GError *error) -{ - g_return_if_fail (TRACKER_IS_MINER_FS (fs)); - g_return_if_fail (G_IS_TASK (task)); - g_return_if_fail (sparql || error); - - if (error) - g_task_return_error (task, error); - else - g_task_return_pointer (task, g_strdup (sparql), g_free); -} - -/** - * tracker_miner_fs_set_throttle: - * @fs: a #TrackerMinerFS - * @throttle: a double between 0.0 and 1.0 - * - * Tells the filesystem miner to throttle its operations. A value of - * 0.0 means no throttling at all, so the miner will perform - * operations at full speed, 1.0 is the slowest value. With a value of - * 1.0, the @fs is typically waiting one full second before handling - * the next batch of queued items to be processed. - * - * Since: 0.8 - **/ -void -tracker_miner_fs_set_throttle (TrackerMinerFS *fs, - gdouble throttle) -{ - g_return_if_fail (TRACKER_IS_MINER_FS (fs)); - - throttle = CLAMP (throttle, 0, 1); - - if (fs->priv->throttle == throttle) { - return; - } - - fs->priv->throttle = throttle; - - /* Update timeouts */ - if (fs->priv->item_queues_handler_id != 0) { - g_source_remove (fs->priv->item_queues_handler_id); - - fs->priv->item_queues_handler_id = - _tracker_idle_add (fs, - item_queue_handlers_cb, - fs); - } -} - -/** - * tracker_miner_fs_get_throttle: - * @fs: a #TrackerMinerFS - * - * Gets the current throttle value, see - * tracker_miner_fs_set_throttle() for more details. - * - * Returns: a double representing a value between 0.0 and 1.0. - * - * Since: 0.8 - **/ -gdouble -tracker_miner_fs_get_throttle (TrackerMinerFS *fs) -{ - g_return_val_if_fail (TRACKER_IS_MINER_FS (fs), 0); - - return fs->priv->throttle; -} - -/** - * tracker_miner_fs_get_urn: - * @fs: a #TrackerMinerFS - * @file: a #GFile obtained in #TrackerMinerFS::process-file - * - * If the item exists in the store, this function retrieves - * the URN for a #GFile being currently processed. - - * If @file is not being currently processed by @fs, or doesn't - * exist in the store yet, %NULL will be returned. - * - * Returns: (transfer none) (nullable): The URN containing the data associated to @file, - * or %NULL. - * - * Since: 0.8 - **/ -const gchar * -tracker_miner_fs_get_urn (TrackerMinerFS *fs, - GFile *file) -{ - TrackerTask *task; - - g_return_val_if_fail (TRACKER_IS_MINER_FS (fs), NULL); - g_return_val_if_fail (G_IS_FILE (file), NULL); - - /* Check if found in currently processed data */ - task = tracker_task_pool_find (fs->priv->task_pool, file); - - if (!task) { - gchar *uri; - - uri = g_file_get_uri (file); - - g_critical ("File '%s' is not being currently processed, " - "so the URN cannot be retrieved.", uri); - g_free (uri); - - return NULL; - } else { - UpdateProcessingTaskContext *ctxt; - - /* We are only storing the URN in the created/updated tasks */ - ctxt = tracker_task_get_data (task); - - if (!ctxt) { - gchar *uri; - - uri = g_file_get_uri (file); - g_critical ("File '%s' is being processed, but not as a " - "CREATED/UPDATED task, so cannot get URN", - uri); - g_free (uri); - return NULL; - } - - return ctxt->urn; - } -} - -/** - * tracker_miner_fs_query_urn: - * @fs: a #TrackerMinerFS - * @file: a #GFile - * - * If the item exists in the store, this function retrieves - * the URN of the given #GFile - - * If @file doesn't exist in the store yet, %NULL will be returned. - * - * Returns: (transfer full): A newly allocated string with the URN containing the data associated - * to @file, or %NULL. - * - * Since: 0.10 - **/ -gchar * -tracker_miner_fs_query_urn (TrackerMinerFS *fs, - GFile *file) -{ - g_return_val_if_fail (TRACKER_IS_MINER_FS (fs), NULL); - g_return_val_if_fail (G_IS_FILE (file), NULL); - - return g_strdup (tracker_file_notifier_get_file_iri (fs->priv->file_notifier, file, TRUE)); -} - -/** - * tracker_miner_fs_has_items_to_process: - * @fs: a #TrackerMinerFS - * - * The @fs keeps many priority queus for content it is processing. - * This function returns %TRUE if the sum of all (or any) priority - * queues is more than 0. This includes items deleted, created, - * updated, moved or being written back. - * - * Returns: %TRUE if there are items to process in the internal - * queues, otherwise %FALSE. - * - * Since: 0.10 - **/ -gboolean -tracker_miner_fs_has_items_to_process (TrackerMinerFS *fs) -{ - g_return_val_if_fail (TRACKER_IS_MINER_FS (fs), FALSE); - - if (tracker_file_notifier_is_active (fs->priv->file_notifier) || - !tracker_priority_queue_is_empty (fs->priv->items)) { - return TRUE; - } - - return FALSE; -} - -/** - * tracker_miner_fs_get_indexing_tree: - * @fs: a #TrackerMinerFS - * - * Returns the #TrackerIndexingTree which determines - * what files/directories are indexed by @fs - * - * Returns: (transfer none): The #TrackerIndexingTree - * holding the indexing configuration - **/ -TrackerIndexingTree * -tracker_miner_fs_get_indexing_tree (TrackerMinerFS *fs) -{ - g_return_val_if_fail (TRACKER_IS_MINER_FS (fs), NULL); - - return fs->priv->indexing_tree; -} - -/** - * tracker_miner_fs_get_data_provider: - * @fs: a #TrackerMinerFS - * - * Returns the #TrackerDataProvider implementation, which is being used - * to supply #GFile and #GFileInfo content to Tracker. - * - * Returns: (transfer none): The #TrackerDataProvider supplying content - * - * Since: 1.2 - **/ -TrackerDataProvider * -tracker_miner_fs_get_data_provider (TrackerMinerFS *fs) -{ - g_return_val_if_fail (TRACKER_IS_MINER_FS (fs), NULL); - - return fs->priv->data_provider; -} diff --git a/src/libtracker-miner/tracker-miner-fs.h b/src/libtracker-miner/tracker-miner-fs.h deleted file mode 100644 index d4398af3c..000000000 --- a/src/libtracker-miner/tracker-miner-fs.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (C) 2009, Nokia <ivan.frade@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __LIBTRACKER_MINER_MINER_FS_H__ -#define __LIBTRACKER_MINER_MINER_FS_H__ - -#if !defined (__LIBTRACKER_MINER_H_INSIDE__) && !defined (TRACKER_COMPILATION) -#error "Only <libtracker-miner/tracker-miner.h> can be included directly." -#endif - -#include <glib-object.h> -#include <gio/gio.h> - -#include <libtracker-sparql/tracker-sparql.h> - -#include "tracker-miner-object.h" -#include "tracker-data-provider.h" -#include "tracker-indexing-tree.h" - -G_BEGIN_DECLS - -#define TRACKER_TYPE_MINER_FS (tracker_miner_fs_get_type()) -#define TRACKER_MINER_FS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_MINER_FS, TrackerMinerFS)) -#define TRACKER_MINER_FS_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), TRACKER_TYPE_MINER_FS, TrackerMinerFSClass)) -#define TRACKER_IS_MINER_FS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_MINER_FS)) -#define TRACKER_IS_MINER_FS_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), TRACKER_TYPE_MINER_FS)) -#define TRACKER_MINER_FS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_MINER_FS, TrackerMinerFSClass)) - -typedef enum { - TRACKER_MINER_FS_EVENT_CREATED, - TRACKER_MINER_FS_EVENT_UPDATED, - TRACKER_MINER_FS_EVENT_DELETED, - TRACKER_MINER_FS_EVENT_MOVED, -} TrackerMinerFSEventType; - -typedef struct _TrackerMinerFS TrackerMinerFS; -typedef struct _TrackerMinerFSPrivate TrackerMinerFSPrivate; - -/** - * TrackerMinerFS: - * - * Abstract miner implementation to get data from the filesystem. - **/ -struct _TrackerMinerFS { - TrackerMiner parent; - TrackerMinerFSPrivate *priv; -}; - -/** - * TrackerMinerFSClass: - * @parent: parent object class - * @process_file: Called when the metadata associated to a file is - * requested. - * @finished: Called when all processing has been performed. - * @process_file_attributes: Called when the metadata associated with - * a file's attributes changes, for example, the mtime. - * @finished_root: Called when all resources on a particular root URI - * have been processed. - * @remove_file: Called when a file is removed. - * @remove_children: Called when children have been removed. - * @move_file: Called when a file has moved. - * @filter_event: Called to filter the event happening to a file. - * @padding: Reserved for future API improvements. - * - * Prototype for the abstract class, @process_file must be implemented - * in the deriving class in order to actually extract data. - **/ -typedef struct { - TrackerMinerClass parent; - - gboolean (* process_file) (TrackerMinerFS *fs, - GFile *file, - GTask *task); - void (* finished) (TrackerMinerFS *fs, - gdouble elapsed, - gint directories_found, - gint directories_ignored, - gint files_found, - gint files_ignored); - gboolean (* process_file_attributes) (TrackerMinerFS *fs, - GFile *file, - GTask *task); - void (* finished_root) (TrackerMinerFS *fs, - GFile *root, - gint directories_found, - gint directories_ignored, - gint files_found, - gint files_ignored); - gchar * (* remove_file) (TrackerMinerFS *fs, - GFile *file); - gchar * (* remove_children) (TrackerMinerFS *fs, - GFile *file); - gchar * (* move_file) (TrackerMinerFS *fs, - GFile *dest, - GFile *source, - gboolean recursive); - - gboolean (* filter_event) (TrackerMinerFS *fs, - TrackerMinerFSEventType type, - GFile *file, - GFile *source_file); - - /* <Private> */ - gpointer padding[20]; -} TrackerMinerFSClass; - -/** - * TrackerMinerFSError: - * @TRACKER_MINER_FS_ERROR_INIT: There was an error during - * initialization of the object. The specific details are in the - * message. - * - * Possible errors returned when calling creating new objects based on - * the #TrackerMinerFS type and other APIs available with this class. - * - * Since: 1.2 - **/ -typedef enum { - TRACKER_MINER_FS_ERROR_INIT, -} TrackerMinerFSError; - -GType tracker_miner_fs_get_type (void) G_GNUC_CONST; -GQuark tracker_miner_fs_error_quark (void); - -/* Properties */ -TrackerIndexingTree * tracker_miner_fs_get_indexing_tree (TrackerMinerFS *fs); -TrackerDataProvider * tracker_miner_fs_get_data_provider (TrackerMinerFS *fs); -gdouble tracker_miner_fs_get_throttle (TrackerMinerFS *fs); -void tracker_miner_fs_set_throttle (TrackerMinerFS *fs, - gdouble throttle); - -/* Queueing files to be processed AFTER checking rules in IndexingTree */ -void tracker_miner_fs_check_file (TrackerMinerFS *fs, - GFile *file, - gint priority, - gboolean check_parents); - -/* Continuation for async vmethods */ -void tracker_miner_fs_notify_finish (TrackerMinerFS *fs, - GTask *task, - const gchar *sparql, - GError *error); - -/* URNs */ -const gchar *tracker_miner_fs_get_urn (TrackerMinerFS *fs, - GFile *file); -gchar *tracker_miner_fs_query_urn (TrackerMinerFS *fs, - GFile *file); - - -/* Progress */ -gboolean tracker_miner_fs_has_items_to_process (TrackerMinerFS *fs); - -G_END_DECLS - -#endif /* __LIBTRACKER_MINER_MINER_FS_H__ */ diff --git a/src/libtracker-miner/tracker-miner-object.c b/src/libtracker-miner/tracker-miner-object.c deleted file mode 100644 index dfaf2dc20..000000000 --- a/src/libtracker-miner/tracker-miner-object.c +++ /dev/null @@ -1,639 +0,0 @@ -/* - * Copyright (C) 2009, Nokia <ivan.frade@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "config.h" - -#include <math.h> - -#include <glib/gi18n.h> - -#include <libtracker-common/tracker-dbus.h> -#include <libtracker-common/tracker-type-utils.h> - -#include "tracker-miner-object.h" - -/* Here we use ceil() to eliminate decimal points beyond what we're - * interested in, which is 2 decimal places for the progress. The - * ceil() call will also round up the last decimal place. - * - * The 0.49 value is used for rounding correctness, because ceil() - * rounds up if the number is > 0.0. - */ -#define PROGRESS_ROUNDED(x) ((x) < 0.01 ? 0.00 : (ceil (((x) * 100) - 0.49) / 100)) - -#ifdef MINER_STATUS_ENABLE_TRACE -#warning Miner status traces are enabled -#define trace(message, ...) g_debug (message, ##__VA_ARGS__) -#else -#define trace(...) -#endif /* MINER_STATUS_ENABLE_TRACE */ - -/** - * SECTION:tracker-miner-object - * @short_description: Abstract base class for data miners - * @include: libtracker-miner/tracker-miner.h - * - * #TrackerMiner is an abstract base class to help developing data miners - * for tracker-store, being an abstract class it doesn't do much by itself, - * but provides the basic signaling and control over the actual indexing - * task. - * - * #TrackerMiner implements the #GInitable interface, and thus, all objects of - * types inheriting from #TrackerMiner must be initialized with g_initable_init() - * just after creation (or directly created with g_initable_new()). - **/ - -struct _TrackerMinerPrivate { - TrackerSparqlConnection *connection; - gboolean started; - gint n_pauses; - gchar *status; - gdouble progress; - gint remaining_time; - gint availability_cookie; - guint update_id; -}; - -enum { - PROP_0, - PROP_STATUS, - PROP_PROGRESS, - PROP_REMAINING_TIME, - PROP_CONNECTION -}; - -enum { - STARTED, - STOPPED, - PAUSED, - RESUMED, - PROGRESS, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -static void miner_set_property (GObject *object, - guint param_id, - const GValue *value, - GParamSpec *pspec); -static void miner_get_property (GObject *object, - guint param_id, - GValue *value, - GParamSpec *pspec); -static void miner_finalize (GObject *object); -static void miner_initable_iface_init (GInitableIface *iface); -static gboolean miner_initable_init (GInitable *initable, - GCancellable *cancellable, - GError **error); - -/** - * tracker_miner_error_quark: - * - * Gives the caller the #GQuark used to identify #TrackerMiner errors - * in #GError structures. The #GQuark is used as the domain for the error. - * - * Returns: the #GQuark used for the domain of a #GError. - * - * Since: 0.8 - **/ -G_DEFINE_QUARK (TrackerMinerError, tracker_miner_error) - -G_DEFINE_ABSTRACT_TYPE_WITH_CODE (TrackerMiner, tracker_miner, G_TYPE_OBJECT, - G_ADD_PRIVATE (TrackerMiner) - G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, - miner_initable_iface_init)); - -static void -tracker_miner_class_init (TrackerMinerClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->set_property = miner_set_property; - object_class->get_property = miner_get_property; - object_class->finalize = miner_finalize; - - /** - * TrackerMiner::started: - * @miner: the #TrackerMiner - * - * the ::started signal is emitted in the miner - * right after it has been started through - * tracker_miner_start(). - * - * Since: 0.8 - **/ - signals[STARTED] = - g_signal_new ("started", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (TrackerMinerClass, started), - NULL, NULL, - NULL, - G_TYPE_NONE, 0); - /** - * TrackerMiner::stopped: - * @miner: the #TrackerMiner - * - * the ::stopped signal is emitted in the miner - * right after it has been stopped through - * tracker_miner_stop(). - * - * Since: 0.8 - **/ - signals[STOPPED] = - g_signal_new ("stopped", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (TrackerMinerClass, stopped), - NULL, NULL, - NULL, - G_TYPE_NONE, 0); - /** - * TrackerMiner::paused: - * @miner: the #TrackerMiner - * - * the ::paused signal is emitted whenever - * there is any reason to pause, either - * internal (through tracker_miner_pause()) or - * external (through DBus, see #TrackerMinerManager). - * - * Since: 0.8 - **/ - signals[PAUSED] = - g_signal_new ("paused", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (TrackerMinerClass, paused), - NULL, NULL, - NULL, - G_TYPE_NONE, 0); - /** - * TrackerMiner::resumed: - * @miner: the #TrackerMiner - * - * the ::resumed signal is emitted whenever - * all reasons to pause have disappeared, see - * tracker_miner_resume() and #TrackerMinerManager. - * - * Since: 0.8 - **/ - signals[RESUMED] = - g_signal_new ("resumed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (TrackerMinerClass, resumed), - NULL, NULL, - NULL, - G_TYPE_NONE, 0); - /** - * TrackerMiner::progress: - * @miner: the #TrackerMiner - * @status: miner status - * @progress: a #gdouble indicating miner progress, from 0 to 1. - * @remaining_time: a #gint indicating the reamaining processing time, in - * seconds. - * - * the ::progress signal will be emitted by TrackerMiner implementations - * to indicate progress about the data mining process. @status will - * contain a translated string with the current miner status and @progress - * will indicate how much has been processed so far. @remaining_time will - * give the number expected of seconds to finish processing, 0 if the - * value cannot be estimated, and -1 if its not applicable. - * - * Since: 0.12 - **/ - signals[PROGRESS] = - g_signal_new ("progress", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (TrackerMinerClass, progress), - NULL, NULL, - NULL, - G_TYPE_NONE, 3, - G_TYPE_STRING, - G_TYPE_DOUBLE, - G_TYPE_INT); - - g_object_class_install_property (object_class, - PROP_STATUS, - g_param_spec_string ("status", - "Status", - "Translatable string with status description", - "Idle", - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - g_object_class_install_property (object_class, - PROP_PROGRESS, - g_param_spec_double ("progress", - "Progress", - "Miner progress", - 0.0, - 1.0, - 0.0, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - - g_object_class_install_property (object_class, - PROP_REMAINING_TIME, - g_param_spec_int ("remaining-time", - "Remaining time", - "Estimated remaining time to finish processing", - -1, - G_MAXINT, - -1, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - /** - * TrackerMiner:connection: - * - * The SPARQL connection to use. For compatibility reasons, if not set - * at construct time, one shall be obtained through - * tracker_sparql_connection_get(). - * - * Since: 2.0 - **/ - g_object_class_install_property (object_class, - PROP_CONNECTION, - g_param_spec_object ("connection", - "Connection", - "SPARQL Connection", - TRACKER_SPARQL_TYPE_CONNECTION, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); -} - -static void -miner_initable_iface_init (GInitableIface *iface) -{ - iface->init = miner_initable_init; -} - -static gboolean -miner_initable_init (GInitable *initable, - GCancellable *cancellable, - GError **error) -{ - TrackerMiner *miner = TRACKER_MINER (initable); - GError *inner_error = NULL; - - if (!miner->priv->connection) { - /* Try to get SPARQL connection... */ - miner->priv->connection = tracker_sparql_connection_get (NULL, &inner_error); - } - - if (!miner->priv->connection) { - g_propagate_error (error, inner_error); - return FALSE; - } - - return TRUE; -} - -static void -tracker_miner_init (TrackerMiner *miner) -{ - miner->priv = tracker_miner_get_instance_private (miner); -} - -static gboolean -miner_update_progress_cb (gpointer data) -{ - TrackerMiner *miner = data; - - trace ("(Miner:'%s') UPDATE PROGRESS SIGNAL", G_OBJECT_TYPE_NAME (miner)); - - g_signal_emit (miner, signals[PROGRESS], 0, - miner->priv->status, - miner->priv->progress, - miner->priv->remaining_time); - - miner->priv->update_id = 0; - - return FALSE; -} - -static void -miner_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - TrackerMiner *miner = TRACKER_MINER (object); - - /* Quite often, we see status of 100% and still have - * status messages saying Processing... which is not - * true. So we use an idle timeout to help that situation. - * Additionally we can't force both properties are correct - * with the GObject API, so we have to do some checks our - * selves. The g_object_bind_property() API also isn't - * sufficient here. - */ - - switch (prop_id) { - case PROP_STATUS: { - const gchar *new_status; - - new_status = g_value_get_string (value); - - trace ("(Miner:'%s') Set property:'status' to '%s'", - G_OBJECT_TYPE_NAME (miner), - new_status); - - if (miner->priv->status && new_status && - strcmp (miner->priv->status, new_status) == 0) { - /* Same, do nothing */ - break; - } - - g_free (miner->priv->status); - miner->priv->status = g_strdup (new_status); - - /* Check progress matches special statuses */ - if (new_status != NULL) { - if (g_ascii_strcasecmp (new_status, "Initializing") == 0 && - miner->priv->progress != 0.0) { - trace ("(Miner:'%s') Set progress to 0.0 from status:'Initializing'", - G_OBJECT_TYPE_NAME (miner)); - miner->priv->progress = 0.0; - } else if (g_ascii_strcasecmp (new_status, "Idle") == 0 && - miner->priv->progress != 1.0) { - trace ("(Miner:'%s') Set progress to 1.0 from status:'Idle'", - G_OBJECT_TYPE_NAME (miner)); - miner->priv->progress = 1.0; - } - } - - if (miner->priv->update_id == 0) { - miner->priv->update_id = g_idle_add_full (G_PRIORITY_HIGH_IDLE, - miner_update_progress_cb, - miner, - NULL); - } - - break; - } - case PROP_PROGRESS: { - gdouble new_progress; - - new_progress = PROGRESS_ROUNDED (g_value_get_double (value)); - trace ("(Miner:'%s') Set property:'progress' to '%2.2f' (%2.2f before rounded)", - G_OBJECT_TYPE_NAME (miner), - new_progress, - g_value_get_double (value)); - - /* NOTE: We don't round the current progress before - * comparison because we use the rounded value when - * we set it last. - * - * Only notify 1% changes - */ - if (new_progress == miner->priv->progress) { - /* Same, do nothing */ - break; - } - - miner->priv->progress = new_progress; - - /* Check status matches special progress values */ - if (new_progress == 0.0) { - if (miner->priv->status == NULL || - g_ascii_strcasecmp (miner->priv->status, "Initializing") != 0) { - trace ("(Miner:'%s') Set status:'Initializing' from progress:0.0", - G_OBJECT_TYPE_NAME (miner)); - g_free (miner->priv->status); - miner->priv->status = g_strdup ("Initializing"); - } - } else if (new_progress == 1.0) { - if (miner->priv->status == NULL || - g_ascii_strcasecmp (miner->priv->status, "Idle") != 0) { - trace ("(Miner:'%s') Set status:'Idle' from progress:1.0", - G_OBJECT_TYPE_NAME (miner)); - g_free (miner->priv->status); - miner->priv->status = g_strdup ("Idle"); - } - } - - if (miner->priv->update_id == 0) { - miner->priv->update_id = g_idle_add_full (G_PRIORITY_HIGH_IDLE, - miner_update_progress_cb, - miner, - NULL); - } - - break; - } - case PROP_REMAINING_TIME: { - gint new_remaining_time; - - new_remaining_time = g_value_get_int (value); - if (new_remaining_time != miner->priv->remaining_time) { - /* Just set the new remaining time, don't notify it */ - miner->priv->remaining_time = new_remaining_time; - } - break; - } - case PROP_CONNECTION: { - miner->priv->connection = g_value_dup_object (value); - break; - } - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -miner_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - TrackerMiner *miner = TRACKER_MINER (object); - - switch (prop_id) { - case PROP_STATUS: - g_value_set_string (value, miner->priv->status); - break; - case PROP_PROGRESS: - g_value_set_double (value, miner->priv->progress); - break; - case PROP_REMAINING_TIME: - g_value_set_int (value, miner->priv->remaining_time); - break; - case PROP_CONNECTION: - g_value_set_object (value, miner->priv->connection); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -/** - * tracker_miner_start: - * @miner: a #TrackerMiner - * - * Tells the miner to start processing data. - * - * Since: 0.8 - **/ -void -tracker_miner_start (TrackerMiner *miner) -{ - g_return_if_fail (TRACKER_IS_MINER (miner)); - - if (miner->priv->started == FALSE) { - miner->priv->started = TRUE; - g_signal_emit (miner, signals[STARTED], 0); - } -} - -/** - * tracker_miner_stop: - * @miner: a #TrackerMiner - * - * Tells the miner to stop processing data. - * - * Since: 0.8 - **/ -void -tracker_miner_stop (TrackerMiner *miner) -{ - g_return_if_fail (TRACKER_IS_MINER (miner)); - - if (miner->priv->started == TRUE) { - miner->priv->started = FALSE; - g_signal_emit (miner, signals[STOPPED], 0); - } -} - -/** - * tracker_miner_is_started: - * @miner: a #TrackerMiner - * - * Returns #TRUE if the miner has been started. - * - * Returns: #TRUE if the miner is already started. - * - * Since: 0.8 - **/ -gboolean -tracker_miner_is_started (TrackerMiner *miner) -{ - g_return_val_if_fail (TRACKER_IS_MINER (miner), TRUE); - - return miner->priv->started; -} - -/** - * tracker_miner_is_paused: - * @miner: a #TrackerMiner - * - * Returns #TRUE if the miner is paused. - * - * Returns: #TRUE if the miner is paused. - * - * Since: 0.10 - **/ -gboolean -tracker_miner_is_paused (TrackerMiner *miner) -{ - g_return_val_if_fail (TRACKER_IS_MINER (miner), TRUE); - - return miner->priv->n_pauses > 0; -} - -/** - * tracker_miner_pause: - * @miner: a #TrackerMiner - * - * Asks @miner to pause. This call may be called multiple times, - * but #TrackerMiner::paused will only be emitted the first time. - * The same number of tracker_miner_resume() calls are expected - * in order to resume operations. - **/ -void -tracker_miner_pause (TrackerMiner *miner) -{ - gint previous; - - g_return_if_fail (TRACKER_IS_MINER (miner)); - - previous = g_atomic_int_add (&miner->priv->n_pauses, 1); - - if (previous == 0) - g_signal_emit (miner, signals[PAUSED], 0); -} - -/** - * tracker_miner_resume: - * @miner: a #TrackerMiner - * - * Asks the miner to resume processing. This needs to be called - * as many times as tracker_miner_pause() calls were done - * previously. This function will return #TRUE when the miner - * is actually resumed. - * - * Returns: #TRUE if the miner resumed its operations. - **/ -gboolean -tracker_miner_resume (TrackerMiner *miner) -{ - g_return_val_if_fail (TRACKER_IS_MINER (miner), FALSE); - g_return_val_if_fail (miner->priv->n_pauses > 0, FALSE); - - if (g_atomic_int_dec_and_test (&miner->priv->n_pauses)) { - g_signal_emit (miner, signals[RESUMED], 0); - return TRUE; - } - - return FALSE; -} - -/** - * tracker_miner_get_connection: - * @miner: a #TrackerMiner - * - * Gets the #TrackerSparqlConnection initialized by @miner - * - * Returns: (transfer none): a #TrackerSparqlConnection. - * - * Since: 0.10 - **/ -TrackerSparqlConnection * -tracker_miner_get_connection (TrackerMiner *miner) -{ - return miner->priv->connection; -} - -static void -miner_finalize (GObject *object) -{ - TrackerMiner *miner = TRACKER_MINER (object); - - if (miner->priv->update_id != 0) { - g_source_remove (miner->priv->update_id); - } - - g_free (miner->priv->status); - - if (miner->priv->connection) { - g_object_unref (miner->priv->connection); - } - - G_OBJECT_CLASS (tracker_miner_parent_class)->finalize (object); -} diff --git a/src/libtracker-miner/tracker-miner-object.h b/src/libtracker-miner/tracker-miner-object.h deleted file mode 100644 index 62513061b..000000000 --- a/src/libtracker-miner/tracker-miner-object.h +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (C) 2009, Nokia <ivan.frade@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __LIBTRACKER_MINER_OBJECT_H__ -#define __LIBTRACKER_MINER_OBJECT_H__ - -#if !defined (__LIBTRACKER_MINER_H_INSIDE__) && !defined (TRACKER_COMPILATION) -#error "Only <libtracker-miner/tracker-miner.h> can be included directly." -#endif - -#include <glib-object.h> -#include <gio/gio.h> - -#include <libtracker-sparql/tracker-sparql.h> - -G_BEGIN_DECLS - -/* Common definitions for all miners */ -/** - * TRACKER_MINER_DBUS_INTERFACE: - * - * The name of the D-Bus interface to use for all data miners that - * inter-operate with Tracker. - * - * Since: 0.8 - **/ -#define TRACKER_MINER_DBUS_INTERFACE "org.freedesktop.Tracker1.Miner" - -/** - * TRACKER_MINER_DBUS_NAME_PREFIX: - * - * D-Bus name prefix to use for all data miners. This allows custom - * miners to be written using @TRACKER_MINER_DBUS_NAME_PREFIX + "Files" for - * example and would show up on D-Bus under - * "org.freedesktop.Tracker1.Miner.Files". - * - * Since: 0.8 - **/ -#define TRACKER_MINER_DBUS_NAME_PREFIX "org.freedesktop.Tracker1.Miner." - -/** - * TRACKER_MINER_DBUS_PATH_PREFIX: - * - * D-Bus path prefix to use for all data miners. This allows custom - * miners to be written using @TRACKER_MINER_DBUS_PATH_PREFIX + "Files" for - * example and would show up on D-Bus under - * "/org/freedesktop/Tracker1/Miner/Files". - * - * Since: 0.8 - **/ -#define TRACKER_MINER_DBUS_PATH_PREFIX "/org/freedesktop/Tracker1/Miner/" - -#define TRACKER_TYPE_MINER (tracker_miner_get_type()) -#define TRACKER_MINER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_MINER, TrackerMiner)) -#define TRACKER_MINER_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), TRACKER_TYPE_MINER, TrackerMinerClass)) -#define TRACKER_IS_MINER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_MINER)) -#define TRACKER_IS_MINER_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), TRACKER_TYPE_MINER)) -#define TRACKER_MINER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_MINER, TrackerMinerClass)) - -/** - * TRACKER_MINER_ERROR_DOMAIN: - * - * Used as the domain for any #GErrors reported by @TrackerMiner objects. - * - * Since: 0.8 - **/ -#define TRACKER_MINER_ERROR_DOMAIN "TrackerMiner" - -/** - * TRACKER_MINER_ERROR: - * - * Returns the @GQuark used for #GErrors and for @TrackerMiner - * implementations. This calls tracker_miner_error_quark(). - * - * Since: 0.8 - **/ -#define TRACKER_MINER_ERROR tracker_miner_error_quark() - -typedef struct _TrackerMiner TrackerMiner; -typedef struct _TrackerMinerPrivate TrackerMinerPrivate; - -/** - * TrackerMiner: - * - * Abstract miner object. - **/ -struct _TrackerMiner { - GObject parent_instance; - TrackerMinerPrivate *priv; -}; - -/** - * TrackerMinerClass: - * @parent_class: parent object class. - * @started: Called when the miner is told to start collecting data. - * @stopped: Called when the miner is told to stop collecting data. - * @paused: Called when the miner is told to pause. - * @resumed: Called when the miner is told to resume activity. - * @progress: progress. - * @padding: Reserved for future API improvements. - * - * Virtual methods left to implement. - **/ -typedef struct { - GObjectClass parent_class; - - /* signals */ - void (* started) (TrackerMiner *miner); - void (* stopped) (TrackerMiner *miner); - - void (* paused) (TrackerMiner *miner); - void (* resumed) (TrackerMiner *miner); - - void (* progress) (TrackerMiner *miner, - const gchar *status, - gdouble progress, - gint remaining_time); - - /* <Private> */ - gpointer padding[10]; -} TrackerMinerClass; - -/** - * TrackerMinerError: - * @TRACKER_MINER_ERROR_NAME_MISSING: No name was given when creating - * the miner. The name is crucial for D-Bus presence and a host of - * other things. - * @TRACKER_MINER_ERROR_NAME_UNAVAILABLE: The name trying to be used - * for the miner was not available, possibly because the miner is - * already running with the same name in another process. - * @TRACKER_MINER_ERROR_PAUSED: Given by miners when an API is used at - * the time the miner itself is paused and such actions should be avoided. - * @TRACKER_MINER_ERROR_PAUSED_ALREADY: The pause request has already - * been given by the same application with the same reason. Duplicate - * pause calls with the same reason by the same application can not - * be carried out. - * @TRACKER_MINER_ERROR_INVALID_COOKIE: When pausing a miner, a cookie - * (or @gint based ID) is given. That cookie must be used to resume a - * previous pause request. If the cookie is unrecognised, this error - * is given. - * - * Possible errors returned when calling #TrackerMiner APIs or - * subclassed miners where the error is generic to all miners. - **/ -typedef enum { - TRACKER_MINER_ERROR_NAME_MISSING, - TRACKER_MINER_ERROR_NAME_UNAVAILABLE, - TRACKER_MINER_ERROR_PAUSED, - TRACKER_MINER_ERROR_PAUSED_ALREADY, - TRACKER_MINER_ERROR_INVALID_COOKIE -} TrackerMinerError; - - -GType tracker_miner_get_type (void) G_GNUC_CONST; -GQuark tracker_miner_error_quark (void); - -void tracker_miner_start (TrackerMiner *miner); -void tracker_miner_stop (TrackerMiner *miner); -gboolean tracker_miner_is_started (TrackerMiner *miner); -gboolean tracker_miner_is_paused (TrackerMiner *miner); - -void tracker_miner_pause (TrackerMiner *miner); -gboolean tracker_miner_resume (TrackerMiner *miner); - -TrackerSparqlConnection *tracker_miner_get_connection (TrackerMiner *miner); - -G_END_DECLS - -#endif /* __LIBTRACKER_MINER_OBJECT_H__ */ diff --git a/src/libtracker-miner/tracker-miner-online.c b/src/libtracker-miner/tracker-miner-online.c deleted file mode 100644 index cf4733601..000000000 --- a/src/libtracker-miner/tracker-miner-online.c +++ /dev/null @@ -1,407 +0,0 @@ -/* - * Copyright (C) 2009-2014, Adrien Bustany <abustany@gnome.org> - * Copyright (C) 2014, Carlos Garnacho <carlosg@gnome.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "config.h" - -#include "tracker-miner-online.h" -#include "tracker-miner-enum-types.h" - -#include <glib/gi18n.h> - -#ifdef HAVE_NETWORK_MANAGER -#include <NetworkManager.h> -#endif /* HAVE_NETWORK_MANAGER */ - -/** - * SECTION:tracker-miner-online - * @short_description: Abstract base class for miners connecting to - * online resources - * @include: libtracker-miner/tracker-miner.h - * - * #TrackerMinerOnline is an abstract base class for miners retrieving data - * from online resources. It's a very thin layer above #TrackerMiner that - * additionally handles network connection status. - * - * #TrackerMinerOnline implementations can implement the - * <literal>connected</literal> vmethod in order to tell the miner whether - * a connection is valid to retrieve data or not. The miner data extraction - * still must be dictated through the #TrackerMiner vmethods. - * - * Since: 0.18 - **/ - -typedef struct _TrackerMinerOnlinePrivate TrackerMinerOnlinePrivate; - -struct _TrackerMinerOnlinePrivate { -#ifdef HAVE_NETWORK_MANAGER - NMClient *client; -#endif - TrackerNetworkType network_type; - gboolean paused; -}; - -enum { - PROP_NETWORK_TYPE = 1 -}; - -enum { - CONNECTED, - DISCONNECTED, - N_SIGNALS -}; - -static void miner_online_initable_iface_init (GInitableIface *iface); - -static GInitableIface* miner_online_initable_parent_iface; -static guint signals[N_SIGNALS] = { 0 }; - -G_DEFINE_ABSTRACT_TYPE_WITH_CODE (TrackerMinerOnline, tracker_miner_online, TRACKER_TYPE_MINER, - G_ADD_PRIVATE (TrackerMinerOnline) - G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, - miner_online_initable_iface_init)); - -static void -miner_online_finalize (GObject *object) -{ -#ifdef HAVE_NETWORK_MANAGER - TrackerMinerOnlinePrivate *priv; - TrackerMinerOnline *miner; - - miner = TRACKER_MINER_ONLINE (object); - priv = tracker_miner_online_get_instance_private (miner); - - if (priv->client) - g_object_unref (priv->client); -#endif /* HAVE_NETWORK_MANAGER */ - - G_OBJECT_CLASS (tracker_miner_online_parent_class)->finalize (object); -} - -static void -miner_online_set_property (GObject *object, - guint param_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (param_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); - break; - } -} - -static void -miner_online_get_property (GObject *object, - guint param_id, - GValue *value, - GParamSpec *pspec) -{ - TrackerMinerOnlinePrivate *priv; - TrackerMinerOnline *miner; - - miner = TRACKER_MINER_ONLINE (object); - priv = tracker_miner_online_get_instance_private (miner); - - switch (param_id) { - case PROP_NETWORK_TYPE: - g_value_set_enum (value, priv->network_type); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); - break; - } -} - -static void -tracker_miner_online_class_init (TrackerMinerOnlineClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = miner_online_finalize; - object_class->set_property = miner_online_set_property; - object_class->get_property = miner_online_get_property; - - g_object_class_install_property (object_class, - PROP_NETWORK_TYPE, - g_param_spec_enum ("network-type", - "Network type", - "Network type for the current connection", - TRACKER_TYPE_NETWORK_TYPE, - TRACKER_NETWORK_TYPE_NONE, - G_PARAM_READABLE)); - - /** - * TrackerMinerOnline::connected: - * @miner: a #TrackerMinerOnline - * @type: a #TrackerNetworkType - * - * the ::connected signal is emitted when a specific @type of - * network becomes connected. - * - * Return values of #TRUE from this signal indicate whether a - * #TrackerMiner should resume indexing or not upon ::connected. - * - * Since: 0.18 - **/ - signals[CONNECTED] = - g_signal_new ("connected", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (TrackerMinerOnlineClass, connected), - NULL, NULL, NULL, - G_TYPE_BOOLEAN, 1, TRACKER_TYPE_NETWORK_TYPE); - - /** - * TrackerMinerOnline::disconnected: - * @miner: a #TrackerMinerOnline - * @type: a #TrackerNetworkType - * - * the ::disconnected signal is emitted when a specific @type of - * network becomes disconnected. - * - * Since: 0.18 - **/ - signals[DISCONNECTED] = - g_signal_new ("disconnected", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (TrackerMinerOnlineClass, connected), - NULL, NULL, NULL, - G_TYPE_NONE, 0); -} - -static void -tracker_miner_online_init (TrackerMinerOnline *miner) -{ - TrackerMinerOnlinePrivate *priv; - - priv = tracker_miner_online_get_instance_private (miner); - priv->network_type = TRACKER_NETWORK_TYPE_NONE; -} - -#ifdef HAVE_NETWORK_MANAGER -/* - * Returns the first NMActiveConnection with the "default" property set, or - * NULL if none is found. - */ -static NMActiveConnection* -find_default_active_connection (NMClient *client) -{ - NMActiveConnection *active_connection = NULL; - const GPtrArray *active_connections; - gint i; - - active_connections = nm_client_get_active_connections (client); - - for (i = 0; i < active_connections->len; i++) { - active_connection = g_ptr_array_index (active_connections, i); - - if (nm_active_connection_get_default (active_connection)) { - break; - } - } - - return active_connection; -} - -static TrackerNetworkType -_nm_client_get_network_type (NMClient *nm_client) -{ - NMActiveConnection *default_active_connection; - const GPtrArray *devices; - NMDevice *device; - NMState state; - - if (!nm_client_get_nm_running (nm_client)) { - return TRACKER_NETWORK_TYPE_UNKNOWN; - } - - state = nm_client_get_state (nm_client); - if (state == NM_STATE_UNKNOWN) - return TRACKER_NETWORK_TYPE_UNKNOWN; - if (state <= NM_STATE_DISCONNECTING) - return TRACKER_NETWORK_TYPE_UNKNOWN; - - default_active_connection = find_default_active_connection (nm_client); - - if (!default_active_connection) { - return TRACKER_NETWORK_TYPE_NONE; - } - - switch (nm_active_connection_get_state (default_active_connection)) { - case NM_ACTIVE_CONNECTION_STATE_UNKNOWN: - return TRACKER_NETWORK_TYPE_UNKNOWN; - case NM_ACTIVE_CONNECTION_STATE_ACTIVATED: - break; - default: - return TRACKER_NETWORK_TYPE_NONE; - } - - devices = nm_active_connection_get_devices (default_active_connection); - - if (!devices->len) { - return TRACKER_NETWORK_TYPE_NONE; - } - - /* Pick the first device, I don't know when there are more than one */ - device = g_ptr_array_index (devices, 0); - - switch (nm_device_get_state (device)) { - case NM_DEVICE_STATE_UNKNOWN: - return TRACKER_NETWORK_TYPE_UNKNOWN; - break; - case NM_DEVICE_STATE_ACTIVATED: - break; - default: - return TRACKER_NETWORK_TYPE_NONE; - } - - if (NM_IS_DEVICE_ETHERNET (device) || NM_IS_DEVICE_WIFI (device)) { - return TRACKER_NETWORK_TYPE_LAN; - } - -#if (NM_CHECK_VERSION (0,8,992)) - if (NM_IS_DEVICE_MODEM (device)) { - return TRACKER_NETWORK_TYPE_3G; - } -#else - if (NM_IS_GSM_DEVICE (device) || NM_IS_CDMA_DEVICE (device)) { - return TRACKER_NETWORK_TYPE_3G; - } -#endif - - /* We know the device is activated, but we don't know the type of device */ - return TRACKER_NETWORK_TYPE_UNKNOWN; -} - -static void -_tracker_miner_online_set_network_type (TrackerMinerOnline *miner, - TrackerNetworkType type) -{ - TrackerMinerOnlinePrivate *priv; - gboolean cont = FALSE; - GError *error = NULL; - - priv = tracker_miner_online_get_instance_private (miner); - - if (type == priv->network_type) { - return; - } - - priv->network_type = type; - - if (type != TRACKER_NETWORK_TYPE_NONE) { - g_signal_emit (miner, signals[CONNECTED], 0, type, &cont); - } else { - g_signal_emit (miner, signals[DISCONNECTED], 0); - } - - if (cont && priv->paused) { - tracker_miner_resume (TRACKER_MINER (miner)); - priv->paused = FALSE; - } else if (!cont && !priv->paused) { - tracker_miner_pause (TRACKER_MINER (miner)); - priv->paused = TRUE; - } - - if (error) { - g_warning ("There was an error after getting network type %d: %s", - type, error->message); - g_error_free (error); - } -} - -static void -_nm_client_state_notify_cb (GObject *object, - GParamSpec *pspec, - TrackerMinerOnline *miner) -{ - TrackerMinerOnlinePrivate *priv; - TrackerNetworkType type; - - priv = tracker_miner_online_get_instance_private (miner); - type = _nm_client_get_network_type (priv->client); - _tracker_miner_online_set_network_type (miner, type); -} -#endif /* HAVE_NETWORK_MANAGER */ - -static gboolean -miner_online_initable_init (GInitable *initable, - GCancellable *cancellable, - GError **error) -{ -#ifdef HAVE_NETWORK_MANAGER - TrackerMinerOnlinePrivate *priv; - TrackerNetworkType network_type; - TrackerMinerOnline *miner; - - miner = TRACKER_MINER_ONLINE (initable); - - priv = tracker_miner_online_get_instance_private (miner); -#endif /* HAVE_NETWORK_MANAGER */ - - if (!miner_online_initable_parent_iface->init (initable, - cancellable, error)) { - return FALSE; - } - -#ifdef HAVE_NETWORK_MANAGER - priv->client = nm_client_new (NULL, error); - if (!priv->client) { - g_prefix_error (error, "Couldn't create NetworkManager client: "); - return FALSE; - } - g_signal_connect (priv->client, "notify::state", - G_CALLBACK (_nm_client_state_notify_cb), miner); - network_type = _nm_client_get_network_type (priv->client); - _tracker_miner_online_set_network_type (miner, network_type); -#endif - - return TRUE; -} - -static void -miner_online_initable_iface_init (GInitableIface *iface) -{ - miner_online_initable_parent_iface = g_type_interface_peek_parent (iface); - iface->init = miner_online_initable_init; -} - -/** - * tracker_miner_online_get_network_type: - * @miner: a #TrackerMinerOnline. - * - * Get the type of network this data @miner uses to index content. - * - * Returns: a #TrackerNetworkType on success or #TRACKER_NETWORK_TYPE_NONE on error. - * - * Since: 0.18 - **/ -TrackerNetworkType -tracker_miner_online_get_network_type (TrackerMinerOnline *miner) -{ - TrackerMinerOnlinePrivate *priv; - - g_return_val_if_fail (TRACKER_IS_MINER_ONLINE (miner), TRACKER_NETWORK_TYPE_NONE); - - priv = tracker_miner_online_get_instance_private (miner); - - return priv->network_type; -} diff --git a/src/libtracker-miner/tracker-miner-online.h b/src/libtracker-miner/tracker-miner-online.h deleted file mode 100644 index b7bdc5d3e..000000000 --- a/src/libtracker-miner/tracker-miner-online.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2009, Adrien Bustany <abustany@gnome.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __LIBTRACKER_MINER_ONLINE_H__ -#define __LIBTRACKER_MINER_ONLINE_H__ - -#if !defined (__LIBTRACKER_MINER_H_INSIDE__) && !defined (TRACKER_COMPILATION) -#error "Only <libtracker-miner/tracker-miner.h> can be included directly." -#endif - -#include <libtracker-miner/tracker-miner-object.h> -#include <libtracker-miner/tracker-miner-enums.h> - -#define TRACKER_TYPE_MINER_ONLINE (tracker_miner_online_get_type()) -#define TRACKER_MINER_ONLINE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_MINER_ONLINE, TrackerMinerOnline)) -#define TRACKER_MINER_ONLINE_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), TRACKER_TYPE_MINER_ONLINE, TrackerMinerOnlineClass)) -#define TRACKER_IS_MINER_ONLINE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_MINER_ONLINE)) -#define TRACKER_IS_MINER_ONLINE_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), TRACKER_TYPE_MINER_ONLINE)) -#define TRACKER_MINER_ONLINE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_MINER_ONLINE, TrackerMinerOnlineClass)) - -G_BEGIN_DECLS - -typedef struct _TrackerMinerOnline TrackerMinerOnline; -typedef struct _TrackerMinerOnlineClass TrackerMinerOnlineClass; - -/** - * TrackerMinerOnline: - * - * Abstract miner object for data requiring connectivity. - **/ -struct _TrackerMinerOnline { - TrackerMiner parent_instance; -}; - -/** - * TrackerMinerOnlineClass: - * @parent_class: a #TrackerMinerClass - * @connected: called when there is a network connection, or a new - * default route, returning #TRUE starts/resumes indexing. - * @disconnected: called when there is no network connection. - * @padding: Reserved for future API improvements. - * - * Virtual methods that can be overridden. - * - * Since: 0.18 - **/ -struct _TrackerMinerOnlineClass { - TrackerMinerClass parent_class; - - /* vmethods */ - gboolean (* connected) (TrackerMinerOnline *miner, - TrackerNetworkType network); - void (* disconnected) (TrackerMinerOnline *miner); - - /* <Private> */ - gpointer padding[10]; -}; - -GType tracker_miner_online_get_type (void) G_GNUC_CONST; - -TrackerNetworkType tracker_miner_online_get_network_type (TrackerMinerOnline *miner); - -G_END_DECLS - -#endif /* __LIBTRACKER_MINER_ONLINE_H__ */ diff --git a/src/libtracker-miner/tracker-miner-proxy.c b/src/libtracker-miner/tracker-miner-proxy.c deleted file mode 100644 index 78a5990b9..000000000 --- a/src/libtracker-miner/tracker-miner-proxy.c +++ /dev/null @@ -1,806 +0,0 @@ -/* - * Copyright (C) 2017, Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Authors: Carlos Garnacho <carlosg@gnome.org> - */ - -/** - * SECTION:tracker-miner-proxy - * @short_description: Proxies a #TrackerMiner on DBus - * @include: libtracker-miner/tracker-miner.h - * - * #TrackerMinerProxy is a helper object to expose org.freedesktop.Tracker1.Miner - * DBus interfaces for the given #TrackerMiner object. This is used to implement - * miners as DBus services. - * - * This proxy allows the miner to be controlled through external means, such as - * #TrackerMinerManager in libtracker-control. - * - * #TrackerMinerProxy implements the #GInitable interface, and thus all objects of - * types inheriting from #TrackerMinerProxy must be initialized with g_initable_init() - * just after creation (or directly created with g_initable_new()). - **/ - -#include "config.h" - -#include <glib/gi18n.h> -#include <libtracker-common/tracker-dbus.h> -#include <libtracker-common/tracker-type-utils.h> -#include <libtracker-common/tracker-domain-ontology.h> - -#include "tracker-miner-proxy.h" - -typedef struct { - TrackerMiner *miner; - GDBusConnection *d_connection; - GDBusNodeInfo *introspection_data; - gchar *dbus_path; - guint registration_id; - GHashTable *pauses; -} TrackerMinerProxyPrivate; - -typedef struct { - gint cookie; - gchar *application; - gchar *reason; - gchar *watch_name; - guint watch_name_id; -} PauseData; - -enum { - PROP_0, - PROP_MINER, - PROP_DBUS_CONNECTION, - PROP_DBUS_PATH, -}; - -static void tracker_miner_proxy_initable_iface_init (GInitableIface *iface); - -G_DEFINE_TYPE_WITH_CODE (TrackerMinerProxy, tracker_miner_proxy, G_TYPE_OBJECT, - G_ADD_PRIVATE (TrackerMinerProxy) - G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, tracker_miner_proxy_initable_iface_init)) - -static const gchar introspection_xml[] = - "<node>" - " <interface name='org.freedesktop.Tracker1.Miner'>" - " <method name='Start'>" - " </method>" - " <method name='GetStatus'>" - " <arg type='s' name='status' direction='out' />" - " </method>" - " <method name='GetProgress'>" - " <arg type='d' name='progress' direction='out' />" - " </method>" - " <method name='GetRemainingTime'>" - " <arg type='i' name='remaining_time' direction='out' />" - " </method>" - " <method name='GetPauseDetails'>" - " <arg type='as' name='pause_applications' direction='out' />" - " <arg type='as' name='pause_reasons' direction='out' />" - " </method>" - " <method name='Pause'>" - " <arg type='s' name='application' direction='in' />" - " <arg type='s' name='reason' direction='in' />" - " <arg type='i' name='cookie' direction='out' />" - " </method>" - " <method name='PauseForProcess'>" - " <arg type='s' name='application' direction='in' />" - " <arg type='s' name='reason' direction='in' />" - " <arg type='i' name='cookie' direction='out' />" - " </method>" - " <method name='Resume'>" - " <arg type='i' name='cookie' direction='in' />" - " </method>" - " <signal name='Started' />" - " <signal name='Stopped' />" - " <signal name='Paused' />" - " <signal name='Resumed' />" - " <signal name='Progress'>" - " <arg type='s' name='status' />" - " <arg type='d' name='progress' />" - " <arg type='i' name='remaining_time' />" - " </signal>" - " </interface>" - "</node>"; - -#define TRACKER_SERVICE "org.freedesktop.Tracker1" - -static PauseData * -pause_data_new (const gchar *application, - const gchar *reason, - const gchar *watch_name, - guint watch_name_id) -{ - PauseData *data; - static gint cookie = 1; - - data = g_slice_new0 (PauseData); - - data->cookie = cookie++; - data->application = g_strdup (application); - data->reason = g_strdup (reason); - data->watch_name = g_strdup (watch_name); - data->watch_name_id = watch_name_id; - - return data; -} - -static void -pause_data_destroy (gpointer data) -{ - PauseData *pd; - - pd = data; - - if (pd->watch_name_id) { - g_bus_unwatch_name (pd->watch_name_id); - } - - g_free (pd->watch_name); - - g_free (pd->reason); - g_free (pd->application); - - g_slice_free (PauseData, pd); -} - -static void -tracker_miner_proxy_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - TrackerMinerProxy *proxy = TRACKER_MINER_PROXY (object); - TrackerMinerProxyPrivate *priv = tracker_miner_proxy_get_instance_private (proxy); - - switch (prop_id) { - case PROP_MINER: - priv->miner = g_value_dup_object (value); - break; - case PROP_DBUS_CONNECTION: - priv->d_connection = g_value_dup_object (value); - break; - case PROP_DBUS_PATH: - priv->dbus_path = g_value_dup_string (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -tracker_miner_proxy_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - TrackerMinerProxy *proxy = TRACKER_MINER_PROXY (object); - TrackerMinerProxyPrivate *priv = tracker_miner_proxy_get_instance_private (proxy); - - switch (prop_id) { - case PROP_MINER: - g_value_set_object (value, priv->miner); - break; - case PROP_DBUS_CONNECTION: - g_value_set_object (value, priv->d_connection); - break; - case PROP_DBUS_PATH: - g_value_set_string (value, priv->dbus_path); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -tracker_miner_proxy_finalize (GObject *object) -{ - TrackerMinerProxy *proxy = TRACKER_MINER_PROXY (object); - TrackerMinerProxyPrivate *priv = tracker_miner_proxy_get_instance_private (proxy); - - g_signal_handlers_disconnect_by_data (priv->miner, proxy); - g_clear_object (&priv->miner); - g_free (priv->dbus_path); - g_hash_table_unref (priv->pauses); - - if (priv->registration_id != 0) { - g_dbus_connection_unregister_object (priv->d_connection, - priv->registration_id); - } - - if (priv->introspection_data) { - g_dbus_node_info_unref (priv->introspection_data); - } - - if (priv->d_connection) { - g_object_unref (priv->d_connection); - } - - G_OBJECT_CLASS (tracker_miner_proxy_parent_class)->finalize (object); -} - -static void -tracker_miner_proxy_class_init (TrackerMinerProxyClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->set_property = tracker_miner_proxy_set_property; - object_class->get_property = tracker_miner_proxy_get_property; - object_class->finalize = tracker_miner_proxy_finalize; - - g_object_class_install_property (object_class, - PROP_MINER, - g_param_spec_object ("miner", - "Miner to manage", - "Miner to manage", - TRACKER_TYPE_MINER, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); - g_object_class_install_property (object_class, - PROP_DBUS_CONNECTION, - g_param_spec_object ("dbus-connection", - "DBus connection", - "DBus connection", - G_TYPE_DBUS_CONNECTION, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); - g_object_class_install_property (object_class, - PROP_DBUS_PATH, - g_param_spec_string ("dbus-path", - "DBus path", - "DBus path for this miner", - NULL, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); -} - -static void -tracker_miner_proxy_init (TrackerMinerProxy *proxy) -{ - TrackerMinerProxyPrivate *priv = tracker_miner_proxy_get_instance_private (proxy); - - priv->pauses = g_hash_table_new_full (g_direct_hash, - g_direct_equal, - NULL, - pause_data_destroy); -} - -static void -handle_method_call_start (TrackerMinerProxy *proxy, - GDBusMethodInvocation *invocation, - GVariant *parameters) -{ - TrackerDBusRequest *request; - TrackerMinerProxyPrivate *priv; - - priv = tracker_miner_proxy_get_instance_private (proxy); - - request = tracker_g_dbus_request_begin (invocation, - "%s", - __PRETTY_FUNCTION__); - - tracker_miner_start (priv->miner); - - tracker_dbus_request_end (request, NULL); - g_dbus_method_invocation_return_value (invocation, NULL); -} - -static void -sync_miner_pause_state (TrackerMinerProxy *proxy) -{ - TrackerMinerProxyPrivate *priv; - guint n_pauses; - gboolean is_paused; - - priv = tracker_miner_proxy_get_instance_private (proxy); - n_pauses = g_hash_table_size (priv->pauses); - is_paused = tracker_miner_is_paused (priv->miner); - - if (!is_paused && n_pauses > 0) { - tracker_miner_pause (priv->miner); - } else if (is_paused && n_pauses == 0) { - tracker_miner_resume (priv->miner); - } -} - -static void -handle_method_call_resume (TrackerMinerProxy *proxy, - GDBusMethodInvocation *invocation, - GVariant *parameters) -{ - gint cookie; - TrackerDBusRequest *request; - TrackerMinerProxyPrivate *priv; - - priv = tracker_miner_proxy_get_instance_private (proxy); - - g_variant_get (parameters, "(i)", &cookie); - - request = tracker_g_dbus_request_begin (invocation, - "%s(cookie:%d)", - __PRETTY_FUNCTION__, - cookie); - - if (!g_hash_table_remove (priv->pauses, GINT_TO_POINTER (cookie))) { - tracker_dbus_request_end (request, NULL); - g_dbus_method_invocation_return_error (invocation, - tracker_miner_error_quark (), - TRACKER_MINER_ERROR_INVALID_COOKIE, - _("Cookie not recognized to resume paused miner")); - } else { - sync_miner_pause_state (proxy); - tracker_dbus_request_end (request, NULL); - g_dbus_method_invocation_return_value (invocation, NULL); - } -} - -static void -pause_process_disappeared_cb (GDBusConnection *connection, - const gchar *name, - gpointer user_data) -{ - TrackerMinerProxy *proxy = user_data; - TrackerMinerProxyPrivate *priv = tracker_miner_proxy_get_instance_private (proxy); - GHashTableIter iter; - gpointer key, value; - - g_message ("Process with name:'%s' has disappeared", name); - - g_hash_table_iter_init (&iter, priv->pauses); - while (g_hash_table_iter_next (&iter, &key, &value)) { - PauseData *pd_iter = value; - - if (g_strcmp0 (name, pd_iter->watch_name) == 0) - g_hash_table_iter_remove (&iter); - } - - sync_miner_pause_state (proxy); -} - -static gint -pause_miner (TrackerMinerProxy *proxy, - const gchar *application, - const gchar *reason, - const gchar *calling_name, - GError **error) -{ - TrackerMinerProxyPrivate *priv; - PauseData *pd; - GHashTableIter iter; - gpointer key, value; - guint watch_name_id = 0; - - priv = tracker_miner_proxy_get_instance_private (proxy); - - /* Check this is not a duplicate pause */ - g_hash_table_iter_init (&iter, priv->pauses); - while (g_hash_table_iter_next (&iter, &key, &value)) { - PauseData *pd = value; - - if (g_strcmp0 (application, pd->application) == 0 && - g_strcmp0 (reason, pd->reason) == 0) { - /* Can't use duplicate pauses */ - g_set_error_literal (error, - tracker_miner_error_quark (), - TRACKER_MINER_ERROR_PAUSED_ALREADY, - _("Pause application and reason match an already existing pause request")); - return -1; - } - } - - if (calling_name) { - g_message ("Watching process with name:'%s'", calling_name); - watch_name_id = g_bus_watch_name (TRACKER_IPC_BUS, - calling_name, - G_BUS_NAME_WATCHER_FLAGS_NONE, - NULL, - pause_process_disappeared_cb, - proxy, - NULL); - } - - pd = pause_data_new (application, reason, calling_name, watch_name_id); - - g_hash_table_insert (priv->pauses, - GINT_TO_POINTER (pd->cookie), - pd); - - sync_miner_pause_state (proxy); - - return pd->cookie; -} - -static void -handle_method_call_pause (TrackerMinerProxy *proxy, - GDBusMethodInvocation *invocation, - GVariant *parameters) -{ - GError *local_error = NULL; - gint cookie; - const gchar *application = NULL, *reason = NULL; - TrackerDBusRequest *request; - - g_variant_get (parameters, "(&s&s)", &application, &reason); - - tracker_gdbus_async_return_if_fail (application != NULL, invocation); - tracker_gdbus_async_return_if_fail (reason != NULL, invocation); - - request = tracker_g_dbus_request_begin (invocation, - "%s(application:'%s', reason:'%s')", - __PRETTY_FUNCTION__, - application, - reason); - - cookie = pause_miner (proxy, application, reason, NULL, &local_error); - if (cookie == -1) { - tracker_dbus_request_end (request, local_error); - - g_dbus_method_invocation_return_gerror (invocation, local_error); - - g_error_free (local_error); - - return; - } - - tracker_dbus_request_end (request, NULL); - g_dbus_method_invocation_return_value (invocation, - g_variant_new ("(i)", cookie)); -} - -static void -handle_method_call_pause_for_process (TrackerMinerProxy *proxy, - GDBusMethodInvocation *invocation, - GVariant *parameters) -{ - GError *local_error = NULL; - gint cookie; - const gchar *application = NULL, *reason = NULL; - TrackerDBusRequest *request; - - g_variant_get (parameters, "(&s&s)", &application, &reason); - - tracker_gdbus_async_return_if_fail (application != NULL, invocation); - tracker_gdbus_async_return_if_fail (reason != NULL, invocation); - - request = tracker_g_dbus_request_begin (invocation, - "%s(application:'%s', reason:'%s')", - __PRETTY_FUNCTION__, - application, - reason); - - cookie = pause_miner (proxy, - application, - reason, - g_dbus_method_invocation_get_sender (invocation), - &local_error); - if (cookie == -1) { - tracker_dbus_request_end (request, local_error); - - g_dbus_method_invocation_return_gerror (invocation, local_error); - - g_error_free (local_error); - - return; - } - - tracker_dbus_request_end (request, NULL); - g_dbus_method_invocation_return_value (invocation, - g_variant_new ("(i)", cookie)); -} - -static void -handle_method_call_get_pause_details (TrackerMinerProxy *proxy, - GDBusMethodInvocation *invocation, - GVariant *parameters) -{ - GSList *applications, *reasons; - GStrv applications_strv, reasons_strv; - GHashTableIter iter; - gpointer key, value; - TrackerDBusRequest *request; - TrackerMinerProxyPrivate *priv; - - priv = tracker_miner_proxy_get_instance_private (proxy); - request = tracker_g_dbus_request_begin (invocation, "%s()", __PRETTY_FUNCTION__); - - applications = NULL; - reasons = NULL; - g_hash_table_iter_init (&iter, priv->pauses); - while (g_hash_table_iter_next (&iter, &key, &value)) { - PauseData *pd = value; - - applications = g_slist_prepend (applications, pd->application); - reasons = g_slist_prepend (reasons, pd->reason); - } - applications = g_slist_reverse (applications); - reasons = g_slist_reverse (reasons); - applications_strv = tracker_gslist_to_string_list (applications); - reasons_strv = tracker_gslist_to_string_list (reasons); - - tracker_dbus_request_end (request, NULL); - g_dbus_method_invocation_return_value (invocation, - g_variant_new ("(^as^as)", - applications_strv, - reasons_strv)); - - g_strfreev (applications_strv); - g_strfreev (reasons_strv); - g_slist_free (applications); - g_slist_free (reasons); -} - -static void -handle_method_call_get_remaining_time (TrackerMinerProxy *proxy, - GDBusMethodInvocation *invocation, - GVariant *parameters) -{ - TrackerDBusRequest *request; - TrackerMinerProxyPrivate *priv; - gint remaining_time; - - priv = tracker_miner_proxy_get_instance_private (proxy); - - request = tracker_g_dbus_request_begin (invocation, "%s()", __PRETTY_FUNCTION__); - - tracker_dbus_request_end (request, NULL); - g_object_get (G_OBJECT (priv->miner), "remaining-time", &remaining_time, NULL); - g_dbus_method_invocation_return_value (invocation, - g_variant_new ("(i)", remaining_time)); -} - -static void -handle_method_call_get_progress (TrackerMinerProxy *proxy, - GDBusMethodInvocation *invocation, - GVariant *parameters) -{ - TrackerDBusRequest *request; - TrackerMinerProxyPrivate *priv; - gdouble progress; - - priv = tracker_miner_proxy_get_instance_private (proxy); - - request = tracker_g_dbus_request_begin (invocation, "%s()", __PRETTY_FUNCTION__); - - tracker_dbus_request_end (request, NULL); - g_object_get (G_OBJECT (priv->miner), "progress", &progress, NULL); - g_dbus_method_invocation_return_value (invocation, - g_variant_new ("(d)", progress)); -} - -static void -handle_method_call_get_status (TrackerMinerProxy *proxy, - GDBusMethodInvocation *invocation, - GVariant *parameters) -{ - TrackerDBusRequest *request; - TrackerMinerProxyPrivate *priv; - gchar *status; - - priv = tracker_miner_proxy_get_instance_private (proxy); - - request = tracker_g_dbus_request_begin (invocation, "%s()", __PRETTY_FUNCTION__); - - tracker_dbus_request_end (request, NULL); - g_object_get (G_OBJECT (priv->miner), "status", &status, NULL); - g_dbus_method_invocation_return_value (invocation, - g_variant_new ("(s)", - status ? status : "")); - g_free (status); -} - -static void -handle_method_call (GDBusConnection *connection, - const gchar *sender, - const gchar *object_path, - const gchar *interface_name, - const gchar *method_name, - GVariant *parameters, - GDBusMethodInvocation *invocation, - gpointer user_data) -{ - TrackerMinerProxy *proxy = user_data; - - if (g_strcmp0 (method_name, "Start") == 0) { - handle_method_call_start (proxy, invocation, parameters); - } else if (g_strcmp0 (method_name, "Resume") == 0) { - handle_method_call_resume (proxy, invocation, parameters); - } else if (g_strcmp0 (method_name, "Pause") == 0) { - handle_method_call_pause (proxy, invocation, parameters); - } else if (g_strcmp0 (method_name, "PauseForProcess") == 0) { - handle_method_call_pause_for_process (proxy, invocation, parameters); - } else if (g_strcmp0 (method_name, "GetPauseDetails") == 0) { - handle_method_call_get_pause_details (proxy, invocation, parameters); - } else if (g_strcmp0 (method_name, "GetRemainingTime") == 0) { - handle_method_call_get_remaining_time (proxy, invocation, parameters); - } else if (g_strcmp0 (method_name, "GetProgress") == 0) { - handle_method_call_get_progress (proxy, invocation, parameters); - } else if (g_strcmp0 (method_name, "GetStatus") == 0) { - handle_method_call_get_status (proxy, invocation, parameters); - } else { - g_dbus_method_invocation_return_error (invocation, - G_DBUS_ERROR, - G_DBUS_ERROR_UNKNOWN_METHOD, - "Unknown method %s", - method_name); - } -} - -static GVariant * -handle_get_property (GDBusConnection *connection, - const gchar *sender, - const gchar *object_path, - const gchar *interface_name, - const gchar *property_name, - GError **error, - gpointer user_data) -{ - return NULL; -} - -static gboolean -handle_set_property (GDBusConnection *connection, - const gchar *sender, - const gchar *object_path, - const gchar *interface_name, - const gchar *property_name, - GVariant *value, - GError **error, - gpointer user_data) -{ - return FALSE; -} - -static void -emit_dbus_signal (TrackerMinerProxy *proxy, - const gchar *signal, - GVariant *variant) -{ - TrackerMinerProxyPrivate *priv; - - priv = tracker_miner_proxy_get_instance_private (proxy); - g_dbus_connection_emit_signal (priv->d_connection, - NULL, - priv->dbus_path, - TRACKER_MINER_DBUS_INTERFACE, - signal, - variant, - NULL); -} - -static void -miner_started_cb (TrackerMiner *miner, - TrackerMinerProxy *proxy) -{ - emit_dbus_signal (proxy, "Started", NULL); -} - -static void -miner_stopped_cb (TrackerMiner *miner, - TrackerMinerProxy *proxy) -{ - emit_dbus_signal (proxy, "Stopped", NULL); -} - -static void -miner_paused_cb (TrackerMiner *miner, - TrackerMinerProxy *proxy) -{ - emit_dbus_signal (proxy, "Paused", NULL); -} - -static void -miner_resumed_cb (TrackerMiner *miner, - TrackerMinerProxy *proxy) -{ - emit_dbus_signal (proxy, "Resumed", NULL); -} - -static void -miner_progress_cb (TrackerMiner *miner, - const gchar *status, - gdouble progress, - gint remaining_time, - TrackerMinerProxy *proxy) -{ - GVariant *variant; - - variant = g_variant_new ("(sdi)", status, progress, remaining_time); - /* variant reference is sunk here */ - emit_dbus_signal (proxy, "Progress", variant); -} - -static gboolean -tracker_miner_proxy_initable_init (GInitable *initable, - GCancellable *cancellable, - GError **error) -{ - TrackerMinerProxy *proxy = TRACKER_MINER_PROXY (initable); - TrackerMinerProxyPrivate *priv = tracker_miner_proxy_get_instance_private (proxy); - GError *inner_error = NULL; - TrackerDomainOntology *domain_ontology; - GDBusInterfaceVTable interface_vtable = { - handle_method_call, - handle_get_property, - handle_set_property - }; - - priv->introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, - &inner_error); - if (inner_error) { - g_propagate_error (error, inner_error); - return FALSE; - } - - priv->registration_id = - g_dbus_connection_register_object (priv->d_connection, - priv->dbus_path, - priv->introspection_data->interfaces[0], - &interface_vtable, - proxy, - NULL, - &inner_error); - if (inner_error) { - g_propagate_error (error, inner_error); - return FALSE; - } - - domain_ontology = tracker_domain_ontology_new (tracker_sparql_connection_get_domain (), - cancellable, &inner_error); - if (inner_error) { - g_propagate_error (error, inner_error); - return FALSE; - } - - g_signal_connect (priv->miner, "started", - G_CALLBACK (miner_started_cb), proxy); - g_signal_connect (priv->miner, "stopped", - G_CALLBACK (miner_stopped_cb), proxy); - g_signal_connect (priv->miner, "paused", - G_CALLBACK (miner_paused_cb), proxy); - g_signal_connect (priv->miner, "resumed", - G_CALLBACK (miner_resumed_cb), proxy); - g_signal_connect (priv->miner, "progress", - G_CALLBACK (miner_progress_cb), proxy); - - tracker_domain_ontology_unref (domain_ontology); - - return TRUE; -} - -static void -tracker_miner_proxy_initable_iface_init (GInitableIface *iface) -{ - iface->init = tracker_miner_proxy_initable_init; -} - -TrackerMinerProxy * -tracker_miner_proxy_new (TrackerMiner *miner, - GDBusConnection *connection, - const gchar *dbus_path, - GCancellable *cancellable, - GError **error) -{ - return g_initable_new (TRACKER_TYPE_MINER_PROXY, - cancellable, error, - "miner", miner, - "dbus-connection", connection, - "dbus-path", dbus_path, - NULL); -} diff --git a/src/libtracker-miner/tracker-miner-proxy.h b/src/libtracker-miner/tracker-miner-proxy.h deleted file mode 100644 index a41c39139..000000000 --- a/src/libtracker-miner/tracker-miner-proxy.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2017, Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Authors: Carlos Garnacho <carlosg@gnome.org> - */ - -#ifndef __TRACKER_MINER_PROXY_H__ -#define __TRACKER_MINER_PROXY_H__ - -#if !defined (__LIBTRACKER_MINER_H_INSIDE__) && !defined (TRACKER_COMPILATION) -#error "Only <libtracker-miner/tracker-miner.h> can be included directly." -#endif - -#include <glib-object.h> -#include <gio/gio.h> -#include "tracker-miner-object.h" - -#define TRACKER_TYPE_MINER_PROXY (tracker_miner_proxy_get_type()) -#define TRACKER_MINER_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_MINER_PROXY, TrackerMinerProxy)) -#define TRACKER_MINER_PROXY_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), TRACKER_TYPE_MINER_PROXY, TrackerMinerProxyClass)) -#define TRACKER_IS_MINER_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_MINER_PROXY)) -#define TRACKER_IS_MINER_PROXY_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), TRACKER_TYPE_MINER_PROXY)) -#define TRACKER_MINER_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_MINER_PROXY, TrackerMinerProxyClass)) - -typedef struct _TrackerMinerProxy TrackerMinerProxy; -typedef struct _TrackerMinerProxyClass TrackerMinerProxyClass; - -struct _TrackerMinerProxy { - GObject parent_instance; -}; - -struct _TrackerMinerProxyClass { - GObjectClass parent_class; - /*<private>*/ - gpointer padding[10]; -}; - -GType tracker_miner_proxy_get_type (void) G_GNUC_CONST; - -TrackerMinerProxy * tracker_miner_proxy_new (TrackerMiner *miner, - GDBusConnection *connection, - const gchar *dbus_path, - GCancellable *cancellable, - GError **error); - -#endif /* __TRACKER_MINER_PROXY_H__ */ diff --git a/src/libtracker-miner/tracker-miner.deps b/src/libtracker-miner/tracker-miner.deps deleted file mode 100644 index cd10dfde4..000000000 --- a/src/libtracker-miner/tracker-miner.deps +++ /dev/null @@ -1 +0,0 @@ -gio-2.0 diff --git a/src/libtracker-miner/tracker-miner.h b/src/libtracker-miner/tracker-miner.h deleted file mode 100644 index 9d6d20ee1..000000000 --- a/src/libtracker-miner/tracker-miner.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2009, Nokia <ivan.frade@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __LIBTRACKER_MINER_H__ -#define __LIBTRACKER_MINER_H__ - -#define __LIBTRACKER_MINER_H_INSIDE__ - -#include <libtracker-miner/tracker-data-provider.h> -#include <libtracker-miner/tracker-decorator.h> -#include <libtracker-miner/tracker-decorator-fs.h> -#include <libtracker-miner/tracker-miner-object.h> -#include <libtracker-miner/tracker-miner-online.h> -#include <libtracker-miner/tracker-miner-fs.h> -#include <libtracker-miner/tracker-miner-enums.h> -#include <libtracker-miner/tracker-miner-enum-types.h> -#include <libtracker-miner/tracker-indexing-tree.h> -#include <libtracker-miner/tracker-miner-proxy.h> - -#undef __LIBTRACKER_MINER_H_INSIDE__ - -#endif /* __LIBTRACKER_MINER_H__ */ diff --git a/src/libtracker-miner/tracker-miner.vapi b/src/libtracker-miner/tracker-miner.vapi deleted file mode 100644 index 8e94eeedd..000000000 --- a/src/libtracker-miner/tracker-miner.vapi +++ /dev/null @@ -1,208 +0,0 @@ -/* tracker-miner.vapi generated by vapigen, do not modify. */ - -[CCode (cprefix = "Tracker", gir_namespace = "TrackerMiner", gir_version = "2.0", lower_case_cprefix = "tracker_")] -namespace Tracker { - [CCode (cheader_filename = "libtracker-miner/tracker-miner.h", type_id = "tracker_decorator_get_type ()")] - public abstract class Decorator : Tracker.Miner, GLib.Initable { - [CCode (has_construct_function = false)] - protected Decorator (); - public void delete_id (int id); - public static GLib.Quark error_quark (); - [CCode (array_length = false, array_null_terminated = true)] - public unowned string[] get_class_names (); - public unowned string get_data_source (); - public uint get_n_items (); - public async Tracker.DecoratorInfo next (GLib.Cancellable? cancellable = null) throws GLib.Error; - public void prepend_id (int id, int class_name_id); - public void set_priority_rdf_types (string rdf_types); - [CCode (array_length = false, array_null_terminated = true)] - [NoAccessorMethod] - public string[] class_names { owned get; set; } - [NoAccessorMethod] - public int commit_batch_size { get; set; } - public string data_source { get; construct; } - [CCode (array_length = false, array_null_terminated = true)] - public string[] priority_rdf_types { set; } - public virtual signal void finished (); - public virtual signal void items_available (); - } - [CCode (cheader_filename = "libtracker-miner/tracker-miner.h", type_id = "tracker_decorator_fs_get_type ()")] - public abstract class DecoratorFS : Tracker.Decorator, GLib.Initable { - [CCode (has_construct_function = false)] - protected DecoratorFS (); - public int prepend_file (GLib.File file); - } - [CCode (cheader_filename = "libtracker-miner/tracker-miner.h", ref_function = "tracker_decorator_info_ref", type_id = "tracker_decorator_info_get_type ()", unref_function = "tracker_decorator_info_unref")] - [Compact] - public class DecoratorInfo { - public unowned string get_mimetype (); - public Tracker.Sparql.Builder get_sparql (); - public unowned GLib.Task get_task (); - public unowned string get_url (); - public unowned string get_urn (); - public Tracker.DecoratorInfo @ref (); - public void unref (); - } - [CCode (cheader_filename = "libtracker-miner/tracker-miner.h", type_id = "tracker_indexing_tree_get_type ()")] - public class IndexingTree : GLib.Object { - [CCode (has_construct_function = false)] - public IndexingTree (); - public void add (GLib.File directory, Tracker.DirectoryFlags flags); - public void add_filter (Tracker.FilterType filter, string glob_string); - public void clear_filters (Tracker.FilterType type); - public bool file_is_indexable (GLib.File file, GLib.FileType file_type); - public bool file_is_root (GLib.File file); - public bool file_matches_filter (Tracker.FilterType type, GLib.File file); - public Tracker.FilterPolicy get_default_policy (Tracker.FilterType filter); - public bool get_filter_hidden (); - public unowned GLib.File get_master_root (); - public unowned GLib.File get_root (GLib.File file, out Tracker.DirectoryFlags directory_flags); - public GLib.List<weak GLib.File> list_roots (); - public bool parent_is_indexable (GLib.File parent, GLib.List<GLib.File> children); - public void remove (GLib.File directory); - public void set_default_policy (Tracker.FilterType filter, Tracker.FilterPolicy policy); - public void set_filter_hidden (bool filter_hidden); - [CCode (has_construct_function = false)] - public IndexingTree.with_root (GLib.File root); - public bool filter_hidden { get; set; } - [NoAccessorMethod] - public GLib.File root { owned get; construct; } - public virtual signal void directory_added (GLib.File directory); - public virtual signal void directory_removed (GLib.File directory); - public virtual signal void directory_updated (GLib.File directory); - } - [CCode (cheader_filename = "libtracker-miner/tracker-miner.h", type_id = "tracker_miner_get_type ()")] - public abstract class Miner : GLib.Object, GLib.Initable { - [CCode (has_construct_function = false)] - protected Miner (); - public static GLib.Quark error_quark (); - public Tracker.Sparql.Connection get_connection (); - public bool is_paused (); - public bool is_started (); - public void pause (); - public bool resume (); - public void start (); - public void stop (); - [NoAccessorMethod] - public string name { owned get; construct; } - [NoAccessorMethod] - public virtual double progress { get; set construct; } - [NoAccessorMethod] - public int remaining_time { get; set construct; } - [NoAccessorMethod] - public string status { owned get; set construct; } - [HasEmitter] - public virtual signal void paused (); - public virtual signal void resumed (); - public virtual signal void started (); - public virtual signal void stopped (); - } - [CCode (cheader_filename = "libtracker-miner/tracker-miner.h", type_id = "tracker_miner_fs_get_type ()")] - public abstract class MinerFS : Tracker.Miner, GLib.Initable { - [CCode (has_construct_function = false)] - protected MinerFS (); - public void check_file (GLib.File file, int priority, bool check_parents); - public static GLib.Quark error_quark (); - public void notify_finish (GLib.File file, GLib.Task task, string sparql, GLib.Error error); - public unowned Tracker.DataProvider get_data_provider (); - public unowned Tracker.IndexingTree get_indexing_tree (); - public double get_throttle (); - public unowned string? get_urn (GLib.File file); - public bool has_items_to_process (); - public string query_urn (GLib.File file); - public void set_throttle (double throttle); - public void writeback_notify (GLib.File file, GLib.Error error); - public Tracker.DataProvider data_provider { get; construct; } - [NoAccessorMethod] - public uint processing_pool_ready_limit { get; set construct; } - [NoAccessorMethod] - public uint processing_pool_wait_limit { get; set construct; } - [NoAccessorMethod] - public GLib.File root { owned get; construct; } - public double throttle { get; set; } - public virtual signal void finished (double elapsed, uint directories_found, uint directories_ignored, uint files_found, uint files_ignored); - public virtual signal void finished_root (GLib.File root); - public virtual signal bool process_file (GLib.File file, Tracker.Sparql.Builder builder, GLib.Cancellable? cancellable = null); - public virtual signal bool process_file_attributes (GLib.File file, Tracker.Sparql.Builder builder, GLib.Cancellable? cancellable = null); - public signal bool writeback_file (GLib.File file, [CCode (array_length = false, array_null_terminated = true)] string[] rdf_types, GLib.GenericArray<string[]> results, GLib.Cancellable? cancellable = null); - } - [CCode (cheader_filename = "libtracker-miner/tracker-miner.h", type_id = "tracker_miner_online_get_type ()")] - public abstract class MinerOnline : Tracker.Miner, GLib.Initable { - [CCode (has_construct_function = false)] - protected MinerOnline (); - public Tracker.NetworkType get_network_type (); - public Tracker.NetworkType network_type { get; } - public virtual signal bool connected (Tracker.NetworkType network); - public virtual signal void disconnected (); - } - [CCode (cheader_filename = "libtracker-miner/tracker-miner.h", type_id = "tracker_data_provider_get_type ()")] - public interface DataProvider : GLib.Object { - public abstract Tracker.Enumerator begin (GLib.File url, string attributes, Tracker.DirectoryFlags flags, GLib.Cancellable? cancellable = null) throws GLib.Error; - public abstract async Tracker.Enumerator begin_async (GLib.File url, string attributes, Tracker.DirectoryFlags flags, int io_priority, GLib.Cancellable? cancellable = null) throws GLib.Error; - public abstract bool end (Tracker.Enumerator enumerator, GLib.Cancellable? cancellable = null) throws GLib.Error; - public abstract async bool end_async (Tracker.Enumerator enumerator, int io_priority, GLib.Cancellable? cancellable = null) throws GLib.Error; - } - [CCode (cheader_filename = "libtracker-miner/tracker-miner.h", type_id = "tracker_enumerator_get_type ()")] - public interface Enumerator : GLib.Object { - public abstract void* next (GLib.Cancellable? cancellable = null) throws GLib.Error; - public abstract async void* next_async (int io_priority, GLib.Cancellable? cancellable = null) throws GLib.Error; - } - [CCode (cheader_filename = "libtracker-miner/tracker-miner.h", cprefix = "TRACKER_DIRECTORY_FLAG_", type_id = "tracker_directory_flags_get_type ()")] - [Flags] - public enum DirectoryFlags { - NONE, - RECURSE, - CHECK_MTIME, - MONITOR, - IGNORE, - PRESERVE, - PRIORITY, - NO_STAT - } - [CCode (cheader_filename = "libtracker-miner/tracker-miner.h", cprefix = "TRACKER_FILTER_POLICY_", type_id = "tracker_filter_policy_get_type ()")] - public enum FilterPolicy { - DENY, - ACCEPT - } - [CCode (cheader_filename = "libtracker-miner/tracker-miner.h", cprefix = "TRACKER_FILTER_", type_id = "tracker_filter_type_get_type ()")] - public enum FilterType { - FILE, - DIRECTORY, - PARENT_DIRECTORY - } - [CCode (cheader_filename = "libtracker-miner/tracker-miner.h", cprefix = "TRACKER_NETWORK_TYPE_", type_id = "tracker_network_type_get_type ()")] - public enum NetworkType { - NONE, - UNKNOWN, - GPRS, - EDGE, - @3G, - LAN - } - [CCode (cheader_filename = "libtracker-miner/tracker-miner.h", cprefix = "TRACKER_DECORATOR_ERROR_")] - public errordomain DecoratorError { - EMPTY, - PAUSED - } - [CCode (cheader_filename = "libtracker-miner/tracker-miner.h", cprefix = "TRACKER_MINER_ERROR_")] - public errordomain MinerError { - NAME_MISSING, - NAME_UNAVAILABLE, - PAUSED, - PAUSED_ALREADY, - INVALID_COOKIE - } - [CCode (cheader_filename = "libtracker-miner/tracker-miner.h", cprefix = "TRACKER_MINER_FS_ERROR_")] - public errordomain MinerFSError { - [CCode (cname = "TRACKER_MINER_FS_ERROR_INIT")] - MINER_FS_ERROR_INIT - } - [CCode (cheader_filename = "libtracker-miner/tracker-miner.h", cname = "TRACKER_MINER_DBUS_INTERFACE")] - public const string MINER_DBUS_INTERFACE; - [CCode (cheader_filename = "libtracker-miner/tracker-miner.h", cname = "TRACKER_MINER_DBUS_NAME_PREFIX")] - public const string MINER_DBUS_NAME_PREFIX; - [CCode (cheader_filename = "libtracker-miner/tracker-miner.h", cname = "TRACKER_MINER_DBUS_PATH_PREFIX")] - public const string MINER_DBUS_PATH_PREFIX; - [CCode (cheader_filename = "libtracker-miner/tracker-miner.h", cname = "TRACKER_MINER_ERROR_DOMAIN")] - public const string MINER_ERROR_DOMAIN; -} diff --git a/src/libtracker-miner/tracker-miner.xml b/src/libtracker-miner/tracker-miner.xml deleted file mode 100644 index f12c8a91b..000000000 --- a/src/libtracker-miner/tracker-miner.xml +++ /dev/null @@ -1,56 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<node name="/"> - <interface name="org.freedesktop.Tracker1.Miner"> - <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="_tracker_miner_dbus"/> - <method name="Start"> - <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/> - </method> - <method name="GetStatus"> - <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/> - <arg type="s" name="status" direction="out" /> - </method> - <method name="GetProgress"> - <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/> - <arg type="d" name="progress" direction="out" /> - </method> - <method name="GetRemainingTime"> - <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/> - <arg type="i" name="remaining_time" direction="out" /> - </method> - <method name="GetPauseDetails"> - <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/> - <arg type="as" name="pause_applications" direction="out" /> - <arg type="as" name="pause_reasons" direction="out" /> - </method> - <method name="Pause"> - <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/> - <arg type="s" name="application" direction="in" /> - <arg type="s" name="reason" direction="in" /> - <arg type="i" name="cookie" direction="out" /> - </method> - <method name="PauseForProcess"> - <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/> - <arg type="s" name="application" direction="in" /> - <arg type="s" name="reason" direction="in" /> - <arg type="i" name="cookie" direction="out" /> - </method> - <method name="Resume"> - <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/> - <arg type="i" name="cookie" direction="in" /> - </method> - - <!-- Signals --> - <signal name="Started" /> - <signal name="Stopped"> - <arg type="b" name="interrupted" /> - </signal> - <signal name="Paused" /> - <signal name="Resumed" /> - <signal name="Progress"> - <arg type="s" name="status" /> - <arg type="d" name="progress" /> - <arg type="i" name="remaining_time" /> - </signal> - </interface> -</node> diff --git a/src/libtracker-miner/tracker-monitor.c b/src/libtracker-miner/tracker-monitor.c deleted file mode 100644 index f87a5b672..000000000 --- a/src/libtracker-miner/tracker-monitor.c +++ /dev/null @@ -1,1139 +0,0 @@ -/* - * Copyright (C) 2009, Nokia <ivan.frade@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "config.h" - -#include <stdlib.h> -#include <string.h> -#include <gio/gio.h> - -#if defined (__OpenBSD__) || defined (__FreeBSD__) || defined (__NetBSD__) || defined (__APPLE__) -#include <sys/types.h> -#include <sys/time.h> -#include <sys/resource.h> -#define TRACKER_MONITOR_KQUEUE -#endif - -#include "tracker-monitor.h" - -/* The life time of an item in the cache */ -#define CACHE_LIFETIME_SECONDS 1 - -typedef struct TrackerMonitorPrivate TrackerMonitorPrivate; - -struct TrackerMonitorPrivate { - GHashTable *monitors; - - gboolean enabled; - - guint monitor_limit; - gboolean monitor_limit_warned; - guint monitors_ignored; - - /* For FAM, the _CHANGES_DONE event is not signalled, so we - * have to just use the _CHANGED event instead. - */ - gboolean use_changed_event; - - GHashTable *cached_events; - - TrackerIndexingTree *tree; -}; - -typedef struct { - GFile *file; - gchar *file_uri; - GFile *other_file; - gchar *other_file_uri; - gboolean is_directory; - GTimeVal start_time; - guint32 event_type; - gboolean expirable; -} EventData; - -enum { - ITEM_CREATED, - ITEM_UPDATED, - ITEM_ATTRIBUTE_UPDATED, - ITEM_DELETED, - ITEM_MOVED, - LAST_SIGNAL -}; - -enum { - PROP_0, - PROP_ENABLED -}; - -static void tracker_monitor_finalize (GObject *object); -static void tracker_monitor_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void tracker_monitor_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static guint get_kqueue_limit (void); -static guint get_inotify_limit (void); -static GFileMonitor * directory_monitor_new (TrackerMonitor *monitor, - GFile *file); -static void directory_monitor_cancel (GFileMonitor *dir_monitor); - - -static void emit_signal_for_event (TrackerMonitor *monitor, - GFileMonitorEvent type, - gboolean is_directory, - GFile *file, - GFile *other_file); -static gboolean monitor_cancel_recursively (TrackerMonitor *monitor, - GFile *file); - -static guint signals[LAST_SIGNAL] = { 0, }; - -G_DEFINE_TYPE_WITH_PRIVATE (TrackerMonitor, tracker_monitor, G_TYPE_OBJECT) - -static void -tracker_monitor_class_init (TrackerMonitorClass *klass) -{ - GObjectClass *object_class; - - object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = tracker_monitor_finalize; - object_class->set_property = tracker_monitor_set_property; - object_class->get_property = tracker_monitor_get_property; - - signals[ITEM_CREATED] = - g_signal_new ("item-created", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - NULL, - G_TYPE_NONE, - 2, - G_TYPE_OBJECT, - G_TYPE_BOOLEAN); - signals[ITEM_UPDATED] = - g_signal_new ("item-updated", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - NULL, - G_TYPE_NONE, - 2, - G_TYPE_OBJECT, - G_TYPE_BOOLEAN); - signals[ITEM_ATTRIBUTE_UPDATED] = - g_signal_new ("item-attribute-updated", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - NULL, - G_TYPE_NONE, - 2, - G_TYPE_OBJECT, - G_TYPE_BOOLEAN); - signals[ITEM_DELETED] = - g_signal_new ("item-deleted", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - NULL, - G_TYPE_NONE, - 2, - G_TYPE_OBJECT, - G_TYPE_BOOLEAN); - signals[ITEM_MOVED] = - g_signal_new ("item-moved", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - NULL, - G_TYPE_NONE, - 4, - G_TYPE_OBJECT, - G_TYPE_OBJECT, - G_TYPE_BOOLEAN, - G_TYPE_BOOLEAN); - - g_object_class_install_property (object_class, - PROP_ENABLED, - g_param_spec_boolean ("enabled", - "Enabled", - "Enabled", - TRUE, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); -} - -static void -tracker_monitor_init (TrackerMonitor *object) -{ - TrackerMonitorPrivate *priv; - GFile *file; - GFileMonitor *monitor; - GError *error = NULL; - - priv = tracker_monitor_get_instance_private (object); - - /* By default we enable monitoring */ - priv->enabled = TRUE; - - /* Create monitors table for this module */ - priv->monitors = - g_hash_table_new_full (g_file_hash, - (GEqualFunc) g_file_equal, - (GDestroyNotify) g_object_unref, - (GDestroyNotify) directory_monitor_cancel); - - priv->cached_events = - g_hash_table_new_full (g_file_hash, - (GEqualFunc) g_file_equal, - g_object_unref, - NULL); - - /* For the first monitor we get the type and find out if we - * are using inotify, FAM, polling, etc. - */ - file = g_file_new_for_path (g_get_home_dir ()); - monitor = g_file_monitor_directory (file, - G_FILE_MONITOR_WATCH_MOVES, - NULL, - &error); - - if (error) { - g_critical ("Could not create sample directory monitor: %s", error->message); - g_error_free (error); - - /* Guessing limit... */ - priv->monitor_limit = 100; - } else { - GType monitor_backend; - const gchar *name; - - monitor_backend = G_OBJECT_TYPE (monitor); - - /* We use the name because the type itself is actually - * private and not available publically. Note this is - * subject to change, but unlikely of course. - */ - name = g_type_name (monitor_backend); - - /* Set limits based on backend... */ - if (strcmp (name, "GInotifyDirectoryMonitor") == 0 || - strcmp (name, "GInotifyFileMonitor") == 0) { - /* Using inotify */ - g_debug ("Monitor backend is Inotify"); - - /* Setting limit based on kernel - * settings in /proc... - */ - priv->monitor_limit = get_inotify_limit (); - - /* We don't use 100% of the monitors, we allow other - * applications to have at least 500 or so to use - * between them selves. This only - * applies to inotify because it is a - * user shared resource. - */ - priv->monitor_limit -= 500; - - /* Make sure we don't end up with a - * negative maximum. - */ - priv->monitor_limit = MAX (priv->monitor_limit, 0); - } - else if (strcmp (name, "GKqueueDirectoryMonitor") == 0 || - strcmp (name, "GKqueueFileMonitor") == 0) { - /* Using kqueue(2) */ - g_debug ("Monitor backend is kqueue"); - - priv->monitor_limit = get_kqueue_limit (); - } - else if (strcmp (name, "GFamDirectoryMonitor") == 0) { - /* Using Fam */ - g_debug ("Monitor backend is Fam"); - - /* Setting limit to an arbitary limit - * based on testing - */ - priv->monitor_limit = 400; - priv->use_changed_event = TRUE; - } - else if (strcmp (name, "GWin32DirectoryMonitor") == 0) { - /* Using Windows */ - g_debug ("Monitor backend is Windows"); - - /* Guessing limit... */ - priv->monitor_limit = 8192; - } - else { - /* Unknown */ - g_warning ("Monitor backend:'%s' is unhandled. Monitoring will be disabled", - name); - priv->enabled = FALSE; - } - - g_file_monitor_cancel (monitor); - g_object_unref (monitor); - } - - g_object_unref (file); - - if (priv->enabled) - g_debug ("Monitor limit is %d", priv->monitor_limit); -} - -static void -tracker_monitor_finalize (GObject *object) -{ - TrackerMonitorPrivate *priv; - - priv = tracker_monitor_get_instance_private (TRACKER_MONITOR (object)); - - g_hash_table_unref (priv->cached_events); - g_hash_table_unref (priv->monitors); - - G_OBJECT_CLASS (tracker_monitor_parent_class)->finalize (object); -} - -static void -tracker_monitor_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (prop_id) { - case PROP_ENABLED: - tracker_monitor_set_enabled (TRACKER_MONITOR (object), - g_value_get_boolean (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static void -tracker_monitor_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - TrackerMonitorPrivate *priv; - - priv = tracker_monitor_get_instance_private (TRACKER_MONITOR (object)); - - switch (prop_id) { - case PROP_ENABLED: - g_value_set_boolean (value, priv->enabled); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static guint -get_kqueue_limit (void) -{ - guint limit = 400; - -#ifdef TRACKER_MONITOR_KQUEUE - struct rlimit rl; - if (getrlimit (RLIMIT_NOFILE, &rl) == 0) { - rl.rlim_cur = rl.rlim_max; - } else { - return limit; - } - - if (setrlimit(RLIMIT_NOFILE, &rl) == 0) - limit = (rl.rlim_cur * 90) / 100; -#endif /* TRACKER_MONITOR_KQUEUE */ - - return limit; -} - -static guint -get_inotify_limit (void) -{ - GError *error = NULL; - const gchar *filename; - gchar *contents = NULL; - guint limit; - - filename = "/proc/sys/fs/inotify/max_user_watches"; - - if (!g_file_get_contents (filename, - &contents, - NULL, - &error)) { - g_warning ("Couldn't get INotify monitor limit from:'%s', %s", - filename, - error ? error->message : "no error given"); - g_clear_error (&error); - - /* Setting limit to an arbitary limit */ - limit = 8192; - } else { - limit = atoi (contents); - g_free (contents); - } - - return limit; -} - -static gboolean -check_is_directory (TrackerMonitor *monitor, - GFile *file) -{ - GFileType file_type; - - file_type = g_file_query_file_type (file, G_FILE_QUERY_INFO_NONE, NULL); - - if (file_type == G_FILE_TYPE_DIRECTORY) - return TRUE; - - if (file_type == G_FILE_TYPE_UNKNOWN) { - TrackerMonitorPrivate *priv; - - priv = tracker_monitor_get_instance_private (monitor); - - /* Whatever it was, it's gone. Check the monitors - * hashtable to know whether it was a directory - * we knew about - */ - if (g_hash_table_lookup (priv->monitors, file) != NULL) - return TRUE; - } - - return FALSE; -} - -gboolean -tracker_monitor_move (TrackerMonitor *monitor, - GFile *old_file, - GFile *new_file) -{ - TrackerMonitorPrivate *priv; - GHashTableIter iter; - GHashTable *new_monitors; - gchar *old_prefix; - gpointer iter_file, iter_file_monitor; - guint items_moved = 0; - - priv = tracker_monitor_get_instance_private (monitor); - - /* So this is tricky. What we have to do is: - * - * 1) Add all monitors for the new_file directory hierarchy - * 2) Then remove the monitors for old_file - * - * This order is necessary because inotify can reuse watch - * descriptors, and libinotify will remove handles - * asynchronously on IN_IGNORE, so the opposite sequence - * may possibly remove valid, just added, monitors. - */ - new_monitors = g_hash_table_new_full (g_file_hash, - (GEqualFunc) g_file_equal, - (GDestroyNotify) g_object_unref, - NULL); - old_prefix = g_file_get_path (old_file); - - /* Find out which subdirectories should have a file monitor added */ - g_hash_table_iter_init (&iter, priv->monitors); - while (g_hash_table_iter_next (&iter, &iter_file, &iter_file_monitor)) { - GFile *f; - gchar *old_path, *new_path; - gchar *new_prefix; - gchar *p; - - if (!g_file_has_prefix (iter_file, old_file) && - !g_file_equal (iter_file, old_file)) { - continue; - } - - old_path = g_file_get_path (iter_file); - p = strstr (old_path, old_prefix); - - if (!p || strcmp (p, old_prefix) == 0) { - g_free (old_path); - continue; - } - - /* Move to end of prefix */ - p += strlen (old_prefix) + 1; - - /* Check this is not the end of the string */ - if (*p == '\0') { - g_free (old_path); - continue; - } - - new_prefix = g_file_get_path (new_file); - new_path = g_build_path (G_DIR_SEPARATOR_S, new_prefix, p, NULL); - g_free (new_prefix); - - f = g_file_new_for_path (new_path); - g_free (new_path); - - if (!g_hash_table_lookup (new_monitors, f)) { - g_hash_table_insert (new_monitors, f, GINT_TO_POINTER (1)); - } else { - g_object_unref (f); - } - - g_free (old_path); - items_moved++; - } - - /* Add a new monitor for the top level directory */ - tracker_monitor_add (monitor, new_file); - - /* Add a new monitor for all subdirectories */ - g_hash_table_iter_init (&iter, new_monitors); - while (g_hash_table_iter_next (&iter, &iter_file, NULL)) { - tracker_monitor_add (monitor, iter_file); - g_hash_table_iter_remove (&iter); - } - - /* Remove the monitor for the old top level directory hierarchy */ - tracker_monitor_remove_recursively (monitor, old_file); - - g_hash_table_unref (new_monitors); - g_free (old_prefix); - - return items_moved > 0; -} - -static const gchar * -monitor_event_to_string (GFileMonitorEvent event_type) -{ - switch (event_type) { - case G_FILE_MONITOR_EVENT_CHANGED: - return "G_FILE_MONITOR_EVENT_CHANGED"; - case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT: - return "G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT"; - case G_FILE_MONITOR_EVENT_DELETED: - return "G_FILE_MONITOR_EVENT_DELETED"; - case G_FILE_MONITOR_EVENT_CREATED: - return "G_FILE_MONITOR_EVENT_CREATED"; - case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED: - return "G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED"; - case G_FILE_MONITOR_EVENT_PRE_UNMOUNT: - return "G_FILE_MONITOR_EVENT_PRE_UNMOUNT"; - case G_FILE_MONITOR_EVENT_UNMOUNTED: - return "G_FILE_MONITOR_EVENT_UNMOUNTED"; - case G_FILE_MONITOR_EVENT_MOVED: - return "G_FILE_MONITOR_EVENT_MOVED"; - case G_FILE_MONITOR_EVENT_RENAMED: - return "G_FILE_MONITOR_EVENT_RENAMED"; - case G_FILE_MONITOR_EVENT_MOVED_IN: - return "G_FILE_MONITOR_EVENT_MOVED_IN"; - case G_FILE_MONITOR_EVENT_MOVED_OUT: - return "G_FILE_MONITOR_EVENT_MOVED_OUT"; - break; - } - - return "unknown"; -} - -static void -emit_signal_for_event (TrackerMonitor *monitor, - GFileMonitorEvent type, - gboolean is_directory, - GFile *file, - GFile *other_file) -{ - /* Note that in any case we should be moving the monitors - * here to the new place, as the new place may be ignored. - * We should leave this to the upper layers. But one thing - * we must do is actually CANCEL all these monitors. */ - if (is_directory && - (type == G_FILE_MONITOR_EVENT_MOVED || - type == G_FILE_MONITOR_EVENT_DELETED)) { - monitor_cancel_recursively (monitor, file); - } - - switch (type) { - case G_FILE_MONITOR_EVENT_CREATED: - g_signal_emit (monitor, - signals[ITEM_CREATED], 0, - file, is_directory); - break; - case G_FILE_MONITOR_EVENT_CHANGED: - g_signal_emit (monitor, - signals[ITEM_UPDATED], 0, - file, is_directory); - break; - case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED: - g_signal_emit (monitor, - signals[ITEM_ATTRIBUTE_UPDATED], 0, - file, is_directory); - break; - case G_FILE_MONITOR_EVENT_DELETED: - g_signal_emit (monitor, - signals[ITEM_DELETED], 0, - file, is_directory); - break; - case G_FILE_MONITOR_EVENT_MOVED: - g_signal_emit (monitor, - signals[ITEM_MOVED], 0, - file, other_file, is_directory, TRUE); - break; - default: - g_warning ("Trying to emit monitor signal with unhandled event %d", - type); - break; - } -} - -static void -flush_cached_event (TrackerMonitor *monitor, - GFile *file, - gboolean is_directory) -{ - gpointer value = NULL; - TrackerMonitorPrivate *priv; - - priv = tracker_monitor_get_instance_private (monitor); - - if (g_hash_table_lookup_extended (priv->cached_events, - file, NULL, &value)) { - GFileMonitorEvent prev_event_type = GPOINTER_TO_UINT (value); - - g_hash_table_remove (priv->cached_events, file); - emit_signal_for_event (monitor, prev_event_type, - is_directory, file, NULL); - } -} - -static void -cache_event (TrackerMonitor *monitor, - GFile *file, - GFileMonitorEvent event_type) -{ - TrackerMonitorPrivate *priv; - - priv = tracker_monitor_get_instance_private (monitor); - - if (g_hash_table_lookup_extended (priv->cached_events, file, - NULL, NULL)) - return; - - g_hash_table_insert (priv->cached_events, - g_object_ref (file), - GUINT_TO_POINTER (event_type)); -} - -static void -monitor_event_cb (GFileMonitor *file_monitor, - GFile *file, - GFile *other_file, - GFileMonitorEvent event_type, - gpointer user_data) -{ - TrackerMonitor *monitor; - gchar *file_uri; - gchar *other_file_uri; - gboolean is_directory = FALSE; - TrackerMonitorPrivate *priv; - gpointer value; - - monitor = user_data; - priv = tracker_monitor_get_instance_private (monitor); - - if (G_UNLIKELY (!priv->enabled)) { - g_debug ("Silently dropping monitor event, monitor disabled for now"); - return; - } - - /* Get URIs as paths may not be in UTF-8 */ - file_uri = g_file_get_uri (file); - - if (!other_file) { - is_directory = check_is_directory (monitor, file); - - other_file_uri = NULL; - g_debug ("Received monitor event:%d (%s) for %s:'%s'", - event_type, - monitor_event_to_string (event_type), - is_directory ? "directory" : "file", - file_uri); - } else { - if (event_type == G_FILE_MONITOR_EVENT_RENAMED || - event_type == G_FILE_MONITOR_EVENT_MOVED_OUT) { - is_directory = check_is_directory (monitor, other_file); - } else if (event_type == G_FILE_MONITOR_EVENT_MOVED_IN) { - is_directory = check_is_directory (monitor, file); - } - - other_file_uri = g_file_get_uri (other_file); - g_debug ("Received monitor event:%d (%s) for files '%s'->'%s'", - event_type, - monitor_event_to_string (event_type), - file_uri, - other_file_uri); - } - - switch (event_type) { - case G_FILE_MONITOR_EVENT_CREATED: - case G_FILE_MONITOR_EVENT_CHANGED: - if (!priv->use_changed_event) { - cache_event (monitor, file, event_type); - } else { - emit_signal_for_event (monitor, event_type, - is_directory, file, NULL); - } - break; - case G_FILE_MONITOR_EVENT_DELETED: - if (g_hash_table_lookup_extended (priv->cached_events, - file, NULL, &value) && - GPOINTER_TO_UINT (value) == G_FILE_MONITOR_EVENT_CREATED) { - /* Consume both the cached CREATED event and this one */ - g_hash_table_remove (priv->cached_events, file); - break; - } - - /* In any case, cached events are stale */ - g_hash_table_remove (priv->cached_events, file); - - /* Fall through */ - case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED: - emit_signal_for_event (monitor, event_type, - is_directory, file, NULL); - break; - case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT: - flush_cached_event (monitor, file, is_directory); - break; - case G_FILE_MONITOR_EVENT_MOVED_IN: - if (other_file) { - /* Both MOVED_IN and MOVE_OUT are fine points to emit - * ::item-moved when source/dest are known. We choose - * to emit it here, and ignore the MOVE_OUT. - */ - emit_signal_for_event (monitor, - G_FILE_MONITOR_EVENT_MOVED, - is_directory, - other_file, file); - } else { - /* No known origin, treat as a new file */ - emit_signal_for_event (monitor, - G_FILE_MONITOR_EVENT_CREATED, - is_directory, - file, NULL); - } - break; - case G_FILE_MONITOR_EVENT_MOVED_OUT: - if (!other_file) { - /* No known destination. Treat as remove */ - emit_signal_for_event (monitor, - G_FILE_MONITOR_EVENT_DELETED, - is_directory, - file, NULL); - } - break; - case G_FILE_MONITOR_EVENT_RENAMED: - emit_signal_for_event (monitor, - G_FILE_MONITOR_EVENT_MOVED, - is_directory, file, other_file); - break; - case G_FILE_MONITOR_EVENT_MOVED: - g_warn_if_reached (); - break; - case G_FILE_MONITOR_EVENT_PRE_UNMOUNT: - case G_FILE_MONITOR_EVENT_UNMOUNTED: - break; - } - - g_free (file_uri); - g_free (other_file_uri); -} - -static GFileMonitor * -directory_monitor_new (TrackerMonitor *monitor, - GFile *file) -{ - GFileMonitor *file_monitor; - GError *error = NULL; - - file_monitor = g_file_monitor_directory (file, - G_FILE_MONITOR_WATCH_MOVES, - NULL, - &error); - - if (error) { - gchar *uri; - - uri = g_file_get_uri (file); - g_warning ("Could not add monitor for path:'%s', %s", - uri, error->message); - - g_error_free (error); - g_free (uri); - - return NULL; - } - - g_signal_connect (file_monitor, "changed", - G_CALLBACK (monitor_event_cb), - monitor); - - return file_monitor; -} - -static void -directory_monitor_cancel (GFileMonitor *monitor) -{ - if (monitor) { - g_file_monitor_cancel (G_FILE_MONITOR (monitor)); - g_object_unref (monitor); - } -} - -TrackerMonitor * -tracker_monitor_new (void) -{ - return g_object_new (TRACKER_TYPE_MONITOR, NULL); -} - -gboolean -tracker_monitor_get_enabled (TrackerMonitor *monitor) -{ - TrackerMonitorPrivate *priv; - - g_return_val_if_fail (TRACKER_IS_MONITOR (monitor), FALSE); - - priv = tracker_monitor_get_instance_private (monitor); - - return priv->enabled; -} - -void -tracker_monitor_set_enabled (TrackerMonitor *monitor, - gboolean enabled) -{ - TrackerMonitorPrivate *priv; - GList *keys, *k; - - g_return_if_fail (TRACKER_IS_MONITOR (monitor)); - - priv = tracker_monitor_get_instance_private (monitor); - - /* Don't replace all monitors if we are already - * enabled/disabled. - */ - if (priv->enabled == enabled) { - return; - } - - priv->enabled = enabled; - g_object_notify (G_OBJECT (monitor), "enabled"); - - keys = g_hash_table_get_keys (priv->monitors); - - /* Update state on all monitored dirs */ - for (k = keys; k != NULL; k = k->next) { - GFile *file; - - file = k->data; - - if (enabled) { - GFileMonitor *dir_monitor; - - dir_monitor = directory_monitor_new (monitor, file); - g_hash_table_replace (priv->monitors, - g_object_ref (file), dir_monitor); - } else { - /* Remove monitor */ - g_hash_table_replace (priv->monitors, - g_object_ref (file), NULL); - } - } - - g_list_free (keys); -} - -gboolean -tracker_monitor_add (TrackerMonitor *monitor, - GFile *file) -{ - TrackerMonitorPrivate *priv; - GFileMonitor *dir_monitor = NULL; - gchar *uri; - - g_return_val_if_fail (TRACKER_IS_MONITOR (monitor), FALSE); - g_return_val_if_fail (G_IS_FILE (file), FALSE); - - priv = tracker_monitor_get_instance_private (monitor); - - if (g_hash_table_lookup (priv->monitors, file)) { - return TRUE; - } - - /* Cap the number of monitors */ - if (g_hash_table_size (priv->monitors) >= priv->monitor_limit) { - priv->monitors_ignored++; - - if (!priv->monitor_limit_warned) { - g_warning ("The maximum number of monitors to set (%d) " - "has been reached, not adding any new ones", - priv->monitor_limit); - priv->monitor_limit_warned = TRUE; - } - - return FALSE; - } - - uri = g_file_get_uri (file); - - if (priv->enabled) { - /* We don't check if a file exists or not since we might want - * to monitor locations which don't exist yet. - * - * Also, we assume ALL paths passed are directories. - */ - dir_monitor = directory_monitor_new (monitor, file); - - if (!dir_monitor) { - g_warning ("Could not add monitor for path:'%s'", - uri); - g_free (uri); - return FALSE; - } - } - - /* NOTE: it is ok to add a NULL file_monitor, when our - * enabled/disabled state changes, we iterate all keys and - * add or remove monitors. - */ - g_hash_table_insert (priv->monitors, - g_object_ref (file), - dir_monitor); - - g_debug ("Added monitor for path:'%s', total monitors:%d", - uri, - g_hash_table_size (priv->monitors)); - - g_free (uri); - - return TRUE; -} - -gboolean -tracker_monitor_remove (TrackerMonitor *monitor, - GFile *file) -{ - TrackerMonitorPrivate *priv; - gboolean removed; - - g_return_val_if_fail (TRACKER_IS_MONITOR (monitor), FALSE); - g_return_val_if_fail (G_IS_FILE (file), FALSE); - - priv = tracker_monitor_get_instance_private (monitor); - removed = g_hash_table_remove (priv->monitors, file); - - if (removed) { - gchar *uri; - - uri = g_file_get_uri (file); - g_debug ("Removed monitor for path:'%s', total monitors:%d", - uri, - g_hash_table_size (priv->monitors)); - - g_free (uri); - } - - return removed; -} - -/* If @is_strict is %TRUE, return %TRUE iff @file is a child of @prefix. - * If @is_strict is %FALSE, additionally return %TRUE if @file equals @prefix. - */ -static gboolean -file_has_maybe_strict_prefix (GFile *file, - GFile *prefix, - gboolean is_strict) -{ - return (g_file_has_prefix (file, prefix) || - (!is_strict && g_file_equal (file, prefix))); -} - -static gboolean -remove_recursively (TrackerMonitor *monitor, - GFile *file, - gboolean remove_top_level) -{ - TrackerMonitorPrivate *priv; - GHashTableIter iter; - gpointer iter_file, iter_file_monitor; - guint items_removed = 0; - gchar *uri; - - g_return_val_if_fail (TRACKER_IS_MONITOR (monitor), FALSE); - g_return_val_if_fail (G_IS_FILE (file), FALSE); - - priv = tracker_monitor_get_instance_private (monitor); - - g_hash_table_iter_init (&iter, priv->monitors); - while (g_hash_table_iter_next (&iter, &iter_file, &iter_file_monitor)) { - if (!file_has_maybe_strict_prefix (iter_file, file, - !remove_top_level)) { - continue; - } - - g_hash_table_iter_remove (&iter); - items_removed++; - } - - uri = g_file_get_uri (file); - g_debug ("Removed all monitors %srecursively for path:'%s', " - "total monitors:%d", - !remove_top_level ? "(except top level) " : "", - uri, g_hash_table_size (priv->monitors)); - g_free (uri); - - if (items_removed > 0) { - /* We reset this because now it is possible we have limit - 1 */ - priv->monitor_limit_warned = FALSE; - return TRUE; - } - - return FALSE; -} - -gboolean -tracker_monitor_remove_recursively (TrackerMonitor *monitor, - GFile *file) -{ - return remove_recursively (monitor, file, TRUE); -} - -gboolean -tracker_monitor_remove_children_recursively (TrackerMonitor *monitor, - GFile *file) -{ - return remove_recursively (monitor, file, FALSE); -} - -static gboolean -monitor_cancel_recursively (TrackerMonitor *monitor, - GFile *file) -{ - TrackerMonitorPrivate *priv; - GHashTableIter iter; - gpointer iter_file, iter_file_monitor; - guint items_cancelled = 0; - - priv = tracker_monitor_get_instance_private (monitor); - - g_hash_table_iter_init (&iter, priv->monitors); - while (g_hash_table_iter_next (&iter, &iter_file, &iter_file_monitor)) { - gchar *uri; - - if (!g_file_has_prefix (iter_file, file) && - !g_file_equal (iter_file, file)) { - continue; - } - - uri = g_file_get_uri (iter_file); - g_file_monitor_cancel (G_FILE_MONITOR (iter_file_monitor)); - g_debug ("Cancelled monitor for path:'%s'", uri); - g_free (uri); - - items_cancelled++; - } - - return items_cancelled > 0; -} - -gboolean -tracker_monitor_is_watched (TrackerMonitor *monitor, - GFile *file) -{ - TrackerMonitorPrivate *priv; - - g_return_val_if_fail (TRACKER_IS_MONITOR (monitor), FALSE); - g_return_val_if_fail (G_IS_FILE (file), FALSE); - - priv = tracker_monitor_get_instance_private (monitor); - - return g_hash_table_lookup (priv->monitors, file) != NULL; -} - -gboolean -tracker_monitor_is_watched_by_string (TrackerMonitor *monitor, - const gchar *path) -{ - TrackerMonitorPrivate *priv; - GFile *file; - gboolean watched; - - g_return_val_if_fail (TRACKER_IS_MONITOR (monitor), FALSE); - g_return_val_if_fail (path != NULL, FALSE); - - priv = tracker_monitor_get_instance_private (monitor); - - file = g_file_new_for_path (path); - watched = g_hash_table_lookup (priv->monitors, file) != NULL; - g_object_unref (file); - - return watched; -} - -guint -tracker_monitor_get_count (TrackerMonitor *monitor) -{ - TrackerMonitorPrivate *priv; - - g_return_val_if_fail (TRACKER_IS_MONITOR (monitor), 0); - - priv = tracker_monitor_get_instance_private (monitor); - - return g_hash_table_size (priv->monitors); -} - -guint -tracker_monitor_get_ignored (TrackerMonitor *monitor) -{ - TrackerMonitorPrivate *priv; - - g_return_val_if_fail (TRACKER_IS_MONITOR (monitor), 0); - - priv = tracker_monitor_get_instance_private (monitor); - - return priv->monitors_ignored; -} - -guint -tracker_monitor_get_limit (TrackerMonitor *monitor) -{ - TrackerMonitorPrivate *priv; - - g_return_val_if_fail (TRACKER_IS_MONITOR (monitor), 0); - - priv = tracker_monitor_get_instance_private (monitor); - - return priv->monitor_limit; -} diff --git a/src/libtracker-miner/tracker-monitor.h b/src/libtracker-miner/tracker-monitor.h deleted file mode 100644 index c65427379..000000000 --- a/src/libtracker-miner/tracker-monitor.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2009, Nokia <ivan.frade@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __LIBTRACKER_MINER_MONITOR_H__ -#define __LIBTRACKER_MINER_MONITOR_H__ - -#if !defined (__LIBTRACKER_MINER_H_INSIDE__) && !defined (TRACKER_COMPILATION) -#error "Only <libtracker-miner/tracker-miner.h> can be included directly." -#endif - -#include <glib-object.h> -#include <gio/gio.h> -#include "tracker-indexing-tree.h" - -G_BEGIN_DECLS - -#define TRACKER_TYPE_MONITOR (tracker_monitor_get_type ()) -#define TRACKER_MONITOR(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), TRACKER_TYPE_MONITOR, TrackerMonitor)) -#define TRACKER_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TRACKER_TYPE_MONITOR, TrackerMonitorClass)) -#define TRACKER_IS_MONITOR(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), TRACKER_TYPE_MONITOR)) -#define TRACKER_IS_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TRACKER_TYPE_MONITOR)) -#define TRACKER_MONITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TRACKER_TYPE_MONITOR, TrackerMonitorClass)) - -typedef struct TrackerMonitor TrackerMonitor; -typedef struct TrackerMonitorClass TrackerMonitorClass; - -struct TrackerMonitor { - GObject parent; -}; - -struct TrackerMonitorClass { - GObjectClass parent; -}; - -GType tracker_monitor_get_type (void); -TrackerMonitor *tracker_monitor_new (void); - -TrackerIndexingTree * tracker_monitor_get_indexing_tree (TrackerMonitor *monitor); -void tracker_monitor_set_indexing_tree (TrackerMonitor *monitor, - TrackerIndexingTree *tree); - -gboolean tracker_monitor_get_enabled (TrackerMonitor *monitor); -void tracker_monitor_set_enabled (TrackerMonitor *monitor, - gboolean enabled); -gboolean tracker_monitor_add (TrackerMonitor *monitor, - GFile *file); -gboolean tracker_monitor_remove (TrackerMonitor *monitor, - GFile *file); -gboolean tracker_monitor_remove_recursively (TrackerMonitor *monitor, - GFile *file); -gboolean tracker_monitor_remove_children_recursively (TrackerMonitor *monitor, - GFile *file); -gboolean tracker_monitor_move (TrackerMonitor *monitor, - GFile *old_file, - GFile *new_file); -gboolean tracker_monitor_is_watched (TrackerMonitor *monitor, - GFile *file); -gboolean tracker_monitor_is_watched_by_string (TrackerMonitor *monitor, - const gchar *path); -guint tracker_monitor_get_count (TrackerMonitor *monitor); -guint tracker_monitor_get_ignored (TrackerMonitor *monitor); -guint tracker_monitor_get_limit (TrackerMonitor *monitor); - -G_END_DECLS - -#endif /* __LIBTRACKER_MINER_MONITOR_H__ */ diff --git a/src/libtracker-miner/tracker-priority-queue.c b/src/libtracker-miner/tracker-priority-queue.c deleted file mode 100644 index 85190cd31..000000000 --- a/src/libtracker-miner/tracker-priority-queue.c +++ /dev/null @@ -1,455 +0,0 @@ -/* - * Copyright (C) 2011, Nokia <ivan.frade@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Author: Carlos Garnacho <carlos@lanedo.com> - */ - -#include "config.h" - -#include "tracker-priority-queue.h" - -typedef struct PrioritySegment PrioritySegment; - -struct PrioritySegment -{ - gint priority; - GList *first_elem; - GList *last_elem; -}; - -struct _TrackerPriorityQueue -{ - GQueue queue; - GArray *segments; - - gint ref_count; -}; - -TrackerPriorityQueue * -tracker_priority_queue_new (void) -{ - TrackerPriorityQueue *queue; - - queue = g_slice_new (TrackerPriorityQueue); - g_queue_init (&queue->queue); - queue->segments = g_array_new (FALSE, FALSE, - sizeof (PrioritySegment)); - - queue->ref_count = 1; - - return queue; -} - -TrackerPriorityQueue * -tracker_priority_queue_ref (TrackerPriorityQueue *queue) -{ - g_atomic_int_inc (&queue->ref_count); - return queue; -} - -void -tracker_priority_queue_unref (TrackerPriorityQueue *queue) -{ - if (g_atomic_int_dec_and_test (&queue->ref_count)) { - g_queue_clear (&queue->queue); - g_array_free (queue->segments, TRUE); - g_slice_free (TrackerPriorityQueue, queue); - } -} - -static void -queue_insert_before_link (GQueue *queue, - GList *sibling, - GList *link_) -{ - if (sibling == queue->head) - g_queue_push_head_link (queue, link_); - else { - link_->next = sibling; - link_->prev = sibling->prev; - sibling->prev->next = link_; - sibling->prev = link_; - queue->length++; - } -} - -static void -queue_insert_after_link (GQueue *queue, - GList *sibling, - GList *link_) -{ - if (sibling == queue->tail) - g_queue_push_tail_link (queue, link_); - else - queue_insert_before_link (queue, sibling->next, link_); -} - -static void -insert_node (TrackerPriorityQueue *queue, - gint priority, - GList *node) -{ - PrioritySegment *segment = NULL; - gboolean found = FALSE; - gint l, r, c; - - /* Perform binary search to find out the segment for - * the given priority, create one if it isn't found. - */ - l = 0; - r = queue->segments->len - 1; - - while (queue->segments->len > 0 && !found) { - c = (r + l) / 2; - segment = &g_array_index (queue->segments, PrioritySegment, c); - - if (segment->priority == priority) { - found = TRUE; - break; - } else if (segment->priority > priority) { - r = c - 1; - } else if (segment->priority < priority) { - l = c + 1; - } - - if (l > r) { - break; - } - } - - if (found) { - /* Element found, append at the end of segment */ - g_assert (segment != NULL); - g_assert (segment->priority == priority); - - queue_insert_after_link (&queue->queue, segment->last_elem, node); - segment->last_elem = node; - } else { - PrioritySegment new_segment = { 0 }; - - new_segment.priority = priority; - - if (segment) { - g_assert (segment->priority != priority); - - /* Binary search got to one of the closest results, - * but we may have come from either of both sides, - * so check whether we have to insert after the - * segment we got. - */ - if (segment->priority > priority) { - /* We have to insert to the left of this element */ - queue_insert_before_link (&queue->queue, segment->first_elem, node); - } else { - /* We have to insert to the right of this element */ - queue_insert_after_link (&queue->queue, segment->last_elem, node); - c++; - } - - new_segment.first_elem = new_segment.last_elem = node; - g_array_insert_val (queue->segments, c, new_segment); - } else { - /* Segments list has 0 elements */ - g_assert (queue->segments->len == 0); - g_assert (g_queue_get_length (&queue->queue) == 0); - - g_queue_push_head_link (&queue->queue, node); - new_segment.first_elem = new_segment.last_elem = node; - - g_array_append_val (queue->segments, new_segment); - } - } -} - -void -tracker_priority_queue_foreach (TrackerPriorityQueue *queue, - GFunc func, - gpointer user_data) -{ - g_return_if_fail (queue != NULL); - g_return_if_fail (func != NULL); - - g_queue_foreach (&queue->queue, func, user_data); -} - -gboolean -tracker_priority_queue_foreach_remove (TrackerPriorityQueue *queue, - GEqualFunc compare_func, - gpointer compare_user_data, - GDestroyNotify destroy_notify) -{ - PrioritySegment *segment; - gint n_segment = 0; - gboolean updated = FALSE; - GList *list; - - g_return_val_if_fail (queue != NULL, FALSE); - g_return_val_if_fail (compare_func != NULL, FALSE); - - list = queue->queue.head; - - if (!list) { - return FALSE; - } - - segment = &g_array_index (queue->segments, PrioritySegment, n_segment); - - while (list) { - gboolean fetch_segment = FALSE; - GList *elem; - - elem = list; - list = list->next; - - if ((compare_func) (elem->data, compare_user_data)) { - /* Update segment limits */ - if (elem == segment->first_elem && - elem == segment->last_elem) { - /* Last element of segment, remove it */ - g_array_remove_index (queue->segments, - n_segment); - fetch_segment = TRUE; - } else if (elem == segment->first_elem) { - /* First elemen in segment */ - segment->first_elem = elem->next; - } else if (elem == segment->last_elem) { - segment->last_elem = elem->prev; - n_segment++; - fetch_segment = TRUE; - } - - if (destroy_notify) { - (destroy_notify) (elem->data); - } - - g_queue_delete_link (&queue->queue, elem); - updated = TRUE; - } else { - if (list != NULL && - elem == segment->last_elem) { - /* Move on to the next segment */ - n_segment++; - fetch_segment = TRUE; - } - } - - if (list && fetch_segment) { - /* Fetch the next segment */ - g_assert (n_segment < queue->segments->len); - segment = &g_array_index (queue->segments, - PrioritySegment, - n_segment); - } - } - - return updated; -} - -gboolean -tracker_priority_queue_is_empty (TrackerPriorityQueue *queue) -{ - g_return_val_if_fail (queue != NULL, FALSE); - - return g_queue_is_empty (&queue->queue); -} - -guint -tracker_priority_queue_get_length (TrackerPriorityQueue *queue) -{ - g_return_val_if_fail (queue != NULL, 0); - - return g_queue_get_length (&queue->queue); -} - -GList * -tracker_priority_queue_add (TrackerPriorityQueue *queue, - gpointer data, - gint priority) -{ - GList *node; - - g_return_val_if_fail (queue != NULL, NULL); - g_return_val_if_fail (data != NULL, NULL); - - node = g_list_alloc (); - node->data = data; - insert_node (queue, priority, node); - - return node; -} - -void -tracker_priority_queue_add_node (TrackerPriorityQueue *queue, - GList *node, - gint priority) -{ - g_return_if_fail (queue != NULL); - g_return_if_fail (node != NULL); - - insert_node (queue, priority, node); -} - -void -tracker_priority_queue_remove_node (TrackerPriorityQueue *queue, - GList *node) -{ - guint i; - - g_return_if_fail (queue != NULL); - - /* Check if it is the first or last of a segment */ - for (i = 0; i < queue->segments->len; i++) { - PrioritySegment *segment; - - segment = &g_array_index (queue->segments, PrioritySegment, i); - - if (segment->first_elem == node) { - if (segment->last_elem == node) - g_array_remove_index (queue->segments, i); - else - segment->first_elem = node->next; - break; - } - - if (segment->last_elem == node) { - segment->last_elem = node->prev; - break; - } - } - - g_queue_delete_link (&queue->queue, node); -} - -gpointer -tracker_priority_queue_find (TrackerPriorityQueue *queue, - gint *priority_out, - GEqualFunc compare_func, - gpointer user_data) -{ - PrioritySegment *segment; - gint n_segment = 0; - GList *list; - - g_return_val_if_fail (queue != NULL, NULL); - g_return_val_if_fail (compare_func != NULL, NULL); - - list = queue->queue.head; - segment = &g_array_index (queue->segments, PrioritySegment, n_segment); - - while (list) { - if ((compare_func) (list->data, user_data)) { - if (priority_out) { - *priority_out = segment->priority; - } - - return list->data; - } - - if (list->next != NULL && - list == segment->last_elem) { - /* Move on to the next segment */ - n_segment++; - g_assert (n_segment < queue->segments->len); - segment = &g_array_index (queue->segments, - PrioritySegment, - n_segment); - } - - list = list->next; - } - - return NULL; -} - -gpointer -tracker_priority_queue_peek (TrackerPriorityQueue *queue, - gint *priority_out) -{ - g_return_val_if_fail (queue != NULL, NULL); - - if (priority_out && queue->segments->len > 0) { - PrioritySegment *segment; - - segment = &g_array_index (queue->segments, PrioritySegment, 0); - *priority_out = segment->priority; - } - - return g_queue_peek_head (&queue->queue); -} - -gpointer -tracker_priority_queue_pop (TrackerPriorityQueue *queue, - gint *priority_out) -{ - GList *node; - gpointer data; - - node = tracker_priority_queue_pop_node (queue, priority_out); - if (node == NULL) - return NULL; - - data = node->data; - g_list_free_1 (node); - - return data; -} - -GList * -tracker_priority_queue_pop_node (TrackerPriorityQueue *queue, - gint *priority_out) -{ - PrioritySegment *segment; - GList *node; - - g_return_val_if_fail (queue != NULL, NULL); - - node = g_queue_peek_head_link (&queue->queue); - - if (!node) { - /* No elements in queue */ - return NULL; - } - - segment = &g_array_index (queue->segments, PrioritySegment, 0); - g_assert (segment->first_elem == node); - - if (priority_out) { - *priority_out = segment->priority; - } - - if (segment->last_elem == node) { - /* It is the last element of the first - * segment, remove segment as well. - */ - g_array_remove_index (queue->segments, 0); - } else { - - /* Move segments first element forward */ - segment->first_elem = segment->first_elem->next; - } - - return g_queue_pop_head_link (&queue->queue); -} - -GList * -tracker_priority_queue_get_head (TrackerPriorityQueue *queue) -{ - g_return_val_if_fail (queue != NULL, NULL); - - return queue->queue.head; -} diff --git a/src/libtracker-miner/tracker-priority-queue.h b/src/libtracker-miner/tracker-priority-queue.h deleted file mode 100644 index 0dbc9b83d..000000000 --- a/src/libtracker-miner/tracker-priority-queue.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2011, Nokia <ivan.frade@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Author: Carlos Garnacho <carlos@lanedo.com> - */ - -#ifndef __LIBTRACKER_MINER_PRIORITY_QUEUE_H__ -#define __LIBTRACKER_MINER_PRIORITY_QUEUE_H__ - -#include <glib.h> - -G_BEGIN_DECLS - -typedef struct _TrackerPriorityQueue TrackerPriorityQueue; - -TrackerPriorityQueue *tracker_priority_queue_new (void); - -TrackerPriorityQueue *tracker_priority_queue_ref (TrackerPriorityQueue *queue); -void tracker_priority_queue_unref (TrackerPriorityQueue *queue); - -gboolean tracker_priority_queue_is_empty (TrackerPriorityQueue *queue); - -guint tracker_priority_queue_get_length (TrackerPriorityQueue *queue); - -GList * tracker_priority_queue_add (TrackerPriorityQueue *queue, - gpointer data, - gint priority); -void tracker_priority_queue_foreach (TrackerPriorityQueue *queue, - GFunc func, - gpointer user_data); - -gboolean tracker_priority_queue_foreach_remove (TrackerPriorityQueue *queue, - GEqualFunc compare_func, - gpointer compare_user_data, - GDestroyNotify destroy_notify); - -gpointer tracker_priority_queue_find (TrackerPriorityQueue *queue, - gint *priority_out, - GEqualFunc compare_func, - gpointer data); - -gpointer tracker_priority_queue_peek (TrackerPriorityQueue *queue, - gint *priority_out); -gpointer tracker_priority_queue_pop (TrackerPriorityQueue *queue, - gint *priority_out); - -GList * tracker_priority_queue_get_head (TrackerPriorityQueue *queue); -void tracker_priority_queue_add_node (TrackerPriorityQueue *queue, - GList *node, - gint priority); -void tracker_priority_queue_remove_node (TrackerPriorityQueue *queue, - GList *node); -GList * tracker_priority_queue_pop_node (TrackerPriorityQueue *queue, - gint *priority_out); - - -G_END_DECLS - -#endif /* __LIBTRACKER_TRACKER_PRIORITY_QUEUE_H__ */ diff --git a/src/libtracker-miner/tracker-sparql-buffer.c b/src/libtracker-miner/tracker-sparql-buffer.c deleted file mode 100644 index 997d4265e..000000000 --- a/src/libtracker-miner/tracker-sparql-buffer.c +++ /dev/null @@ -1,547 +0,0 @@ -/* - * Copyright (C) 2011, Nokia <ivan.frade@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Author: Carlos Garnacho <carlos@lanedo.com> - */ - -#include "config.h" - -#include <libtracker-sparql/tracker-sparql.h> - -#include "tracker-sparql-buffer.h" - -/* Maximum time (seconds) before forcing a sparql buffer flush */ -#define MAX_SPARQL_BUFFER_TIME 15 - -typedef struct _TrackerSparqlBufferPrivate TrackerSparqlBufferPrivate; -typedef struct _SparqlTaskData SparqlTaskData; -typedef struct _UpdateArrayData UpdateArrayData; -typedef struct _UpdateData UpdateData; - -enum { - PROP_0, - PROP_CONNECTION -}; - -struct _TrackerSparqlBufferPrivate -{ - TrackerSparqlConnection *connection; - guint flush_timeout_id; - GPtrArray *tasks; - gint n_updates; -}; - -struct _SparqlTaskData -{ - gchar *str; - GTask *async_task; -}; - -struct _UpdateData { - TrackerSparqlBuffer *buffer; - TrackerTask *task; -}; - -struct _UpdateArrayData { - TrackerSparqlBuffer *buffer; - GPtrArray *tasks; - GArray *sparql_array; -}; - -G_DEFINE_TYPE_WITH_PRIVATE (TrackerSparqlBuffer, tracker_sparql_buffer, TRACKER_TYPE_TASK_POOL) - -static void -tracker_sparql_buffer_finalize (GObject *object) -{ - TrackerSparqlBufferPrivate *priv; - - priv = tracker_sparql_buffer_get_instance_private (TRACKER_SPARQL_BUFFER (object)); - - g_object_unref (priv->connection); - - if (priv->flush_timeout_id != 0) { - g_source_remove (priv->flush_timeout_id); - } - - G_OBJECT_CLASS (tracker_sparql_buffer_parent_class)->finalize (object); -} - -static void -tracker_sparql_buffer_set_property (GObject *object, - guint param_id, - const GValue *value, - GParamSpec *pspec) -{ - TrackerSparqlBufferPrivate *priv; - - priv = tracker_sparql_buffer_get_instance_private (TRACKER_SPARQL_BUFFER (object)); - - switch (param_id) { - case PROP_CONNECTION: - priv->connection = g_value_dup_object (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); - break; - } -} - -static void -tracker_sparql_buffer_get_property (GObject *object, - guint param_id, - GValue *value, - GParamSpec *pspec) -{ - TrackerSparqlBufferPrivate *priv; - - priv = tracker_sparql_buffer_get_instance_private (TRACKER_SPARQL_BUFFER (object)); - - switch (param_id) { - case PROP_CONNECTION: - g_value_set_object (value, - priv->connection); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); - break; - } -} - -static void -tracker_sparql_buffer_class_init (TrackerSparqlBufferClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = tracker_sparql_buffer_finalize; - object_class->set_property = tracker_sparql_buffer_set_property; - object_class->get_property = tracker_sparql_buffer_get_property; - - g_object_class_install_property (object_class, - PROP_CONNECTION, - g_param_spec_object ("connection", - "sparql connection", - "Sparql Connection", - TRACKER_SPARQL_TYPE_CONNECTION, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); -} - -static gboolean -flush_timeout_cb (gpointer user_data) -{ - TrackerSparqlBuffer *buffer = user_data; - TrackerSparqlBufferPrivate *priv; - - priv = tracker_sparql_buffer_get_instance_private (buffer); - tracker_sparql_buffer_flush (buffer, "Buffer time reached"); - priv->flush_timeout_id = 0; - - return FALSE; -} - -static void -reset_flush_timeout (TrackerSparqlBuffer *buffer) -{ - TrackerSparqlBufferPrivate *priv; - - priv = tracker_sparql_buffer_get_instance_private (buffer); - - if (priv->flush_timeout_id != 0) { - g_source_remove (priv->flush_timeout_id); - } - - priv->flush_timeout_id = g_timeout_add_seconds (MAX_SPARQL_BUFFER_TIME, - flush_timeout_cb, - buffer); -} - -static void -tracker_sparql_buffer_init (TrackerSparqlBuffer *buffer) -{ -} - -TrackerSparqlBuffer * -tracker_sparql_buffer_new (TrackerSparqlConnection *connection, - guint limit) -{ - return g_object_new (TRACKER_TYPE_SPARQL_BUFFER, - "connection", connection, - "limit", limit, - NULL); -} - -static void -remove_task_foreach (TrackerTask *task, - TrackerTaskPool *pool) -{ - tracker_task_pool_remove (pool, task); -} - -static void -update_array_data_free (UpdateArrayData *update_data) -{ - if (!update_data) - return; - - if (update_data->sparql_array) { - /* The array contains pointers to strings in the tasks, so no need to - * deallocate its pointed contents, just the array itself. */ - g_array_free (update_data->sparql_array, TRUE); - } - - g_ptr_array_foreach (update_data->tasks, - (GFunc) remove_task_foreach, - update_data->buffer); - g_ptr_array_free (update_data->tasks, TRUE); - - g_slice_free (UpdateArrayData, update_data); -} - -static void -tracker_sparql_buffer_update_array_cb (GObject *object, - GAsyncResult *result, - gpointer user_data) -{ - TrackerSparqlBufferPrivate *priv; - TrackerSparqlBuffer *buffer; - GError *global_error = NULL; - GPtrArray *sparql_array_errors; - UpdateArrayData *update_data; - gint i; - - /* Get arrays of errors and queries */ - update_data = user_data; - buffer = TRACKER_SPARQL_BUFFER (update_data->buffer); - priv = tracker_sparql_buffer_get_instance_private (buffer); - priv->n_updates--; - - g_debug ("(Sparql buffer) Finished array-update with %u tasks", - update_data->tasks->len); - - sparql_array_errors = tracker_sparql_connection_update_array_finish (priv->connection, - result, - &global_error); - if (global_error) { - g_critical (" (Sparql buffer) Error in array-update: %s", - global_error->message); - } - - /* Report status on each task of the batch update */ - for (i = 0; i < update_data->tasks->len; i++) { - TrackerTask *task; - SparqlTaskData *task_data; - GError *error = NULL; - - task = g_ptr_array_index (update_data->tasks, i); - task_data = tracker_task_get_data (task); - - if (global_error) { - error = global_error; - } else { - error = g_ptr_array_index (sparql_array_errors, i); - if (error) { - GFile *file; - gchar *uri; - - file = tracker_task_get_file (task); - uri = g_file_get_uri (file); - g_critical (" (Sparql buffer) Error in task %u (%s) of the array-update: %s", - i, uri, error->message); - g_free (uri); - - g_debug (" Sparql: %s", task_data->str); - } - } - - /* Call finished handler with the error, if any */ - if (error) { - g_task_return_error (task_data->async_task, - g_error_copy (error)); - } else { - g_task_return_pointer (task_data->async_task, - tracker_task_ref (task), - (GDestroyNotify) tracker_task_unref); - } - - g_clear_object (&task_data->async_task); - - /* No need to deallocate the task here, it will be done when - * unref-ing the UpdateArrayData below */ - } - - /* Unref the arrays of errors and queries */ - if (sparql_array_errors) { - g_ptr_array_unref (sparql_array_errors); - } - - /* Note that tasks are actually deallocated here */ - update_array_data_free (update_data); - - if (global_error) { - g_error_free (global_error); - } - - if (tracker_task_pool_limit_reached (TRACKER_TASK_POOL (buffer))) { - tracker_sparql_buffer_flush (buffer, "SPARQL buffer limit reached (after flush)"); - } -} - -gboolean -tracker_sparql_buffer_flush (TrackerSparqlBuffer *buffer, - const gchar *reason) -{ - TrackerSparqlBufferPrivate *priv; - GArray *sparql_array; - UpdateArrayData *update_data; - gint i; - - priv = tracker_sparql_buffer_get_instance_private (buffer); - - if (priv->n_updates > 0) { - return FALSE; - } - - if (!priv->tasks || - priv->tasks->len == 0) { - return FALSE; - } - - g_debug ("Flushing SPARQL buffer, reason: %s", reason); - - if (priv->flush_timeout_id != 0) { - g_source_remove (priv->flush_timeout_id); - priv->flush_timeout_id = 0; - } - - /* Loop buffer and construct array of strings */ - sparql_array = g_array_new (FALSE, TRUE, sizeof (gchar *)); - - for (i = 0; i < priv->tasks->len; i++) { - SparqlTaskData *task_data; - TrackerTask *task; - - task = g_ptr_array_index (priv->tasks, i); - task_data = tracker_task_get_data (task); - g_array_append_val (sparql_array, task_data->str); - } - - update_data = g_slice_new0 (UpdateArrayData); - update_data->buffer = buffer; - update_data->tasks = g_ptr_array_ref (priv->tasks); - update_data->sparql_array = sparql_array; - - /* Empty pool, update_data will keep - * references to the tasks to keep - * these alive. - */ - g_ptr_array_unref (priv->tasks); - priv->tasks = NULL; - priv->n_updates++; - - /* Start the update */ - tracker_sparql_connection_update_array_async (priv->connection, - (gchar **) update_data->sparql_array->data, - update_data->sparql_array->len, - G_PRIORITY_DEFAULT, - NULL, - tracker_sparql_buffer_update_array_cb, - update_data); - return TRUE; -} - -static void -tracker_sparql_buffer_update_cb (GObject *object, - GAsyncResult *result, - gpointer user_data) -{ - UpdateData *update_data = user_data; - SparqlTaskData *task_data; - GError *error = NULL; - - tracker_sparql_connection_update_finish (TRACKER_SPARQL_CONNECTION (object), - result, &error); - - task_data = tracker_task_get_data (update_data->task); - - /* Call finished handler with the error, if any */ - if (error) { - g_task_return_error (task_data->async_task, error); - } else { - g_task_return_pointer (task_data->async_task, - tracker_task_ref (update_data->task), - (GDestroyNotify) tracker_task_unref); - } - - g_clear_object (&task_data->async_task); - - tracker_task_pool_remove (TRACKER_TASK_POOL (update_data->buffer), - update_data->task); - g_slice_free (UpdateData, update_data); -} - -static void -sparql_buffer_push_high_priority (TrackerSparqlBuffer *buffer, - TrackerTask *task, - SparqlTaskData *data) -{ - TrackerSparqlBufferPrivate *priv; - UpdateData *update_data; - - priv = tracker_sparql_buffer_get_instance_private (buffer); - - /* Task pool addition adds a reference (below) */ - update_data = g_slice_new0 (UpdateData); - update_data->buffer = buffer; - update_data->task = task; - - tracker_task_pool_add (TRACKER_TASK_POOL (buffer), task); - tracker_sparql_connection_update_async (priv->connection, - data->str, - G_PRIORITY_HIGH, - NULL, - tracker_sparql_buffer_update_cb, - update_data); -} - -static void -sparql_buffer_push_to_pool (TrackerSparqlBuffer *buffer, - TrackerTask *task) -{ - TrackerSparqlBufferPrivate *priv; - - priv = tracker_sparql_buffer_get_instance_private (buffer); - - if (tracker_task_pool_get_size (TRACKER_TASK_POOL (buffer)) == 0) { - reset_flush_timeout (buffer); - } - - /* Task pool addition increments reference */ - tracker_task_pool_add (TRACKER_TASK_POOL (buffer), task); - - if (!priv->tasks) { - priv->tasks = g_ptr_array_new_with_free_func ((GDestroyNotify) tracker_task_unref); - } - - /* We add a reference here because we unref when removed from - * the GPtrArray. */ - g_ptr_array_add (priv->tasks, tracker_task_ref (task)); - - if (tracker_task_pool_limit_reached (TRACKER_TASK_POOL (buffer))) { - tracker_sparql_buffer_flush (buffer, "SPARQL buffer limit reached"); - } else if (priv->tasks->len > tracker_task_pool_get_limit (TRACKER_TASK_POOL (buffer)) / 2) { - /* We've filled half of the buffer, flush it as we receive more tasks */ - tracker_sparql_buffer_flush (buffer, "SPARQL buffer half-full"); - } -} - -void -tracker_sparql_buffer_push (TrackerSparqlBuffer *buffer, - TrackerTask *task, - gint priority, - GAsyncReadyCallback cb, - gpointer user_data) -{ - SparqlTaskData *data; - - g_return_if_fail (TRACKER_IS_SPARQL_BUFFER (buffer)); - g_return_if_fail (task != NULL); - - /* NOTE: We don't own the task and if we want it we have to - * reference it, each function below references task in - * different ways. - */ - data = tracker_task_get_data (task); - - if (!data->async_task) { - data->async_task = g_task_new (buffer, NULL, cb, user_data); - g_task_set_task_data (data->async_task, - tracker_task_ref (task), - (GDestroyNotify) tracker_task_unref); - } - - if (priority <= G_PRIORITY_HIGH) { - sparql_buffer_push_high_priority (buffer, task, data); - } else { - sparql_buffer_push_to_pool (buffer, task); - } -} - -static SparqlTaskData * -sparql_task_data_new (gchar *data, - guint flags) -{ - SparqlTaskData *task_data; - - task_data = g_slice_new0 (SparqlTaskData); - task_data->str = data; - - return task_data; -} - -static void -sparql_task_data_free (SparqlTaskData *data) -{ - g_free (data->str); - - if (data->async_task) { - g_object_unref (data->async_task); - } - - g_slice_free (SparqlTaskData, data); -} - -TrackerTask * -tracker_sparql_task_new_take_sparql_str (GFile *file, - gchar *sparql_str) -{ - SparqlTaskData *data; - - data = sparql_task_data_new (sparql_str, 0); - return tracker_task_new (file, data, - (GDestroyNotify) sparql_task_data_free); -} - -TrackerTask * -tracker_sparql_task_new_with_sparql_str (GFile *file, - const gchar *sparql_str) -{ - SparqlTaskData *data; - - data = sparql_task_data_new (g_strdup (sparql_str), 0); - return tracker_task_new (file, data, - (GDestroyNotify) sparql_task_data_free); -} - -TrackerTask * -tracker_sparql_buffer_push_finish (TrackerSparqlBuffer *buffer, - GAsyncResult *res, - GError **error) -{ - TrackerTask *task; - - g_return_val_if_fail (TRACKER_IS_SPARQL_BUFFER (buffer), NULL); - g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL); - g_return_val_if_fail (!error || !*error, NULL); - - task = g_task_propagate_pointer (G_TASK (res), error); - - if (!task) - task = g_task_get_task_data (G_TASK (res)); - - return task; -} diff --git a/src/libtracker-miner/tracker-sparql-buffer.h b/src/libtracker-miner/tracker-sparql-buffer.h deleted file mode 100644 index bc3b11035..000000000 --- a/src/libtracker-miner/tracker-sparql-buffer.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2011, Nokia <ivan.frade@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Author: Carlos Garnacho <carlos@lanedo.com> - */ - -#ifndef __LIBTRACKER_MINER_SPARQL_BUFFER_H__ -#define __LIBTRACKER_MINER_SPARQL_BUFFER_H__ - -#include <glib-object.h> -#include <gio/gio.h> - -#include <libtracker-sparql/tracker-sparql.h> - -#include "tracker-task-pool.h" - -G_BEGIN_DECLS - -/* Task pool */ -#define TRACKER_TYPE_SPARQL_BUFFER (tracker_sparql_buffer_get_type()) -#define TRACKER_SPARQL_BUFFER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_SPARQL_BUFFER, TrackerSparqlBuffer)) -#define TRACKER_SPARQL_BUFFER_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), TRACKER_TYPE_SPARQL_BUFFER, TrackerSparqlBufferClass)) -#define TRACKER_IS_SPARQL_BUFFER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_SPARQL_BUFFER)) -#define TRACKER_IS_SPARQL_BUFFER_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), TRACKER_TYPE_SPARQL_BUFFER)) -#define TRACKER_SPARQL_BUFFER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_SPARQL_BUFFER, TrackerSparqlBufferClass)) - -typedef struct _TrackerSparqlBuffer TrackerSparqlBuffer; -typedef struct _TrackerSparqlBufferClass TrackerSparqlBufferClass; - -struct _TrackerSparqlBuffer -{ - TrackerTaskPool parent_instance; -}; - -struct _TrackerSparqlBufferClass -{ - TrackerTaskPoolClass parent_class; -}; - -GType tracker_sparql_buffer_get_type (void) G_GNUC_CONST; - -TrackerSparqlBuffer *tracker_sparql_buffer_new (TrackerSparqlConnection *connection, - guint limit); - -gboolean tracker_sparql_buffer_flush (TrackerSparqlBuffer *buffer, - const gchar *reason); - -void tracker_sparql_buffer_push (TrackerSparqlBuffer *buffer, - TrackerTask *task, - gint priority, - GAsyncReadyCallback cb, - gpointer user_data); - -TrackerTask * tracker_sparql_buffer_push_finish (TrackerSparqlBuffer *buffer, - GAsyncResult *res, - GError **error); - -TrackerTask * tracker_sparql_task_new_take_sparql_str (GFile *file, - gchar *sparql_str); -TrackerTask * tracker_sparql_task_new_with_sparql_str (GFile *file, - const gchar *sparql_str); - -G_END_DECLS - -#endif /* __LIBTRACKER_MINER_SPARQL_BUFFER_H__ */ diff --git a/src/libtracker-miner/tracker-task-pool.c b/src/libtracker-miner/tracker-task-pool.c deleted file mode 100644 index b9bc6df2a..000000000 --- a/src/libtracker-miner/tracker-task-pool.c +++ /dev/null @@ -1,355 +0,0 @@ -/* - * Copyright (C) 2011, Nokia <ivan.frade@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Author: Carlos Garnacho <carlos@lanedo.com> - */ - -#include "config.h" - -#include "tracker-task-pool.h" - -enum { - PROP_0, - PROP_LIMIT, - PROP_LIMIT_REACHED -}; - -typedef struct _TrackerTaskPoolPrivate TrackerTaskPoolPrivate; - -struct _TrackerTaskPoolPrivate -{ - GHashTable *tasks; - guint limit; -}; - -struct _TrackerTask -{ - GFile *file; - gpointer data; - GDestroyNotify destroy_notify; - gint ref_count; -}; - -G_DEFINE_TYPE_WITH_PRIVATE (TrackerTaskPool, tracker_task_pool, G_TYPE_OBJECT) - -static void -tracker_task_pool_finalize (GObject *object) -{ - TrackerTaskPoolPrivate *priv; - - priv = tracker_task_pool_get_instance_private (TRACKER_TASK_POOL (object)); - g_hash_table_unref (priv->tasks); - - G_OBJECT_CLASS (tracker_task_pool_parent_class)->finalize (object); -} - -static void -tracker_task_pool_set_property (GObject *object, - guint param_id, - const GValue *value, - GParamSpec *pspec) -{ - TrackerTaskPool *pool = TRACKER_TASK_POOL (object); - - - switch (param_id) { - case PROP_LIMIT: - tracker_task_pool_set_limit (pool, - g_value_get_uint (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); - } -} - -static void -tracker_task_pool_get_property (GObject *object, - guint param_id, - GValue *value, - GParamSpec *pspec) -{ - TrackerTaskPool *pool = TRACKER_TASK_POOL (object); - - switch (param_id) { - case PROP_LIMIT: - g_value_set_uint (value, - tracker_task_pool_get_limit (pool)); - break; - case PROP_LIMIT_REACHED: - g_value_set_boolean (value, - tracker_task_pool_limit_reached (pool)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); - } -} - -static void -tracker_task_pool_class_init (TrackerTaskPoolClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = tracker_task_pool_finalize; - object_class->set_property = tracker_task_pool_set_property; - object_class->get_property = tracker_task_pool_get_property; - - g_object_class_install_property (object_class, - PROP_LIMIT, - g_param_spec_uint ("limit", - "Limit", - "Task limit", - 1, G_MAXUINT, 1, - G_PARAM_READWRITE)); - g_object_class_install_property (object_class, - PROP_LIMIT_REACHED, - g_param_spec_boolean ("limit-reached", - "Limit reached", - "Task limit reached", - FALSE, - G_PARAM_READABLE)); -} - -static gboolean -file_equal (GFile *file1, - GFile *file2) -{ - if (file1 == file2) { - return TRUE; - } else { - return g_file_equal (file1, file2); - } -} - -static void -tracker_task_pool_init (TrackerTaskPool *pool) -{ - TrackerTaskPoolPrivate *priv; - - priv = tracker_task_pool_get_instance_private (pool); - priv->tasks = g_hash_table_new_full (g_file_hash, - (GEqualFunc) file_equal, - NULL, - (GDestroyNotify) tracker_task_unref); - priv->limit = 0; -} - -TrackerTaskPool * -tracker_task_pool_new (guint limit) -{ - return g_object_new (TRACKER_TYPE_TASK_POOL, - "limit", limit, - NULL); -} - -void -tracker_task_pool_set_limit (TrackerTaskPool *pool, - guint limit) -{ - TrackerTaskPoolPrivate *priv; - gboolean old_limit_reached; - - g_return_if_fail (TRACKER_IS_TASK_POOL (pool)); - - old_limit_reached = tracker_task_pool_limit_reached (pool); - - priv = tracker_task_pool_get_instance_private (pool); - priv->limit = limit; - - if (old_limit_reached != - tracker_task_pool_limit_reached (pool)) { - g_object_notify (G_OBJECT (pool), "limit-reached"); - } -} - -guint -tracker_task_pool_get_limit (TrackerTaskPool *pool) -{ - TrackerTaskPoolPrivate *priv; - - g_return_val_if_fail (TRACKER_IS_TASK_POOL (pool), 0); - - priv = tracker_task_pool_get_instance_private (pool); - return priv->limit; -} - -guint -tracker_task_pool_get_size (TrackerTaskPool *pool) -{ - TrackerTaskPoolPrivate *priv; - - g_return_val_if_fail (TRACKER_IS_TASK_POOL (pool), 0); - - priv = tracker_task_pool_get_instance_private (pool); - return g_hash_table_size (priv->tasks); -} - -gboolean -tracker_task_pool_limit_reached (TrackerTaskPool *pool) -{ - TrackerTaskPoolPrivate *priv; - - g_return_val_if_fail (TRACKER_IS_TASK_POOL (pool), FALSE); - - priv = tracker_task_pool_get_instance_private (pool); - return (g_hash_table_size (priv->tasks) >= priv->limit); -} - -void -tracker_task_pool_add (TrackerTaskPool *pool, - TrackerTask *task) -{ - TrackerTaskPoolPrivate *priv; - GFile *file; - - g_return_if_fail (TRACKER_IS_TASK_POOL (pool)); - - priv = tracker_task_pool_get_instance_private (pool); - - file = tracker_task_get_file (task); - - if (g_hash_table_contains (priv->tasks, file)) { - /* This is bad! We use the task's associated GFile as the key for the - * hash table, so if there's already a value we are about to overwrite - * it. This suggests there's a bug in the tracker-miner-fs.c code. - */ - g_warning ("Multiple update tasks for file %s", g_file_get_uri (file)); - }; - - g_hash_table_insert (priv->tasks, - tracker_task_get_file (task), - tracker_task_ref (task)); - - if (g_hash_table_size (priv->tasks) == priv->limit) { - g_object_notify (G_OBJECT (pool), "limit-reached"); - } -} - -gboolean -tracker_task_pool_remove (TrackerTaskPool *pool, - TrackerTask *task) -{ - TrackerTaskPoolPrivate *priv; - - g_return_val_if_fail (TRACKER_IS_TASK_POOL (pool), FALSE); - - priv = tracker_task_pool_get_instance_private (pool); - - if (g_hash_table_remove (priv->tasks, - tracker_task_get_file (task))) { - if (g_hash_table_size (priv->tasks) == priv->limit - 1) { - /* We've gone below the threshold again */ - g_object_notify (G_OBJECT (pool), "limit-reached"); - } - - return TRUE; - } - - return FALSE; -} - -void -tracker_task_pool_foreach (TrackerTaskPool *pool, - GFunc func, - gpointer user_data) -{ - TrackerTaskPoolPrivate *priv; - GHashTableIter iter; - TrackerTask *task; - - g_return_if_fail (TRACKER_IS_TASK_POOL (pool)); - g_return_if_fail (func != NULL); - - priv = tracker_task_pool_get_instance_private (pool); - g_hash_table_iter_init (&iter, priv->tasks); - - while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &task)) { - (func) (task, user_data); - } -} - -TrackerTask * -tracker_task_pool_find (TrackerTaskPool *pool, - GFile *file) -{ - TrackerTaskPoolPrivate *priv; - - g_return_val_if_fail (TRACKER_IS_TASK_POOL (pool), NULL); - g_return_val_if_fail (G_IS_FILE (file), NULL); - - priv = tracker_task_pool_get_instance_private (pool); - return g_hash_table_lookup (priv->tasks, file); -} - -/* Task */ -TrackerTask * -tracker_task_new (GFile *file, - gpointer data, - GDestroyNotify destroy_notify) -{ - TrackerTask *task; - - task = g_slice_new0 (TrackerTask); - task->file = g_object_ref (file); - task->destroy_notify = destroy_notify; - task->data = data; - task->ref_count = 1; - - return task; -} - -TrackerTask * -tracker_task_ref (TrackerTask *task) -{ - g_return_val_if_fail (task != NULL, NULL); - - g_atomic_int_inc (&task->ref_count); - - return task; -} -void -tracker_task_unref (TrackerTask *task) -{ - g_return_if_fail (task != NULL); - - if (g_atomic_int_dec_and_test (&task->ref_count)) { - g_object_unref (task->file); - - if (task->data && - task->destroy_notify) { - (task->destroy_notify) (task->data); - } - - g_slice_free (TrackerTask, task); - } -} - -GFile * -tracker_task_get_file (TrackerTask *task) -{ - g_return_val_if_fail (task != NULL, NULL); - - return task->file; -} - -gpointer -tracker_task_get_data (TrackerTask *task) -{ - g_return_val_if_fail (task != NULL, NULL); - - return task->data; -} diff --git a/src/libtracker-miner/tracker-task-pool.h b/src/libtracker-miner/tracker-task-pool.h deleted file mode 100644 index ea0f48769..000000000 --- a/src/libtracker-miner/tracker-task-pool.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2011, Nokia <ivan.frade@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Author: Carlos Garnacho <carlos@lanedo.com> - */ - -#ifndef __LIBTRACKER_MINER_TASK_POOL_H__ -#define __LIBTRACKER_MINER_TASK_POOL_H__ - -#include <glib-object.h> -#include <gio/gio.h> - -G_BEGIN_DECLS - -/* Task pool */ -#define TRACKER_TYPE_TASK_POOL (tracker_task_pool_get_type()) -#define TRACKER_TASK_POOL(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_TASK_POOL, TrackerTaskPool)) -#define TRACKER_TASK_POOL_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), TRACKER_TYPE_TASK_POOL, TrackerTaskPoolClass)) -#define TRACKER_IS_TASK_POOL(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_TASK_POOL)) -#define TRACKER_IS_TASK_POOL_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), TRACKER_TYPE_TASK_POOL)) -#define TRACKER_TASK_POOL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_TASK_POOL, TrackerTaskPoolClass)) - -typedef struct _TrackerTaskPool TrackerTaskPool; -typedef struct _TrackerTaskPoolClass TrackerTaskPoolClass; -typedef struct _TrackerTask TrackerTask; - -struct _TrackerTaskPool -{ - GObject parent_instance; -}; - -struct _TrackerTaskPoolClass -{ - GObjectClass parent_class; -}; - -GType tracker_task_pool_get_type (void) G_GNUC_CONST; - -TrackerTaskPool *tracker_task_pool_new (guint limit); - -void tracker_task_pool_set_limit (TrackerTaskPool *pool, - guint limit); -guint tracker_task_pool_get_limit (TrackerTaskPool *pool); -guint tracker_task_pool_get_size (TrackerTaskPool *pool); - -gboolean tracker_task_pool_limit_reached (TrackerTaskPool *pool); - -void tracker_task_pool_add (TrackerTaskPool *pool, - TrackerTask *task); - -gboolean tracker_task_pool_remove (TrackerTaskPool *pool, - TrackerTask *task); - -void tracker_task_pool_foreach (TrackerTaskPool *pool, - GFunc func, - gpointer user_data); - -TrackerTask * tracker_task_pool_find (TrackerTaskPool *pool, - GFile *file); - -/* Task */ -TrackerTask * tracker_task_new (GFile *file, - gpointer data, - GDestroyNotify destroy_notify); - -GFile * tracker_task_get_file (TrackerTask *task); - -TrackerTask * tracker_task_ref (TrackerTask *task); -void tracker_task_unref (TrackerTask *task); - -gpointer tracker_task_get_data (TrackerTask *task); - - -G_END_DECLS - -#endif /* __LIBTRACKER_MINER_TASK_POOL_H__ */ diff --git a/src/libtracker-miner/tracker-utils.c b/src/libtracker-miner/tracker-utils.c deleted file mode 100644 index aec67b560..000000000 --- a/src/libtracker-miner/tracker-utils.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2009, Nokia <ivan.frade@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "config.h" - -#include "tracker-utils.h" - -gboolean -tracker_accumulator_check_file (GSignalInvocationHint *hint, - GValue *return_accumulator, - const GValue *handler_return, - gpointer accumulator_data) -{ - gboolean use; - - use = g_value_get_boolean (handler_return); - g_value_set_boolean (return_accumulator, use); - - return (use == TRUE); -} diff --git a/src/libtracker-miner/tracker-utils.h b/src/libtracker-miner/tracker-utils.h deleted file mode 100644 index 88b363496..000000000 --- a/src/libtracker-miner/tracker-utils.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2009, Nokia <ivan.frade@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __LIBTRACKER_MINER_UTILS_H__ -#define __LIBTRACKER_MINER_UTILS_H__ - -#if !defined (__LIBTRACKER_MINER_H_INSIDE__) && !defined (TRACKER_COMPILATION) -#error "Only <libtracker-miner/tracker-miner.h> can be included directly." -#endif - -#include <glib-object.h> - -G_BEGIN_DECLS - -gboolean tracker_accumulator_check_file (GSignalInvocationHint *hint, - GValue *return_accumulator, - const GValue *handler_return, - gpointer accumulator_data); - -G_END_DECLS - -#endif /* __LIBTRACKER_MINER_UTILS_H__ */ diff --git a/src/meson.build b/src/meson.build index dfcfe1460..816d1be3c 100644 --- a/src/meson.build +++ b/src/meson.build @@ -20,9 +20,6 @@ subdir('libtracker-direct') subdir('libtracker-remote') subdir('libtracker-sparql-backend') -# Public libtracker-miner library -subdir('libtracker-miner') - # Public commandline control tool subdir('tracker') diff --git a/tests/libtracker-miner/.gitignore b/tests/libtracker-miner/.gitignore deleted file mode 100644 index ea67dbaa5..000000000 --- a/tests/libtracker-miner/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -tracker-crawler -tracker-crawler-test -tracker-miner-manager -tracker-miner-manager-test -tracker-miner-mock.[ch] -tracker-monitor-test -tracker-thumbnailer-test -tracker-password-provider-test -tracker-priority-queue-test -tracker-task-pool-test -tracker-indexing-tree-test -tracker-connection-mock.c -tracker-file-enumerator-test -tracker-file-notifier-test -tracker-file-system-test diff --git a/tests/libtracker-miner/data/dir/empty-dir/.hidden b/tests/libtracker-miner/data/dir/empty-dir/.hidden deleted file mode 100644 index e69de29bb..000000000 --- a/tests/libtracker-miner/data/dir/empty-dir/.hidden +++ /dev/null diff --git a/tests/libtracker-miner/data/dir/file1 b/tests/libtracker-miner/data/dir/file1 deleted file mode 100644 index e69de29bb..000000000 --- a/tests/libtracker-miner/data/dir/file1 +++ /dev/null diff --git a/tests/libtracker-miner/data/dir/file2 b/tests/libtracker-miner/data/dir/file2 deleted file mode 100644 index e69de29bb..000000000 --- a/tests/libtracker-miner/data/dir/file2 +++ /dev/null diff --git a/tests/libtracker-miner/data/empty-dir/.hidden b/tests/libtracker-miner/data/empty-dir/.hidden deleted file mode 100644 index e69de29bb..000000000 --- a/tests/libtracker-miner/data/empty-dir/.hidden +++ /dev/null diff --git a/tests/libtracker-miner/data/file1 b/tests/libtracker-miner/data/file1 deleted file mode 100644 index e69de29bb..000000000 --- a/tests/libtracker-miner/data/file1 +++ /dev/null diff --git a/tests/libtracker-miner/empty-gobject.c b/tests/libtracker-miner/empty-gobject.c deleted file mode 100644 index 3448c9ef9..000000000 --- a/tests/libtracker-miner/empty-gobject.c +++ /dev/null @@ -1,138 +0,0 @@ -/* empty-gobject.c generated by valac, the Vala compiler - * generated from empty-gobject.vala, do not modify */ - - -#include <glib.h> -#include <glib-object.h> - - -#define TYPE_EMPTY_OBJECT (empty_object_get_type ()) -#define EMPTY_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_EMPTY_OBJECT, EmptyObject)) -#define EMPTY_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_EMPTY_OBJECT, EmptyObjectClass)) -#define IS_EMPTY_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_EMPTY_OBJECT)) -#define IS_EMPTY_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_EMPTY_OBJECT)) -#define EMPTY_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_EMPTY_OBJECT, EmptyObjectClass)) - -typedef struct _EmptyObject EmptyObject; -typedef struct _EmptyObjectClass EmptyObjectClass; -typedef struct _EmptyObjectPrivate EmptyObjectPrivate; - -struct _EmptyObject { - GObject parent_instance; - EmptyObjectPrivate * priv; -}; - -struct _EmptyObjectClass { - GObjectClass parent_class; -}; - -struct _EmptyObjectPrivate { - gint _id; -}; - - -static gpointer empty_object_parent_class = NULL; - -GType empty_object_get_type (void); -#define EMPTY_OBJECT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_EMPTY_OBJECT, EmptyObjectPrivate)) -enum { - EMPTY_OBJECT_DUMMY_PROPERTY, - EMPTY_OBJECT_ID -}; -EmptyObject* empty_object_new (void); -EmptyObject* empty_object_construct (GType object_type); -gint empty_object_get_id (EmptyObject* self); -void empty_object_set_id (EmptyObject* self, gint value); -static void empty_object_finalize (GObject* obj); -static void empty_object_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec); -static void empty_object_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec); - - - -EmptyObject* empty_object_construct (GType object_type) { - EmptyObject * self; - self = (EmptyObject*) g_object_new (object_type, NULL); - return self; -} - - -EmptyObject* empty_object_new (void) { - return empty_object_construct (TYPE_EMPTY_OBJECT); -} - - -gint empty_object_get_id (EmptyObject* self) { - gint result; - g_return_val_if_fail (self != NULL, 0); - result = self->priv->_id; - return result; -} - - -void empty_object_set_id (EmptyObject* self, gint value) { - g_return_if_fail (self != NULL); - self->priv->_id = value; - g_object_notify ((GObject *) self, "id"); -} - - -static void empty_object_class_init (EmptyObjectClass * klass) { - empty_object_parent_class = g_type_class_peek_parent (klass); - g_type_class_add_private (klass, sizeof (EmptyObjectPrivate)); - G_OBJECT_CLASS (klass)->get_property = empty_object_get_property; - G_OBJECT_CLASS (klass)->set_property = empty_object_set_property; - G_OBJECT_CLASS (klass)->finalize = empty_object_finalize; - g_object_class_install_property (G_OBJECT_CLASS (klass), EMPTY_OBJECT_ID, g_param_spec_int ("id", "id", "id", G_MININT, G_MAXINT, 0, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE)); -} - - -static void empty_object_instance_init (EmptyObject * self) { - self->priv = EMPTY_OBJECT_GET_PRIVATE (self); -} - - -static void empty_object_finalize (GObject* obj) { - G_OBJECT_CLASS (empty_object_parent_class)->finalize (obj); -} - - -GType empty_object_get_type (void) { - static GType empty_object_type_id = 0; - if (empty_object_type_id == 0) { - static const GTypeInfo g_define_type_info = { sizeof (EmptyObjectClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) empty_object_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (EmptyObject), 0, (GInstanceInitFunc) empty_object_instance_init, NULL }; - empty_object_type_id = g_type_register_static (G_TYPE_OBJECT, "EmptyObject", &g_define_type_info, 0); - } - return empty_object_type_id; -} - - -static void empty_object_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) { - EmptyObject * self; - self = EMPTY_OBJECT (object); - switch (property_id) { - case EMPTY_OBJECT_ID: - g_value_set_int (value, empty_object_get_id (self)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - - -static void empty_object_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec) { - EmptyObject * self; - self = EMPTY_OBJECT (object); - switch (property_id) { - case EMPTY_OBJECT_ID: - empty_object_set_id (self, g_value_get_int (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - - - - diff --git a/tests/libtracker-miner/empty-gobject.h b/tests/libtracker-miner/empty-gobject.h deleted file mode 100644 index c760ac751..000000000 --- a/tests/libtracker-miner/empty-gobject.h +++ /dev/null @@ -1,43 +0,0 @@ -/* empty-gobject.h generated by valac, the Vala compiler, do not modify */ - - -#ifndef __EMPTY_GOBJECT_H__ -#define __EMPTY_GOBJECT_H__ - -#include <glib.h> -#include <glib-object.h> - -G_BEGIN_DECLS - - -#define TYPE_EMPTY_OBJECT (empty_object_get_type ()) -#define EMPTY_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_EMPTY_OBJECT, EmptyObject)) -#define EMPTY_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_EMPTY_OBJECT, EmptyObjectClass)) -#define IS_EMPTY_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_EMPTY_OBJECT)) -#define IS_EMPTY_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_EMPTY_OBJECT)) -#define EMPTY_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_EMPTY_OBJECT, EmptyObjectClass)) - -typedef struct _EmptyObject EmptyObject; -typedef struct _EmptyObjectClass EmptyObjectClass; -typedef struct _EmptyObjectPrivate EmptyObjectPrivate; - -struct _EmptyObject { - GObject parent_instance; - EmptyObjectPrivate * priv; -}; - -struct _EmptyObjectClass { - GObjectClass parent_class; -}; - - -GType empty_object_get_type (void); -EmptyObject* empty_object_new (void); -EmptyObject* empty_object_construct (GType object_type); -gint empty_object_get_id (EmptyObject* self); -void empty_object_set_id (EmptyObject* self, gint value); - - -G_END_DECLS - -#endif diff --git a/tests/libtracker-miner/meson.build b/tests/libtracker-miner/meson.build deleted file mode 100644 index d01937469..000000000 --- a/tests/libtracker-miner/meson.build +++ /dev/null @@ -1,58 +0,0 @@ -libtracker_miner_tests = [ - 'crawler', - 'file-enumerator', - 'file-system', - 'indexing-tree', - 'priority-queue', - 'task-pool', - 'thumbnailer', -] - -libtracker_miner_slow_tests = [ - 'file-notifier', - 'miner-fs', - 'monitor', -] - -libtracker_miner_test_c_args = [ - '-DLIBEXEC_PATH="@0@/@1@"'.format(get_option('prefix'), get_option('libexecdir')), - '-DTEST', - '-DTEST_DATA_DIR="@0@/data"'.format(meson.current_source_dir()), - '-DTEST_MINERS_DIR="@0@/mock-miners"'.format(meson.current_source_dir()), - '-DTEST_ONTOLOGIES_DIR="@0@/src/ontologies/nepomuk"'.format(source_root), -] - -libtracker_miner_test_deps = [tracker_common_dep, tracker_miner_dep, tracker_sparql_dep] - -foreach base_name: libtracker_miner_tests - source = 'tracker-@0@-test.c'.format(base_name) - binary_name = 'tracker-@0@-test'.format(base_name) - - binary = executable(binary_name, source, - dependencies: libtracker_miner_test_deps, - c_args: libtracker_miner_test_c_args, - link_with: [libtracker_miner_private]) - - tests += { - 'name': base_name, - 'exe': binary, - 'suite': ['miner'], - } -endforeach - -foreach base_name: libtracker_miner_slow_tests - source = 'tracker-@0@-test.c'.format(base_name) - binary_name = 'tracker-@0@-test'.format(base_name) - - binary = executable(binary_name, source, - dependencies: libtracker_miner_test_deps, - c_args: libtracker_miner_test_c_args, - link_with: [libtracker_miner_private]) - - tests += { - 'name': base_name, - 'exe': binary, - 'suite': ['miner', 'slow'], - 'timeout': 180 - } -endforeach diff --git a/tests/libtracker-miner/miners-mock.c b/tests/libtracker-miner/miners-mock.c deleted file mode 100644 index fe46b398a..000000000 --- a/tests/libtracker-miner/miners-mock.c +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Copyright (C) 2010, Nokia <ivan.frade@nokia.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include <string.h> - -#include <glib-object.h> -#include <gobject/gvaluecollector.h> - -#include "empty-gobject.h" -#include "miners-mock.h" -#include "tracker-miner-mock.h" - -GHashTable *miners = NULL; - -void -miners_mock_init () -{ - TrackerMinerMock *miner; - - miners = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); - - miner = tracker_miner_mock_new (MOCK_MINER_1); - tracker_miner_mock_set_paused (miner, FALSE); - g_hash_table_insert (miners, g_strdup (MOCK_MINER_1), miner); - - miner = tracker_miner_mock_new (MOCK_MINER_2); - tracker_miner_mock_set_paused (miner, TRUE); - g_hash_table_insert (miners, g_strdup (MOCK_MINER_2), miner); -} - -/* - * DBus overrides - */ -#if 0 -/* Todo: port to gdbus */ - -DBusGConnection * -dbus_g_bus_get (DBusBusType type, GError **error) -{ - return (DBusGConnection *) empty_object_new (); -} - -DBusGProxy * -dbus_g_proxy_new_for_name (DBusGConnection *connection, - const gchar *service, - const gchar *path, - const gchar *interface ) -{ - TrackerMinerMock *miner; - - miner = (TrackerMinerMock *)g_hash_table_lookup (miners, service); - if (!miner) { - return (DBusGProxy *) empty_object_new (); - } - return (DBusGProxy *) miner; -} - -void -dbus_g_proxy_add_signal (DBusGProxy *proxy, const char *signal_name, GType first_type,...) -{ -} - -void -dbus_g_proxy_connect_signal (DBusGProxy *proxy, - const char *signal_name, - GCallback handler, - void *data, - GClosureNotify free_data_func) -{ - TrackerMinerMock *miner = (TrackerMinerMock *)proxy; - - if (g_strcmp0 (signal_name, "NameOwnerChanged") == 0) { - return; - } - - g_signal_connect (miner, g_utf8_strdown (signal_name, -1), handler, data); - -} - -/* - * Two mock miners available but only 1 running - */ -gboolean -dbus_g_proxy_call (DBusGProxy *proxy, - const gchar *function_name, - GError **error, - GType first_arg_type, ...) -{ - va_list args; - GType arg_type; - const gchar *running_services[] = { "org.gnome.Tomboy", - "org.gnome.GConf", - MOCK_MINER_1, - "org.gnome.SessionManager", - NULL}; - - va_start (args, first_arg_type); - - if (g_strcmp0 (function_name, "ListNames") == 0) { - /* - * G_TYPE_INVALID, - * G_TYPE_STRV, &result, - * G_TYPE_INVALID - */ - GValue value = { 0, }; - gchar *local_error = NULL; - - arg_type = va_arg (args, GType); - - g_assert (arg_type == G_TYPE_STRV); - g_value_init (&value, arg_type); - g_value_set_boxed (&value, running_services); - G_VALUE_LCOPY (&value, - args, 0, - &local_error); - g_free (local_error); - g_value_unset (&value); - - } else if (g_strcmp0 (function_name, "NameHasOwner") == 0) { - /* - * G_TYPE_STRING, miner, - * G_TYPE_INVALID, - * G_TYPE_BOOLEAN, &active, - * G_TYPE_INVALID)) { - */ - GValue value = { 0, }; - gchar *local_error = NULL; - const gchar *miner_name; - TrackerMinerMock *miner; - gboolean active; - - g_value_init (&value, G_TYPE_STRING); - G_VALUE_COLLECT (&value, args, 0, &local_error); - g_free (local_error); - miner_name = g_value_get_string (&value); - - miner = (TrackerMinerMock *)g_hash_table_lookup (miners, miner_name); - active = !tracker_miner_mock_get_paused (miner); - g_value_unset (&value); - - arg_type = va_arg (args, GType); - g_assert (arg_type == G_TYPE_INVALID); - - arg_type = va_arg (args, GType); - g_assert (arg_type == G_TYPE_BOOLEAN); - g_value_init (&value, arg_type); - g_value_set_boolean (&value, active); - G_VALUE_LCOPY (&value, - args, 0, - &local_error); - g_free (local_error); - g_value_unset (&value); - - } else if (g_strcmp0 (function_name, "GetPauseDetails") == 0) { - /* - * G_TYPE_INVALID, - * G_TYPE_STRV, &apps, - * G_TYPE_STRV, &reasons, - * G_TYPE_INVALID - */ - GValue value = { 0, }; - gchar *local_error = NULL; - gint amount; - gchar **apps, **reasons; - TrackerMinerMock *miner = (TrackerMinerMock *)proxy; - - arg_type = va_arg (args, GType); - g_assert (arg_type == G_TYPE_STRV); - g_value_init (&value, arg_type); - apps = tracker_miner_mock_get_apps (miner, &amount); - if (apps == NULL || amount == 0) { - apps = g_new0 (gchar *, 1); - } - g_value_set_boxed (&value, apps); - G_VALUE_LCOPY (&value, - args, 0, - &local_error); - g_free (local_error); - g_value_unset (&value); - - arg_type = va_arg (args, GType); - g_assert (arg_type == G_TYPE_STRV); - g_value_init (&value, arg_type); - reasons = tracker_miner_mock_get_reasons (miner, &amount); - if (reasons == NULL || amount == 0) { - reasons = g_new0 (gchar *, 1); - } - g_value_set_boxed (&value, reasons); - G_VALUE_LCOPY (&value, - args, 0, - &local_error); - g_free (local_error); - g_value_unset (&value); - - } else if (g_strcmp0 (function_name, "Pause") == 0) { - /* - * G_TYPE_STRING, &app, - * G_TYPE_STRING, &reason, - * G_TYPE_INVALID, - * G_TYPE_INT, &cookie, - * G_TYPE_INVALID - */ - GValue value_app = { 0, }; - gchar *local_error = NULL; - GValue value_reason = {0, }; - const gchar *app; - const gchar *reason; - TrackerMinerMock *miner = (TrackerMinerMock *)proxy; - - g_value_init (&value_app, G_TYPE_STRING); - G_VALUE_COLLECT (&value_app, args, 0, &local_error); - g_free (local_error); - app = g_value_get_string (&value_app); - - arg_type = va_arg (args, GType); - g_value_init (&value_reason, G_TYPE_STRING); - G_VALUE_COLLECT (&value_reason, args, 0, &local_error); - g_free (local_error); - reason = g_value_get_string (&value_reason); - - tracker_miner_mock_pause (miner, app, reason); - - } else if (g_strcmp0 (function_name, "Resume") == 0) { - /* - * G_TYPE_INT, &cookie - * G_TYPE_INVALID - */ - TrackerMinerMock *miner = (TrackerMinerMock *)proxy; - tracker_miner_mock_resume (miner); - - } else if (g_strcmp0 (function_name, "GetProgress") == 0) { - /* Whatever */ - } else if (g_strcmp0 (function_name, "GetStatus") == 0) { - /* Whatever */ - } else { - g_critical ("dbus_g_proxy_call '%s' unsupported", function_name); - } - - va_end (args); - return TRUE; -} - - -void -dbus_g_proxy_call_no_reply (DBusGProxy *proxy, - const char *method, - GType first_arg_type, - ...) -{ -} - - -void -dbus_g_connection_unref (DBusGConnection *conn) -{ - /* It is an EmptyGObject */ - g_object_unref (conn); -} - -#endif diff --git a/tests/libtracker-miner/miners-mock.h b/tests/libtracker-miner/miners-mock.h deleted file mode 100644 index 36ffdb295..000000000 --- a/tests/libtracker-miner/miners-mock.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2010, Nokia <ivan.frade@nokia.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#ifndef __MINERS_MOCK_H__ -#define __MINERS_MOCK_H__ - -#include <glib.h> - -G_BEGIN_DECLS - -#define MOCK_MINER_1 "org.freedesktop.Tracker1.Miner.Mock1" -#define MOCK_MINER_2 "org.freedesktop.Tracker1.Miner.Mock2" - -/* - * Assumptions: - * - * There are this two miners, - * Initial state: Mock1 is running, Mock2 is paused - * - */ -void miners_mock_init (void); - -G_END_DECLS - - -#endif diff --git a/tests/libtracker-miner/mock-miners/mock-miner-1.desktop b/tests/libtracker-miner/mock-miners/mock-miner-1.desktop deleted file mode 100644 index 1286bb89f..000000000 --- a/tests/libtracker-miner/mock-miners/mock-miner-1.desktop +++ /dev/null @@ -1,5 +0,0 @@ -[Desktop Entry] -Name=Mock miner for testing -Comment=Comment in the mock miner -DBusName=org.freedesktop.Tracker1.Miner.Mock1 -DBusPath=/org/freedesktop/Tracker1/Miner/Mock1 diff --git a/tests/libtracker-miner/mock-miners/mock-miner-2.desktop b/tests/libtracker-miner/mock-miners/mock-miner-2.desktop deleted file mode 100644 index d753b5ae0..000000000 --- a/tests/libtracker-miner/mock-miners/mock-miner-2.desktop +++ /dev/null @@ -1,5 +0,0 @@ -[Desktop Entry] -Name=Yet another mock miner -Comment=Stupid and tedious test for the comment -DBusName=org.freedesktop.Tracker1.Miner.Mock2 -DBusPath=/org/freedesktop/Tracker1/Miner/Mock2 diff --git a/tests/libtracker-miner/thumbnailer-mock.c b/tests/libtracker-miner/thumbnailer-mock.c deleted file mode 100644 index 880f56fd9..000000000 --- a/tests/libtracker-miner/thumbnailer-mock.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (C) 2010, Nokia <ivan.frade@nokia.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include <glib-object.h> -#include <gobject/gvaluecollector.h> - -#include "empty-gobject.h" -#include "thumbnailer-mock.h" - -static GList *calls = NULL; - -void -dbus_mock_call_log_reset () -{ - if (calls) { - g_list_foreach (calls, (GFunc)g_free, NULL); - g_list_free (calls); - calls = NULL; - } -} - -GList * -dbus_mock_call_log_get () -{ - return calls; -} - -#if 0 - -static void -dbus_mock_call_log_append (const gchar *function_name) -{ - calls = g_list_append (calls, g_strdup (function_name)); -} - - -/* Port to gdbus */ -/* - * DBus overrides - */ - -DBusGConnection * -dbus_g_bus_get (DBusBusType type, GError **error) -{ - return (DBusGConnection *) empty_object_new (); -} - -DBusGProxy * -dbus_g_proxy_new_for_name (DBusGConnection *connection, - const gchar *service, - const gchar *path, - const gchar *interface ) -{ - return (DBusGProxy *) empty_object_new (); -} - -gboolean -dbus_g_proxy_call (DBusGProxy *proxy, - const gchar *function_name, - GError **error, - GType first_arg_type, ...) -{ - va_list args; - GType arg_type; - const gchar *supported_mimes[] = { "mock/one", "mock/two", NULL}; - int counter; - - g_assert (g_strcmp0 (function_name, "GetSupported") == 0); - - /* - G_TYPE_INVALID, - G_TYPE_STRV, &uri_schemes, - G_TYPE_STRV, &mime_types, - G_TYPE_INVALID); - - Set the mock values in the second parameter :) - */ - - va_start (args, first_arg_type); - arg_type = va_arg (args, GType); - - counter = 1; - while (arg_type != G_TYPE_INVALID) { - - if (arg_type == G_TYPE_STRV && counter == 2) { - gchar *local_error = NULL; - GValue value = { 0, }; - g_value_init (&value, arg_type); - g_value_set_boxed (&value, supported_mimes); - G_VALUE_LCOPY (&value, - args, 0, - &local_error); - g_free (local_error); - g_value_unset (&value); - } else { - gpointer *out_param; - out_param = va_arg (args, gpointer *); - } - arg_type = va_arg (args, GType); - counter += 1; - } - - va_end (args); - return TRUE; -} - - -void -dbus_g_proxy_call_no_reply (DBusGProxy *proxy, - const char *method, - GType first_arg_type, - ...) -{ - dbus_mock_call_log_append (method); -} -#endif - diff --git a/tests/libtracker-miner/thumbnailer-mock.h b/tests/libtracker-miner/thumbnailer-mock.h deleted file mode 100644 index 8dd8b7279..000000000 --- a/tests/libtracker-miner/thumbnailer-mock.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2010, Nokia <ivan.frade@nokia.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#ifndef __THUMBNAILER_MOCK_H__ -#define __THUMBNAILER_MOCK_H__ - -#include <glib.h> - -G_BEGIN_DECLS - -void dbus_mock_call_log_reset (void); -GList * dbus_mock_call_log_get (void); - -G_END_DECLS - - -#endif diff --git a/tests/libtracker-miner/tracker-connection-mock.vala b/tests/libtracker-miner/tracker-connection-mock.vala deleted file mode 100644 index f8ed123fc..000000000 --- a/tests/libtracker-miner/tracker-connection-mock.vala +++ /dev/null @@ -1,97 +0,0 @@ -using GLib; -using Tracker; - - -public class TrackerMockResults : Tracker.Sparql.Cursor { - int rows; - int current_row = -1; - string[,] results; - string[] var_names; - Sparql.ValueType[] types; - int cols; - - public TrackerMockResults (owned string[,] results, int rows, int cols, string[] var_names, Sparql.ValueType[] types) { - this.rows = rows; - this.cols = cols; - this.results = (owned) results; - this.types = types; - this.var_names = var_names; - } - - public override int n_columns { get { return cols; } } - - public override Sparql.ValueType get_value_type (int column) - requires (current_row >= 0) { - return this.types[column]; - } - - public override unowned string? get_variable_name (int column) - requires (current_row >= 0) { - return this.var_names[column]; - } - - public override unowned string? get_string (int column, out long length = null) - requires (current_row >= 0) { - unowned string str; - - str = results[current_row, column]; - - length = str.length; - - return str; - } - - public override bool next (Cancellable? cancellable = null) throws GLib.Error { - if (current_row >= rows - 1) { - return false; - } - current_row++; - return true; - } - - public override async bool next_async (Cancellable? cancellable = null) throws GLib.Error { - /* This cursor isn't blocking, it's fine to just call next here */ - return next (cancellable); - } - - public override void rewind () { - current_row = 0; - } -} - - - - -public class TrackerMockConnection : Sparql.Connection { - - TrackerMockResults results = null; - TrackerMockResults hardcoded = new TrackerMockResults ({{"11", "12"}, {"21", "22"}}, 2, 2, - {"artist", "album"}, - {Sparql.ValueType.STRING, Sparql.ValueType.STRING}); - - public override Sparql.Cursor query (string sparql, - Cancellable? cancellable = null) - throws Sparql.Error, IOError, DBusError { - if (this.results != null) { - return results; - } else { - return hardcoded; - } - } - - - public async override Sparql.Cursor query_async (string sparql, Cancellable? cancellable = null) - throws Sparql.Error, IOError, DBusError { - if (this.results != null) { - return results; - } else { - return hardcoded; - } - } - - - public void set_results (TrackerMockResults results) { - this.results = results; - } - -} diff --git a/tests/libtracker-miner/tracker-crawler-test.c b/tests/libtracker-miner/tracker-crawler-test.c deleted file mode 100644 index 45295a8b4..000000000 --- a/tests/libtracker-miner/tracker-crawler-test.c +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Copyright (C) 2010, Nokia <ivan.frade@nokia.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "config.h" - -#include <locale.h> - -#include <libtracker-miner/tracker-crawler.h> - -typedef struct CrawlerTest CrawlerTest; - -struct CrawlerTest { - GMainLoop *main_loop; - guint directories_found; - guint directories_ignored; - guint files_found; - guint files_ignored; - gboolean interrupted; - - /* signals statistics */ - guint n_check_directory; - guint n_check_directory_contents; - guint n_check_file; -}; - -static void -crawler_finished_cb (TrackerCrawler *crawler, - gboolean interrupted, - gpointer user_data) -{ - CrawlerTest *test = user_data; - - test->interrupted = interrupted; - - if (test->main_loop) { - g_main_loop_quit (test->main_loop); - } -} - -static void -crawler_directory_crawled_cb (TrackerCrawler *crawler, - GFile *directory, - GNode *tree, - guint directories_found, - guint directories_ignored, - guint files_found, - guint files_ignored, - gpointer user_data) -{ - CrawlerTest *test = user_data; - - test->directories_found = directories_found; - test->directories_ignored = directories_ignored; - test->files_found = files_found; - test->files_ignored = files_ignored; - - g_assert_cmpint (g_node_n_nodes (tree, G_TRAVERSE_ALL), ==, directories_found + files_found); -} - -static gboolean -crawler_check_directory_cb (TrackerCrawler *crawler, - GFile *file, - gpointer user_data) -{ - CrawlerTest *test = user_data; - - test->n_check_directory++; - - return TRUE; -} - -static gboolean -crawler_check_file_cb (TrackerCrawler *crawler, - GFile *file, - gpointer user_data) -{ - CrawlerTest *test = user_data; - - test->n_check_file++; - - return TRUE; -} - -static gboolean -crawler_check_directory_contents_cb (TrackerCrawler *crawler, - GFile *file, - GList *contents, - gpointer user_data) -{ - CrawlerTest *test = user_data; - - test->n_check_directory_contents++; - - return TRUE; -} - -static void -test_crawler_crawl (void) -{ - TrackerCrawler *crawler; - CrawlerTest test = { 0 }; - gboolean started; - GFile *file; - - test.main_loop = g_main_loop_new (NULL, FALSE); - - crawler = tracker_crawler_new (NULL); - g_signal_connect (crawler, "finished", - G_CALLBACK (crawler_finished_cb), &test); - - file = g_file_new_for_path (TEST_DATA_DIR); - - started = tracker_crawler_start (crawler, file, TRACKER_DIRECTORY_FLAG_NONE); - - g_assert_cmpint (started, ==, 1); - - g_main_loop_run (test.main_loop); - - g_assert_cmpint (test.interrupted, ==, 0); - - g_main_loop_unref (test.main_loop); - g_object_unref (crawler); - g_object_unref (file); -} - -static void -test_crawler_crawl_interrupted (void) -{ - TrackerCrawler *crawler; - CrawlerTest test = { 0 }; - gboolean started; - GFile *file; - - crawler = tracker_crawler_new (NULL); - g_signal_connect (crawler, "finished", - G_CALLBACK (crawler_finished_cb), &test); - - file = g_file_new_for_path (TEST_DATA_DIR); - - started = tracker_crawler_start (crawler, file, TRACKER_DIRECTORY_FLAG_NONE); - - g_assert_cmpint (started, ==, 1); - - tracker_crawler_stop (crawler); - - g_assert_cmpint (test.interrupted, ==, 1); - - g_object_unref (crawler); - g_object_unref (file); -} - -static void -test_crawler_crawl_nonexisting (void) -{ - TrackerCrawler *crawler; - GFile *file; - gboolean started; - - crawler = tracker_crawler_new (NULL); - file = g_file_new_for_path (TEST_DATA_DIR "-idontexist"); - - started = tracker_crawler_start (crawler, file, TRACKER_DIRECTORY_FLAG_NONE); - - g_assert_cmpint (started, ==, 0); - - g_object_unref (crawler); - g_object_unref (file); -} - -static void -test_crawler_crawl_non_recursive (void) -{ - TrackerCrawler *crawler; - CrawlerTest test = { 0 }; - GFile *file; - - test.main_loop = g_main_loop_new (NULL, FALSE); - - crawler = tracker_crawler_new (NULL); - g_signal_connect (crawler, "finished", - G_CALLBACK (crawler_finished_cb), &test); - g_signal_connect (crawler, "directory-crawled", - G_CALLBACK (crawler_directory_crawled_cb), &test); - - file = g_file_new_for_path (TEST_DATA_DIR); - - tracker_crawler_start (crawler, file, TRACKER_DIRECTORY_FLAG_NONE); - - g_main_loop_run (test.main_loop); - - /* There are 3 directories (including parent) and 1 file in toplevel dir */ - g_assert_cmpint (test.directories_found, ==, 3); - g_assert_cmpint (test.directories_ignored, ==, 0); - g_assert_cmpint (test.files_found, ==, 1); - g_assert_cmpint (test.files_ignored, ==, 0); - - g_main_loop_unref (test.main_loop); - g_object_unref (crawler); - g_object_unref (file); -} - -static void -test_crawler_crawl_n_signals_non_recursive (void) -{ - TrackerCrawler *crawler; - CrawlerTest test = { 0 }; - GFile *file; - - setlocale (LC_ALL, ""); - - test.main_loop = g_main_loop_new (NULL, FALSE); - - crawler = tracker_crawler_new (NULL); - g_signal_connect (crawler, "finished", - G_CALLBACK (crawler_finished_cb), &test); - g_signal_connect (crawler, "directory-crawled", - G_CALLBACK (crawler_directory_crawled_cb), &test); - g_signal_connect (crawler, "check-directory", - G_CALLBACK (crawler_check_directory_cb), &test); - g_signal_connect (crawler, "check-directory-contents", - G_CALLBACK (crawler_check_directory_contents_cb), &test); - g_signal_connect (crawler, "check-file", - G_CALLBACK (crawler_check_file_cb), &test); - - file = g_file_new_for_path (TEST_DATA_DIR); - - tracker_crawler_start (crawler, file, TRACKER_DIRECTORY_FLAG_NONE); - - g_main_loop_run (test.main_loop); - - g_assert_cmpint (test.directories_found, ==, test.n_check_directory); - g_assert_cmpint (1, ==, test.n_check_directory_contents); - g_assert_cmpint (test.files_found, ==, test.n_check_file); - - g_main_loop_unref (test.main_loop); - g_object_unref (crawler); - g_object_unref (file); -} - -int -main (int argc, - char **argv) -{ - g_test_init (&argc, &argv, NULL); - - g_test_message ("Testing filesystem crawler"); - - g_test_add_func ("/libtracker-miner/tracker-crawler/crawl", - test_crawler_crawl); - g_test_add_func ("/libtracker-miner/tracker-crawler/crawl-interrupted", - test_crawler_crawl_interrupted); - g_test_add_func ("/libtracker-miner/tracker-crawler/crawl-nonexisting", - test_crawler_crawl_nonexisting); - - g_test_add_func ("/libtracker-miner/tracker-crawler/crawl-non-recursive", - test_crawler_crawl_non_recursive); - - g_test_add_func ("/libtracker-miner/tracker-crawler/crawl-n-signals-non-recursive", - test_crawler_crawl_n_signals_non_recursive); - - return g_test_run (); -} diff --git a/tests/libtracker-miner/tracker-file-enumerator-test.c b/tests/libtracker-miner/tracker-file-enumerator-test.c deleted file mode 100644 index edf00842a..000000000 --- a/tests/libtracker-miner/tracker-file-enumerator-test.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2014, Softathome <contact@softathome.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "config.h" - -#include <locale.h> - -#include <libtracker-miner/tracker-miner.h> -/* Normally private */ -#include <libtracker-miner/tracker-file-data-provider.h> - -static void -test_enumerator_and_provider (void) -{ - TrackerDataProvider *data_provider; - GFileEnumerator *enumerator; - GFileInfo *info; - GFile *url; - GError *error = NULL; - gint count = 0; - - data_provider = tracker_file_data_provider_new (); - g_assert_nonnull (data_provider); - - /* FIXME: Use better tmp data structure */ - url = g_file_new_for_path (g_get_tmp_dir ()); - g_assert_nonnull (url); - - /* fe = g_file_enumerate_children ( */ - /* 0, */ - /* NULL, */ - /* &error); */ - - /* g_assert_no_error (error); */ - /* g_assert_nonnull (fe); */ - - /* enumerator = tracker_file_enumerator_new (fe); */ - /* g_assert_nonnull (enumerator); */ - - enumerator = tracker_data_provider_begin (data_provider, - url, - G_FILE_ATTRIBUTE_STANDARD_NAME "," \ - G_FILE_ATTRIBUTE_STANDARD_TYPE, - G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, - NULL, - &error); - g_assert_no_error (error); - g_assert_nonnull (enumerator); - - while ((info = g_file_enumerator_next_file (enumerator, NULL, &error)) != NULL) { - g_assert_no_error (error); - count++; - } - - g_assert_no_error (error); - g_assert (count > 0); - - g_object_unref (enumerator); - g_object_unref (data_provider); -} - -int -main (int argc, char **argv) -{ - setlocale (LC_ALL, ""); - - g_test_init (&argc, &argv, NULL); - - g_test_message ("Testing file enumerator"); - - g_test_add_func ("/libtracker-miner/tracker-enumerator-and-provider", - test_enumerator_and_provider); - - return g_test_run (); -} diff --git a/tests/libtracker-miner/tracker-file-notifier-test.c b/tests/libtracker-miner/tracker-file-notifier-test.c deleted file mode 100644 index e195104b0..000000000 --- a/tests/libtracker-miner/tracker-file-notifier-test.c +++ /dev/null @@ -1,798 +0,0 @@ -/* - * Copyright (C) 2011, Nokia <ivan.frade@nokia.com> - * - * Author: Carlos Garnacho <carlos@lanedo.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "config.h" - -#include <string.h> -#include <unistd.h> -#include <stdlib.h> -#include <locale.h> - -#include <glib.h> -#include <glib/gstdio.h> - -#include <libtracker-miner/tracker-miner-enums.h> -#include <libtracker-miner/tracker-file-notifier.h> - -typedef struct { - gint op; - gchar *path; - gchar *other_path; -} FilesystemOperation; - -/* Fixture struct */ -typedef struct { - GFile *test_file; - gchar *test_path; - - TrackerSparqlConnection *connection; - TrackerIndexingTree *indexing_tree; - GMainLoop *main_loop; - - /* The file notifier to test */ - TrackerFileNotifier *notifier; - - guint expire_timeout_id; - gboolean expect_finished; - - FilesystemOperation *expect_results; - guint expect_n_results; - - GList *ops; -} TestCommonContext; - -typedef enum { - OPERATION_CREATE, - OPERATION_UPDATE, - OPERATION_DELETE, - OPERATION_MOVE -} OperationType; - -#if GLIB_MINOR_VERSION < 30 -gchar * -g_mkdtemp (gchar *tmpl) -{ - return mkdtemp (tmpl); -} -#endif - -#define test_add(path,fun) \ - g_test_add (path, \ - TestCommonContext, \ - NULL, \ - test_common_context_setup, \ - fun, \ - test_common_context_teardown) - -static void -filesystem_operation_free (FilesystemOperation *op) -{ - g_free (op->path); - g_free (op->other_path); - g_free (op); -} - -static void -perform_file_operation (TestCommonContext *fixture, - gchar *command, - gchar *filename, - gchar *other_filename) -{ - gchar *path, *other_path, *call; - - path = g_build_filename (fixture->test_path, filename, NULL); - - if (other_filename) { - other_path = g_build_filename (fixture->test_path, filename, NULL); - call = g_strdup_printf ("%s %s %s", command, path, other_path); - g_free (other_path); - } else { - call = g_strdup_printf ("%s %s", command, path); - } - - system (call); - - g_free (call); - g_free (path); -} - -#define CREATE_FOLDER(fixture,p) perform_file_operation((fixture),"mkdir",(p),NULL) -#define CREATE_UPDATE_FILE(fixture,p) perform_file_operation((fixture),"touch",(p),NULL) -#define DELETE_FILE(fixture,p) perform_file_operation((fixture),"rm",(p),NULL) -#define DELETE_FOLDER(fixture,p) perform_file_operation((fixture),"rm -rf",(p),NULL) - -static void -file_notifier_file_created_cb (TrackerFileNotifier *notifier, - GFile *file, - gpointer user_data) -{ - TestCommonContext *fixture = user_data; - FilesystemOperation *op; - - op = g_new0 (FilesystemOperation, 1); - op->op = OPERATION_CREATE; - op->path = g_file_get_relative_path (fixture->test_file , file); - - fixture->ops = g_list_prepend (fixture->ops, op); - - if (!fixture->expect_finished && - fixture->expect_n_results == g_list_length (fixture->ops)) { - g_main_loop_quit (fixture->main_loop); - } -} - -static void -file_notifier_file_updated_cb (TrackerFileNotifier *notifier, - GFile *file, - gboolean attributes_only, - gpointer user_data) -{ - TestCommonContext *fixture = user_data; - FilesystemOperation *op; - - op = g_new0 (FilesystemOperation, 1); - op->op = OPERATION_UPDATE; - op->path = g_file_get_relative_path (fixture->test_file , file); - - fixture->ops = g_list_prepend (fixture->ops, op); - - if (!fixture->expect_finished && - fixture->expect_n_results == g_list_length (fixture->ops)) { - g_main_loop_quit (fixture->main_loop); - } -} - -static void -file_notifier_file_deleted_cb (TrackerFileNotifier *notifier, - GFile *file, - gpointer user_data) -{ - TestCommonContext *fixture = user_data; - FilesystemOperation *op; - guint i; - - op = g_new0 (FilesystemOperation, 1); - op->op = OPERATION_DELETE; - op->path = g_file_get_relative_path (fixture->test_file , file); - - for (i = 0; i < fixture->expect_n_results; i++) { - if (fixture->expect_results[i].op == op->op && - g_strcmp0 (fixture->expect_results[i].path, op->path) != 0 && - g_str_has_prefix (op->path, fixture->expect_results[i].path)) { - /* Deleted file is the child of a directory - * that's expected to be deleted. - */ - filesystem_operation_free (op); - return; - } - } - - fixture->ops = g_list_prepend (fixture->ops, op); - - if (!fixture->expect_finished && - fixture->expect_n_results == g_list_length (fixture->ops)) { - g_main_loop_quit (fixture->main_loop); - } -} - -static void -file_notifier_file_moved_cb (TrackerFileNotifier *notifier, - GFile *file, - GFile *other_file, - gpointer user_data) -{ - TestCommonContext *fixture = user_data; - FilesystemOperation *op; - - op = g_new0 (FilesystemOperation, 1); - op->op = OPERATION_MOVE; - op->path = g_file_get_relative_path (fixture->test_file , file); - op->other_path = g_file_get_relative_path (fixture->test_file , - other_file); - - fixture->ops = g_list_prepend (fixture->ops, op); - - if (!fixture->expect_finished && - fixture->expect_n_results == g_list_length (fixture->ops)) { - g_main_loop_quit (fixture->main_loop); - } -} - -static void -file_notifier_finished_cb (TrackerFileNotifier *notifier, - gpointer user_data) -{ - TestCommonContext *fixture = user_data; - - if (fixture->expect_finished) { - g_main_loop_quit (fixture->main_loop); - } -} - -static void -test_common_context_index_dir (TestCommonContext *fixture, - const gchar *filename, - TrackerDirectoryFlags flags) -{ - GFile *file; - gchar *path; - - path = g_build_filename (fixture->test_path, filename, NULL); - file = g_file_new_for_path (path); - g_free (path); - - tracker_indexing_tree_add (fixture->indexing_tree, file, flags); - g_object_unref (file); -} - -static void -test_common_context_remove_dir (TestCommonContext *fixture, - const gchar *filename) -{ - GFile *file; - gchar *path; - - path = g_build_filename (fixture->test_path, filename, NULL); - file = g_file_new_for_path (path); - g_free (path); - - tracker_indexing_tree_remove (fixture->indexing_tree, file); - g_object_unref (file); -} - -static void -test_common_context_setup (TestCommonContext *fixture, - gconstpointer data) -{ - GFile *data_loc, *ontology; - GError *error = NULL; - - fixture->test_path = g_build_filename (g_get_tmp_dir (), - "tracker-test-XXXXXX", - NULL); - fixture->test_path = g_mkdtemp (fixture->test_path); - fixture->test_file = g_file_new_for_path (fixture->test_path); - - data_loc = g_file_get_child (fixture->test_file, ".data"); - ontology = g_file_new_for_path (TEST_ONTOLOGIES_DIR); - fixture->connection = tracker_sparql_connection_local_new (0, data_loc, data_loc, ontology, NULL, &error); - g_assert_no_error (error); - - fixture->ops = NULL; - - /* Create basic folders within the test location */ - CREATE_FOLDER (fixture, "recursive"); - CREATE_FOLDER (fixture, "non-recursive"); - CREATE_FOLDER (fixture, "non-indexed"); - - fixture->indexing_tree = tracker_indexing_tree_new (); - tracker_indexing_tree_set_filter_hidden (fixture->indexing_tree, TRUE); - - fixture->main_loop = g_main_loop_new (NULL, FALSE); - fixture->notifier = tracker_file_notifier_new (fixture->indexing_tree, FALSE, - fixture->connection); - - g_signal_connect (fixture->notifier, "file-created", - G_CALLBACK (file_notifier_file_created_cb), fixture); - g_signal_connect (fixture->notifier, "file-updated", - G_CALLBACK (file_notifier_file_updated_cb), fixture); - g_signal_connect (fixture->notifier, "file-deleted", - G_CALLBACK (file_notifier_file_deleted_cb), fixture); - g_signal_connect (fixture->notifier, "file-moved", - G_CALLBACK (file_notifier_file_moved_cb), fixture); - g_signal_connect (fixture->notifier, "finished", - G_CALLBACK (file_notifier_finished_cb), fixture); -} - -static void -test_common_context_teardown (TestCommonContext *fixture, - gconstpointer data) -{ - g_list_foreach (fixture->ops, (GFunc) filesystem_operation_free, NULL); - g_list_free (fixture->ops); - - if (fixture->notifier) { - g_object_unref (fixture->notifier); - } - - if (fixture->indexing_tree) { - g_object_unref (fixture->indexing_tree); - } - - if (fixture->test_file) { - g_object_unref (fixture->test_file); - } - - DELETE_FOLDER (fixture, NULL); - - if (fixture->test_path) { - g_free (fixture->test_path); - } - - g_clear_object (&fixture->connection); - g_main_loop_unref (fixture->main_loop); -} - -static gboolean -timeout_expired_cb (gpointer user_data) -{ - TestCommonContext *fixture = user_data; - - fixture->expire_timeout_id = 0; - g_main_loop_quit (fixture->main_loop); - - return FALSE; -} - -static void -test_common_context_expect_results (TestCommonContext *fixture, - FilesystemOperation *results, - guint n_results, - guint max_timeout, - gboolean expect_finished) -{ - GList *ops; - guint i, id; - - fixture->expect_finished = expect_finished; - fixture->expect_n_results = n_results; - fixture->expect_results = results; - - if (fixture->expect_n_results != g_list_length (fixture->ops)) { - if (max_timeout != 0) { - id = g_timeout_add_seconds (max_timeout, - (GSourceFunc) timeout_expired_cb, - fixture); - fixture->expire_timeout_id = id; - } - - g_main_loop_run (fixture->main_loop); - - if (max_timeout != 0 && fixture->expire_timeout_id != 0) { - g_source_remove (fixture->expire_timeout_id); - } - } - - for (i = 0; i < n_results; i++) { - gboolean matched = FALSE; - - ops = fixture->ops; - - while (ops) { - FilesystemOperation *op = ops->data; - - if (op->op == results[i].op && - g_strcmp0 (op->path, results[i].path) == 0 && - g_strcmp0 (op->other_path, results[i].other_path) == 0) { - filesystem_operation_free (op); - fixture->ops = g_list_delete_link (fixture->ops, ops); - matched = TRUE; - break; - } - - ops = ops->next; - } - - if (!matched) { - if (results[i].op == OPERATION_MOVE) { - g_critical ("Expected operation %d on %s (-> %s) didn't happen", - results[i].op, results[i].path, - results[i].other_path); - } else { - g_critical ("Expected operation %d on %s didn't happen", - results[i].op, results[i].path); - } - } - } - - ops = fixture->ops; - - while (ops) { - FilesystemOperation *op = ops->data; - - if (op->op == OPERATION_MOVE) { - g_critical ("Unexpected operation %d on %s (-> %s) happened", - op->op, op->path, - op->other_path); - } else { - g_critical ("Unexpected operation %d on %s happened", - op->op, op->path); - } - } - - g_assert_cmpint (g_list_length (fixture->ops), ==, 0); -} - -static void -test_file_notifier_crawling_non_recursive (TestCommonContext *fixture, - gconstpointer data) -{ - FilesystemOperation expected_results[] = { - { OPERATION_CREATE, "non-recursive", NULL }, - { OPERATION_CREATE, "non-recursive/folder", NULL }, - { OPERATION_CREATE, "non-recursive/bbb", NULL }, - }; - - CREATE_FOLDER (fixture, "non-recursive/folder"); - CREATE_UPDATE_FILE (fixture, "non-recursive/folder/aaa"); - CREATE_UPDATE_FILE (fixture, "non-recursive/bbb"); - - test_common_context_index_dir (fixture, "non-recursive", - TRACKER_DIRECTORY_FLAG_CHECK_MTIME); - - tracker_file_notifier_start (fixture->notifier); - - test_common_context_expect_results (fixture, expected_results, - G_N_ELEMENTS (expected_results), - 2, TRUE); - - tracker_file_notifier_stop (fixture->notifier); -} - -static void -test_file_notifier_crawling_recursive (TestCommonContext *fixture, - gconstpointer data) -{ - FilesystemOperation expected_results[] = { - { OPERATION_CREATE, "recursive", NULL }, - { OPERATION_CREATE, "recursive/folder", NULL }, - { OPERATION_CREATE, "recursive/folder/aaa", NULL }, - { OPERATION_CREATE, "recursive/bbb", NULL }, - }; - - CREATE_FOLDER (fixture, "recursive/folder"); - CREATE_UPDATE_FILE (fixture, "recursive/folder/aaa"); - CREATE_UPDATE_FILE (fixture, "recursive/bbb"); - - test_common_context_index_dir (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_RECURSE | - TRACKER_DIRECTORY_FLAG_CHECK_MTIME); - - tracker_file_notifier_start (fixture->notifier); - - test_common_context_expect_results (fixture, expected_results, - G_N_ELEMENTS (expected_results), - 2, TRUE); - - tracker_file_notifier_stop (fixture->notifier); -} - -static void -test_file_notifier_crawling_non_recursive_within_recursive (TestCommonContext *fixture, - gconstpointer data) -{ - FilesystemOperation expected_results[] = { - { OPERATION_CREATE, "recursive", NULL }, - { OPERATION_CREATE, "recursive/folder", NULL }, - { OPERATION_CREATE, "recursive/folder/aaa", NULL }, - { OPERATION_CREATE, "recursive/bbb", NULL }, - { OPERATION_CREATE, "recursive/folder/non-recursive", NULL }, - { OPERATION_CREATE, "recursive/folder/non-recursive/ccc", NULL }, - { OPERATION_CREATE, "recursive/folder/non-recursive/folder", NULL }, - }; - - CREATE_FOLDER (fixture, "recursive/folder"); - CREATE_UPDATE_FILE (fixture, "recursive/folder/aaa"); - CREATE_UPDATE_FILE (fixture, "recursive/bbb"); - CREATE_FOLDER (fixture, "recursive/folder/non-recursive"); - CREATE_UPDATE_FILE (fixture, "recursive/folder/non-recursive/ccc"); - CREATE_FOLDER (fixture, "recursive/folder/non-recursive/folder"); - CREATE_UPDATE_FILE (fixture, "recursive/folder/non-recursive/folder/ddd"); - - test_common_context_index_dir (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_RECURSE | - TRACKER_DIRECTORY_FLAG_CHECK_MTIME); - test_common_context_index_dir (fixture, "recursive/folder/non-recursive", - TRACKER_DIRECTORY_FLAG_NONE | - TRACKER_DIRECTORY_FLAG_CHECK_MTIME); - - tracker_file_notifier_start (fixture->notifier); - - test_common_context_expect_results (fixture, expected_results, - G_N_ELEMENTS (expected_results), - 2, TRUE); - - tracker_file_notifier_stop (fixture->notifier); -} - -static void -test_file_notifier_crawling_recursive_within_non_recursive (TestCommonContext *fixture, - gconstpointer data) -{ - FilesystemOperation expected_results[] = { - { OPERATION_CREATE, "non-recursive", NULL }, - { OPERATION_CREATE, "non-recursive/folder", NULL }, - { OPERATION_CREATE, "non-recursive/bbb", NULL }, - { OPERATION_CREATE, "non-recursive/folder/recursive", NULL }, - { OPERATION_CREATE, "non-recursive/folder/recursive/ccc", NULL }, - { OPERATION_CREATE, "non-recursive/folder/recursive/folder", NULL }, - { OPERATION_CREATE, "non-recursive/folder/recursive/folder/ddd", NULL }, - }; - - CREATE_FOLDER (fixture, "non-recursive/folder"); - CREATE_UPDATE_FILE (fixture, "non-recursive/folder/aaa"); - CREATE_UPDATE_FILE (fixture, "non-recursive/bbb"); - CREATE_FOLDER (fixture, "non-recursive/folder/recursive"); - CREATE_UPDATE_FILE (fixture, "non-recursive/folder/recursive/ccc"); - CREATE_FOLDER (fixture, "non-recursive/folder/recursive/folder"); - CREATE_UPDATE_FILE (fixture, "non-recursive/folder/recursive/folder/ddd"); - - test_common_context_index_dir (fixture, "non-recursive/folder/recursive", - TRACKER_DIRECTORY_FLAG_RECURSE | - TRACKER_DIRECTORY_FLAG_CHECK_MTIME); - test_common_context_index_dir (fixture, "non-recursive", - TRACKER_DIRECTORY_FLAG_NONE | - TRACKER_DIRECTORY_FLAG_CHECK_MTIME); - - tracker_file_notifier_start (fixture->notifier); - - test_common_context_expect_results (fixture, expected_results, - G_N_ELEMENTS (expected_results), - 2, TRUE); - - tracker_file_notifier_stop (fixture->notifier); -} - -static void -test_file_notifier_crawling_ignore_within_recursive (TestCommonContext *fixture, - gconstpointer data) -{ - FilesystemOperation expected_results[] = { - { OPERATION_CREATE, "recursive", NULL }, - { OPERATION_CREATE, "recursive/folder", NULL }, - { OPERATION_CREATE, "recursive/folder/aaa", NULL }, - { OPERATION_CREATE, "recursive/bbb", NULL }, - { OPERATION_DELETE, "recursive/folder/ignore", NULL } - }; - - CREATE_FOLDER (fixture, "recursive/folder"); - CREATE_UPDATE_FILE (fixture, "recursive/folder/aaa"); - CREATE_UPDATE_FILE (fixture, "recursive/bbb"); - CREATE_FOLDER (fixture, "recursive/folder/ignore"); - CREATE_UPDATE_FILE (fixture, "recursive/folder/ignore/ccc"); - CREATE_FOLDER (fixture, "recursive/folder/ignore/folder"); - CREATE_UPDATE_FILE (fixture, "recursive/folder/ignore/folder/ddd"); - - test_common_context_index_dir (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_RECURSE | - TRACKER_DIRECTORY_FLAG_CHECK_MTIME); - test_common_context_index_dir (fixture, "recursive/folder/ignore", - TRACKER_DIRECTORY_FLAG_IGNORE | - TRACKER_DIRECTORY_FLAG_CHECK_MTIME); - - tracker_file_notifier_start (fixture->notifier); - - test_common_context_expect_results (fixture, expected_results, - G_N_ELEMENTS (expected_results), - 2, TRUE); - - tracker_file_notifier_stop (fixture->notifier); -} - -static void -test_file_notifier_changes_remove_non_recursive (TestCommonContext *fixture, - gconstpointer data) -{ - FilesystemOperation expected_results[] = { - { OPERATION_DELETE, "non-recursive", NULL } - }; - - test_file_notifier_crawling_non_recursive (fixture, data); - - test_common_context_remove_dir (fixture, "non-recursive"); - tracker_file_notifier_start (fixture->notifier); - test_common_context_expect_results (fixture, expected_results, - G_N_ELEMENTS (expected_results), - 1, FALSE); - tracker_file_notifier_stop (fixture->notifier); -} - -static void -test_file_notifier_changes_remove_recursive (TestCommonContext *fixture, - gconstpointer data) -{ - FilesystemOperation expected_results[] = { - { OPERATION_DELETE, "recursive", NULL } - }; - - test_file_notifier_crawling_recursive (fixture, data); - - test_common_context_remove_dir (fixture, "recursive"); - tracker_file_notifier_start (fixture->notifier); - test_common_context_expect_results (fixture, expected_results, - G_N_ELEMENTS (expected_results), - 1, FALSE); - tracker_file_notifier_stop (fixture->notifier); -} - -static void -test_file_notifier_changes_remove_ignore (TestCommonContext *fixture, - gconstpointer data) -{ - FilesystemOperation expected_results[] = { - { OPERATION_CREATE, "recursive/folder/ignore", NULL }, - { OPERATION_CREATE, "recursive/folder/ignore/ccc", NULL }, - { OPERATION_CREATE, "recursive/folder/ignore/folder", NULL }, - { OPERATION_CREATE, "recursive/folder/ignore/folder/ddd", NULL } - }; - FilesystemOperation expected_results2[] = { - { OPERATION_DELETE, "recursive/folder/ignore", NULL } - }; - - /* Start off from ignore test case */ - test_file_notifier_crawling_ignore_within_recursive (fixture, data); - - /* Remove ignored folder */ - test_common_context_remove_dir (fixture, "recursive/folder/ignore"); - tracker_file_notifier_start (fixture->notifier); - test_common_context_expect_results (fixture, expected_results, - G_N_ELEMENTS (expected_results), - 1, FALSE); - tracker_file_notifier_stop (fixture->notifier); - - /* And add it back */ - fixture->expect_n_results = G_N_ELEMENTS (expected_results2); - test_common_context_index_dir (fixture, "recursive/folder/ignore", - TRACKER_DIRECTORY_FLAG_IGNORE); - tracker_file_notifier_start (fixture->notifier); - test_common_context_expect_results (fixture, expected_results2, - G_N_ELEMENTS (expected_results2), - 1, FALSE); - tracker_file_notifier_stop (fixture->notifier); -} - -static void -test_file_notifier_monitor_updates_non_recursive (TestCommonContext *fixture, - gconstpointer data) -{ - FilesystemOperation expected_results[] = { - { OPERATION_CREATE, "non-recursive", NULL }, - { OPERATION_CREATE, "non-recursive/folder", NULL }, - { OPERATION_CREATE, "non-recursive/bbb", NULL } - }; - FilesystemOperation expected_results2[] = { - { OPERATION_CREATE, "non-recursive", NULL }, - { OPERATION_UPDATE, "non-recursive/bbb", NULL }, - { OPERATION_CREATE, "non-recursive/ccc", NULL }, - { OPERATION_UPDATE, "non-recursive/ccc", NULL } - }; - FilesystemOperation expected_results3[] = { - { OPERATION_DELETE, "non-recursive/folder", NULL }, - { OPERATION_DELETE, "non-recursive/ccc", NULL } - }; - - CREATE_FOLDER (fixture, "non-recursive/folder"); - CREATE_UPDATE_FILE (fixture, "non-recursive/bbb"); - - test_common_context_index_dir (fixture, "non-recursive", - TRACKER_DIRECTORY_FLAG_MONITOR | - TRACKER_DIRECTORY_FLAG_CHECK_MTIME); - - tracker_file_notifier_start (fixture->notifier); - test_common_context_expect_results (fixture, expected_results, - G_N_ELEMENTS (expected_results), - 2, TRUE); - tracker_file_notifier_stop (fixture->notifier); - - /* Perform file updates */ - tracker_file_notifier_start (fixture->notifier); - CREATE_UPDATE_FILE (fixture, "non-recursive/folder/aaa"); - CREATE_UPDATE_FILE (fixture, "non-recursive/bbb"); - CREATE_UPDATE_FILE (fixture, "non-recursive/ccc"); - test_common_context_expect_results (fixture, expected_results2, - G_N_ELEMENTS (expected_results2), - 3, FALSE); - - DELETE_FILE (fixture, "non-recursive/ccc"); - DELETE_FOLDER (fixture, "non-recursive/folder"); - test_common_context_expect_results (fixture, expected_results3, - G_N_ELEMENTS (expected_results3), - 3, FALSE); - tracker_file_notifier_stop (fixture->notifier); -} - -static void -test_file_notifier_monitor_updates_recursive (TestCommonContext *fixture, - gconstpointer data) -{ - FilesystemOperation expected_results[] = { - { OPERATION_CREATE, "recursive", NULL }, - { OPERATION_CREATE, "recursive/bbb", NULL } - }; - FilesystemOperation expected_results2[] = { - { OPERATION_CREATE, "recursive", NULL }, - { OPERATION_CREATE, "recursive/folder", NULL }, - { OPERATION_CREATE, "recursive/folder/aaa", NULL }, - { OPERATION_UPDATE, "recursive/bbb", NULL }, - }; - FilesystemOperation expected_results3[] = { - { OPERATION_DELETE, "recursive/folder", NULL }, - { OPERATION_DELETE, "recursive/bbb", NULL } - }; - - CREATE_UPDATE_FILE (fixture, "recursive/bbb"); - - test_common_context_index_dir (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_RECURSE | - TRACKER_DIRECTORY_FLAG_MONITOR | - TRACKER_DIRECTORY_FLAG_CHECK_MTIME); - - tracker_file_notifier_start (fixture->notifier); - test_common_context_expect_results (fixture, expected_results, - G_N_ELEMENTS (expected_results), - 2, TRUE); - tracker_file_notifier_stop (fixture->notifier); - - /* Perform file updates */ - tracker_file_notifier_start (fixture->notifier); - CREATE_FOLDER (fixture, "recursive/folder"); - CREATE_UPDATE_FILE (fixture, "recursive/folder/aaa"); - CREATE_UPDATE_FILE (fixture, "recursive/bbb"); - test_common_context_expect_results (fixture, expected_results2, - G_N_ELEMENTS (expected_results2), - 5, FALSE); - - DELETE_FILE (fixture, "recursive/bbb"); - DELETE_FOLDER (fixture, "recursive/folder"); - test_common_context_expect_results (fixture, expected_results3, - G_N_ELEMENTS (expected_results3), - 5, FALSE); - tracker_file_notifier_stop (fixture->notifier); -} - -gint -main (gint argc, - gchar **argv) -{ - setlocale (LC_ALL, ""); - - g_test_init (&argc, &argv, NULL); - - g_test_message ("Testing file notifier"); - - /* Crawling */ - test_add ("/libtracker-miner/file-notifier/crawling-non-recursive", - test_file_notifier_crawling_non_recursive); - test_add ("/libtracker-miner/file-notifier/crawling-recursive", - test_file_notifier_crawling_recursive); - test_add ("/libtracker-miner/file-notifier/crawling-non-recursive-within-recursive", - test_file_notifier_crawling_non_recursive_within_recursive); - test_add ("/libtracker-miner/file-notifier/crawling-recursive-within-non-recursive", - test_file_notifier_crawling_recursive_within_non_recursive); - test_add ("/libtracker-miner/file-notifier/crawling-ignore-within-recursive", - test_file_notifier_crawling_ignore_within_recursive); - - /* Config changes */ - test_add ("/libtracker-miner/file-notifier/changes-remove-non-recursive", - test_file_notifier_changes_remove_non_recursive); - test_add ("/libtracker-miner/file-notifier/changes-remove-recursive", - test_file_notifier_changes_remove_recursive); - test_add ("/libtracker-miner/file-notifier/changes-remove-ignore", - test_file_notifier_changes_remove_ignore); - - /* Monitoring */ - test_add ("/libtracker-miner/file-notifier/monitor-updates-non-recursive", - test_file_notifier_monitor_updates_non_recursive); - test_add ("/libtracker-miner/file-notifier/monitor-updates-recursive", - test_file_notifier_monitor_updates_recursive); - - return g_test_run (); -} diff --git a/tests/libtracker-miner/tracker-file-system-test.c b/tests/libtracker-miner/tracker-file-system-test.c deleted file mode 100644 index c7919a7d1..000000000 --- a/tests/libtracker-miner/tracker-file-system-test.c +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright (C) 2011, Nokia <ivan.frade@nokia.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ -#include <string.h> -#include <unistd.h> - -#include <glib.h> -#include <glib/gstdio.h> - -#include <libtracker-miner/tracker-file-system.h> - -/* Fixture struct */ -typedef struct { - /* The filesystem to test */ - TrackerFileSystem *file_system; -} TestCommonContext; - -#define test_add(path,fun) \ - g_test_add (path, \ - TestCommonContext, \ - NULL, \ - test_common_context_setup, \ - fun, \ - test_common_context_teardown) - -static void -test_common_context_setup (TestCommonContext *fixture, - gconstpointer data) -{ - fixture->file_system = tracker_file_system_new (NULL); -} - -static void -test_common_context_teardown (TestCommonContext *fixture, - gconstpointer data) -{ - if (fixture->file_system) - g_object_unref (fixture->file_system); -} - -static void -test_file_system_insertions (TestCommonContext *fixture, - gconstpointer data) -{ - GFile *file, *canonical, *other; - - file = g_file_new_for_uri ("file:///aaa/"); - canonical = tracker_file_system_peek_file (fixture->file_system, file); - g_assert (canonical == NULL); - - canonical = tracker_file_system_get_file (fixture->file_system, file, - G_FILE_TYPE_DIRECTORY, NULL); - g_object_unref (file); - - g_assert (canonical != NULL); - - file = g_file_new_for_uri ("file:///aaa/"); - other = tracker_file_system_get_file (fixture->file_system, file, - G_FILE_TYPE_DIRECTORY, NULL); - g_assert (canonical == other); - - other = tracker_file_system_peek_file (fixture->file_system, file); - g_object_unref (file); - g_assert (other != NULL); -} - -static void -test_file_system_children (TestCommonContext *fixture, - gconstpointer data) -{ - GFile *file, *parent, *child, *other; - - file = g_file_new_for_uri ("file:///aaa/"); - parent = tracker_file_system_get_file (fixture->file_system, file, - G_FILE_TYPE_DIRECTORY, NULL); - g_object_unref (file); - - file = g_file_new_for_uri ("file:///aaa/bbb"); - child = tracker_file_system_get_file (fixture->file_system, file, - G_FILE_TYPE_REGULAR, parent); - g_assert (child != NULL); - g_object_unref (file); - - file = g_file_new_for_uri ("file:///aaa/bbb"); - other = tracker_file_system_get_file (fixture->file_system, file, - G_FILE_TYPE_REGULAR, NULL); - g_assert (other != NULL); - g_assert (child == other); - - g_object_unref (file); -} - -static void -test_file_system_indirect_children (TestCommonContext *fixture, - gconstpointer data) -{ - GFile *file, *parent, *child, *other; - - file = g_file_new_for_uri ("file:///aaa/"); - parent = tracker_file_system_get_file (fixture->file_system, file, - G_FILE_TYPE_DIRECTORY, NULL); - g_object_unref (file); - - file = g_file_new_for_uri ("file:///aaa/bbb/ccc"); - child = tracker_file_system_get_file (fixture->file_system, file, - G_FILE_TYPE_REGULAR, parent); - g_assert (child != NULL); - g_object_unref (file); - - file = g_file_new_for_uri ("file:///aaa/bbb/ccc"); - other = tracker_file_system_get_file (fixture->file_system, file, - G_FILE_TYPE_REGULAR, NULL); - g_assert (other != NULL); - g_assert (child == other); - - /* FIXME: check missing parent in between */ - - g_object_unref (file); -} - -static void -test_file_system_reparenting (TestCommonContext *fixture, - gconstpointer data) -{ - GFile *file, *parent, *child, *grandchild, *other; - - file = g_file_new_for_uri ("file:///aaa/"); - parent = tracker_file_system_get_file (fixture->file_system, file, - G_FILE_TYPE_DIRECTORY, NULL); - g_object_unref (file); - - file = g_file_new_for_uri ("file:///aaa/bbb/ccc"); - grandchild = tracker_file_system_get_file (fixture->file_system, file, - G_FILE_TYPE_REGULAR, parent); - g_assert (grandchild != NULL); - g_object_unref (file); - - file = g_file_new_for_uri ("file:///aaa/bbb"); - child = tracker_file_system_get_file (fixture->file_system, file, - G_FILE_TYPE_REGULAR, parent); - g_assert (child != NULL); - g_object_unref (file); - - file = g_file_new_for_uri ("file:///aaa/bbb/ccc"); - other = tracker_file_system_peek_file (fixture->file_system, file); - g_assert (other != NULL); - g_assert (grandchild == other); - g_object_unref (file); - - /* Delete child in between */ - g_object_unref (child); - - /* Check that child doesn't exist anymore */ - file = g_file_new_for_uri ("file:///aaa/bbb"); - child = tracker_file_system_peek_file (fixture->file_system, file); - g_assert (child == NULL); - g_object_unref (file); - - /* Check that grand child still exists */ - file = g_file_new_for_uri ("file:///aaa/bbb/ccc"); - other = tracker_file_system_peek_file (fixture->file_system, file); - g_assert (other != NULL); - g_assert (grandchild == other); - g_object_unref (file); -} - -static void -test_file_system_properties (TestCommonContext *fixture, - gconstpointer data) -{ - GQuark property1_quark, property2_quark; - gchar *value = "value"; - gchar *ret_value; - GFile *file, *f; - - property1_quark = g_quark_from_string ("file-system-test-property1"); - tracker_file_system_register_property (property1_quark, - NULL); - property2_quark = g_quark_from_string ("file-system-test-property2"); - tracker_file_system_register_property (property2_quark, - NULL); - - f = g_file_new_for_uri ("file:///aaa/"); - file = tracker_file_system_get_file (fixture->file_system, f, - G_FILE_TYPE_REGULAR, NULL); - g_object_unref (f); - - /* Set both properties */ - tracker_file_system_set_property (fixture->file_system, file, - property1_quark, value); - tracker_file_system_set_property (fixture->file_system, file, - property2_quark, value); - - /* Check second property and remove it */ - ret_value = tracker_file_system_get_property (fixture->file_system, - file, property2_quark); - g_assert (ret_value == value); - - tracker_file_system_unset_property (fixture->file_system, - file, property2_quark); - - ret_value = tracker_file_system_get_property (fixture->file_system, - file, property2_quark); - g_assert (ret_value == NULL); - - /* Check first property and remove it */ - ret_value = tracker_file_system_get_property (fixture->file_system, - file, property1_quark); - g_assert (ret_value == value); - - tracker_file_system_unset_property (fixture->file_system, - file, property1_quark); - - ret_value = tracker_file_system_get_property (fixture->file_system, - file, property1_quark); - g_assert (ret_value == NULL); -} - -gint -main (gint argc, - gchar **argv) -{ - g_test_init (&argc, &argv, NULL); - - g_test_message ("Testing file system abstraction"); - - test_add ("/libtracker-miner/file-system/insertions", - test_file_system_insertions); - test_add ("/libtracker-miner/file-system/children", - test_file_system_children); - test_add ("/libtracker-miner/file-system/indirect-children", - test_file_system_indirect_children); - test_add ("/libtracker-miner/file-system/reparenting", - test_file_system_reparenting); - test_add ("/libtracker-miner/file-system/file-properties", - test_file_system_properties); - - return g_test_run (); -} diff --git a/tests/libtracker-miner/tracker-indexing-tree-test.c b/tests/libtracker-miner/tracker-indexing-tree-test.c deleted file mode 100644 index 78b874c1d..000000000 --- a/tests/libtracker-miner/tracker-indexing-tree-test.c +++ /dev/null @@ -1,986 +0,0 @@ -/* - * Copyright (C) 2011, Nokia <ivan.frade@nokia.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include <string.h> -#include <unistd.h> - -#include <glib.h> -#include <glib/gstdio.h> - -#include <libtracker-miner/tracker-indexing-tree.h> - -/* - * Test directory structure: - * - Directory A - * -- Directory AA - * --- Directory AAA - * ---- Directory AAAA - * ---- Directory AAAB - * --- Directory AAB - * -- Directory AB - * --- Directory ABA - * --- Directory ABB - */ -typedef enum { - TEST_DIRECTORY_A = 0, - TEST_DIRECTORY_AA, - TEST_DIRECTORY_AAA, - TEST_DIRECTORY_AAAA, - TEST_DIRECTORY_AAAB, - TEST_DIRECTORY_AAB, - TEST_DIRECTORY_AB, - TEST_DIRECTORY_ABA, - TEST_DIRECTORY_ABB, - TEST_DIRECTORY_LAST -} TestDirectory; - -/* Fixture struct */ -typedef struct { - /* Array with all existing test directories */ - GFile *test_dir[TEST_DIRECTORY_LAST]; - /* The tree to test */ - TrackerIndexingTree *tree; -} TestCommonContext; - -#define ASSERT_INDEXABLE(fixture, id) \ - g_assert (tracker_indexing_tree_file_is_indexable (fixture->tree, \ - fixture->test_dir[id], \ - G_FILE_TYPE_DIRECTORY) == TRUE) -#define ASSERT_NOT_INDEXABLE(fixture, id) \ - g_assert (tracker_indexing_tree_file_is_indexable (fixture->tree, \ - fixture->test_dir[id], \ - G_FILE_TYPE_DIRECTORY) == FALSE) - -#define test_add(path,fun) \ - g_test_add (path, \ - TestCommonContext, \ - NULL, \ - test_common_context_setup, \ - fun, \ - test_common_context_teardown) - -static void -test_common_context_setup (TestCommonContext *fixture, - gconstpointer data) -{ - guint i; - static const gchar *test_directories_subpaths [TEST_DIRECTORY_LAST] = { - "/A", - "/A/A", - "/A/A/A", - "/A/A/A/A", - "/A/A/A/B", - "/A/A/B", - "/A/B/", - "/A/B/A", - "/A/B/B" - }; - - /* Initialize aux directories */ - for (i = 0; i < TEST_DIRECTORY_LAST; i++) - fixture->test_dir[i] = g_file_new_for_path (test_directories_subpaths[i]); - - fixture->tree = tracker_indexing_tree_new (); -} - -static void -test_common_context_teardown (TestCommonContext *fixture, - gconstpointer data) -{ - gint i; - - /* Deinit aux directories, from last to first */ - for (i = TEST_DIRECTORY_LAST-1; i >= 0; i--) { - if (fixture->test_dir[i]) - g_object_unref (fixture->test_dir[i]); - } - - if (fixture->tree) - g_object_unref (fixture->tree); -} - -/* If A is ignored, - * -A, AA, AB, AAA, AAB, ABA and ABB are not indexable - */ -static void -test_indexing_tree_001 (TestCommonContext *fixture, - gconstpointer data) -{ - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A], - TRACKER_DIRECTORY_FLAG_IGNORE); - - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_A); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); -} - -/* If A is monitored (NOT recursively): - * -A, AA, AB are indexable - * -AAA, AAB, ABA and ABB are not indexable - */ -static void -test_indexing_tree_002 (TestCommonContext *fixture, - gconstpointer data) -{ - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A], - TRACKER_DIRECTORY_FLAG_MONITOR); - - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_A); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAB); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); -} - -/* If A is monitored (recursively): - * -A, AA, AB, AAA, AAB, ABA and ABB are indexable - */ -static void -test_indexing_tree_003 (TestCommonContext *fixture, - gconstpointer data) -{ - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A], - TRACKER_DIRECTORY_FLAG_MONITOR | TRACKER_DIRECTORY_FLAG_RECURSE); - - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_A); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAAA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAAB); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAB); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AB); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); -} - -/* If A is ignored and AA is ignored: - * -A, AA, AB, AAA, AAB, ABA and ABB are not indexable - */ -static void -test_indexing_tree_004 (TestCommonContext *fixture, - gconstpointer data) -{ - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A], - TRACKER_DIRECTORY_FLAG_IGNORE); - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_AA], - TRACKER_DIRECTORY_FLAG_IGNORE); - - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_A); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); -} - -/* If A is ignored and AA is monitored (not recursively): - * -AA, AAA, AAB are indexable - * -A, AAAA, AAAB, AB, ABA, ABB are not indexable - */ -static void -test_indexing_tree_005 (TestCommonContext *fixture, - gconstpointer data) -{ - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A], - TRACKER_DIRECTORY_FLAG_IGNORE); - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_AA], - TRACKER_DIRECTORY_FLAG_MONITOR); - - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_A); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAB); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); -} - -/* If A is ignored and AA is monitored (recursively): - * -AA, AAA, AAAA, AAAB, AAB are indexable - * -A, AB, ABA, ABB are not indexable - */ -static void -test_indexing_tree_006 (TestCommonContext *fixture, - gconstpointer data) -{ - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A], - TRACKER_DIRECTORY_FLAG_IGNORE); - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_AA], - TRACKER_DIRECTORY_FLAG_MONITOR | TRACKER_DIRECTORY_FLAG_RECURSE); - - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_A); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAAA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAAB); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); -} - -/* If A is monitored (not recursively) and AA is ignored: - * -A and AB are indexable - * -AA, AAA, AAAA, AAAB, AAB, ABA, ABB are not indexable - */ -static void -test_indexing_tree_007 (TestCommonContext *fixture, - gconstpointer data) -{ - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A], - TRACKER_DIRECTORY_FLAG_MONITOR); - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_AA], - TRACKER_DIRECTORY_FLAG_IGNORE); - - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_A); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAB); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); -} - -/* If A is monitored (not recursively) and AA is monitored (not recursively): - * -A, AA, AAA, AAB, AB are indexable - * -AAAA, AAAB, ABA, ABB are not indexable - */ -static void -test_indexing_tree_008 (TestCommonContext *fixture, - gconstpointer data) -{ - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A], - TRACKER_DIRECTORY_FLAG_MONITOR); - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_AA], - TRACKER_DIRECTORY_FLAG_MONITOR); - - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_A); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAB); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAB); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); -} - -/* If A is monitored (not recursively) and AA is monitored (recursively): - * -A, AA, AAA, AAAA, AAAB, AAB, AB are indexable - * -ABA, ABB are not indexable - */ -static void -test_indexing_tree_009 (TestCommonContext *fixture, - gconstpointer data) -{ - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A], - TRACKER_DIRECTORY_FLAG_MONITOR); - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_AA], - TRACKER_DIRECTORY_FLAG_MONITOR | TRACKER_DIRECTORY_FLAG_RECURSE); - - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_A); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAAA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAAB); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAB); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); -} - -/* If A is monitored (recursively) and AA is ignored: - * -A, AB, ABA, ABB are indexable - * -AA, AAA, AAAA, AAAB, AAB are not indexable - */ -static void -test_indexing_tree_010 (TestCommonContext *fixture, - gconstpointer data) -{ - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A], - TRACKER_DIRECTORY_FLAG_MONITOR | TRACKER_DIRECTORY_FLAG_RECURSE); - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_AA], - TRACKER_DIRECTORY_FLAG_IGNORE); - - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_A); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAB); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AB); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); -} - -/* If A is monitored (recursively) and AA is monitored (not recursively): - * -A, AA, AAA, AAB, AB, ABA, ABB are indexable - * -AAAA, AAAB are not indexable - */ -static void -test_indexing_tree_011 (TestCommonContext *fixture, - gconstpointer data) -{ - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A], - TRACKER_DIRECTORY_FLAG_MONITOR | TRACKER_DIRECTORY_FLAG_RECURSE); - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_AA], - TRACKER_DIRECTORY_FLAG_MONITOR); - - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_A); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAB); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAB); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AB); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); -} - -/* If A is monitored (recursively) and AA is monitored (recursively): - * -A, AA, AAA, AAAA, AAAB, AAB, AB, ABA, ABB are indexable - */ -static void -test_indexing_tree_012 (TestCommonContext *fixture, - gconstpointer data) -{ - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A], - TRACKER_DIRECTORY_FLAG_MONITOR | TRACKER_DIRECTORY_FLAG_RECURSE); - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_AA], - TRACKER_DIRECTORY_FLAG_MONITOR | TRACKER_DIRECTORY_FLAG_RECURSE); - - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_A); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAAA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAAB); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAB); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AB); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); -} - -/* If A is ignored and AA is ignored, then A is removed from tree - * -A, AA, AAA, AAAA, AAAB, AAB, AB, ABA and ABB are not indexable - */ -static void -test_indexing_tree_013 (TestCommonContext *fixture, - gconstpointer data) -{ - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A], - TRACKER_DIRECTORY_FLAG_IGNORE); - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_AA], - TRACKER_DIRECTORY_FLAG_IGNORE); - - tracker_indexing_tree_remove (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A]); - - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_A); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); -} - -/* If A is ignored and AA is ignored, then AA is removed from tree - * -A, AA, AAA, AAAA, AAAB, AAB, AB, ABA and ABB are not indexable - */ -static void -test_indexing_tree_014 (TestCommonContext *fixture, - gconstpointer data) -{ - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A], - TRACKER_DIRECTORY_FLAG_IGNORE); - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_AA], - TRACKER_DIRECTORY_FLAG_IGNORE); - - tracker_indexing_tree_remove (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_AA]); - - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_A); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); -} - -/* If A is ignored and AA is monitored (not recursively), then A is removed - * from tree. - * -AA, AAA, AAB are indexable - * -A, AAAA, AAAB, AB, ABA and ABB are not indexable - */ -static void -test_indexing_tree_015 (TestCommonContext *fixture, - gconstpointer data) -{ - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A], - TRACKER_DIRECTORY_FLAG_IGNORE); - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_AA], - TRACKER_DIRECTORY_FLAG_MONITOR); - - tracker_indexing_tree_remove (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A]); - - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_A); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAB); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); -} - -/* If A is ignored and AA is monitored (not recursively), then AA is removed - * from tree. - * -A, AA, AAA, AAAA, AAAB, AAB, AB, ABA and ABB are not indexable - */ -static void -test_indexing_tree_016 (TestCommonContext *fixture, - gconstpointer data) -{ - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A], - TRACKER_DIRECTORY_FLAG_IGNORE); - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_AA], - TRACKER_DIRECTORY_FLAG_MONITOR); - - tracker_indexing_tree_remove (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_AA]); - - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_A); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); -} - -/* If A is ignored and AA is monitored (recursively), then A is removed from - * tree. - * -AA, AAA, AAAA, AAAB, AAB are indexable - * -A, AB, ABA and ABB are not indexable - */ -static void -test_indexing_tree_017 (TestCommonContext *fixture, - gconstpointer data) -{ - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A], - TRACKER_DIRECTORY_FLAG_IGNORE); - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_AA], - TRACKER_DIRECTORY_FLAG_MONITOR | TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_indexing_tree_remove (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A]); - - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_A); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAAA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAAB); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); -} - -/* If A is ignored and AA is monitored (recursively), then AA is removed - * from tree. - * -A, AA, AAA, AAAA, AAAB, AAB, AB, ABA and ABB are not indexable - */ -static void -test_indexing_tree_018 (TestCommonContext *fixture, - gconstpointer data) -{ - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A], - TRACKER_DIRECTORY_FLAG_IGNORE); - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_AA], - TRACKER_DIRECTORY_FLAG_MONITOR | TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_indexing_tree_remove (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_AA]); - - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_A); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); -} - -/* If A is monitored (not recursively) and AA is ignored, then A is removed - * from tree. - * -A, AA, AAA, AAAA, AAAB, AAB, AB, ABA and ABB are not indexable - */ -static void -test_indexing_tree_019 (TestCommonContext *fixture, - gconstpointer data) -{ - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A], - TRACKER_DIRECTORY_FLAG_MONITOR); - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_AA], - TRACKER_DIRECTORY_FLAG_IGNORE); - - tracker_indexing_tree_remove (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A]); - - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_A); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); -} - -/* If A is monitored (not recursively) and AA is ignored, then AA is removed - * from tree. - * -A, AA, AB are indexable. - * -AAA, AAAA, AAAB, AAB, ABA and ABB are not indexable - */ -static void -test_indexing_tree_020 (TestCommonContext *fixture, - gconstpointer data) -{ - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A], - TRACKER_DIRECTORY_FLAG_MONITOR); - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_AA], - TRACKER_DIRECTORY_FLAG_IGNORE); - - tracker_indexing_tree_remove (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_AA]); - - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_A); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAB); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); -} - -/* If A is monitored (not recursively) and AA is monitored (not recursively), - * then A is removed from tree. - * -AA, AAA, AAB are indexable. - * -A, AAAA, AAAB, AB, ABA and ABB are not indexable - */ -static void -test_indexing_tree_021 (TestCommonContext *fixture, - gconstpointer data) -{ - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A], - TRACKER_DIRECTORY_FLAG_MONITOR); - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_AA], - TRACKER_DIRECTORY_FLAG_MONITOR); - - tracker_indexing_tree_remove (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A]); - - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_A); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAB); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); -} - -/* If A is monitored (not recursively) and AA is monitored (not recursively), - * then AA is removed from tree. - * -A, AA, AB are indexable. - * -AAA, AAAA, AAAB, AAB, ABA and ABB are not indexable - */ -static void -test_indexing_tree_022 (TestCommonContext *fixture, - gconstpointer data) -{ - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A], - TRACKER_DIRECTORY_FLAG_MONITOR); - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_AA], - TRACKER_DIRECTORY_FLAG_MONITOR); - - tracker_indexing_tree_remove (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_AA]); - - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_A); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAB); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); -} - -/* If A is monitored (not recursively) and AA is monitored (recursively), - * then A is removed from tree. - * -AA, AAA, AAAA, AAAB, AAB are indexable. - * -A, AB, ABA and ABB are not indexable - */ -static void -test_indexing_tree_023 (TestCommonContext *fixture, - gconstpointer data) -{ - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A], - TRACKER_DIRECTORY_FLAG_MONITOR); - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_AA], - TRACKER_DIRECTORY_FLAG_MONITOR | TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_indexing_tree_remove (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A]); - - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_A); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAAA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAAB); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); -} - -/* If A is monitored (not recursively) and AA is monitored (recursively), - * then AA is removed from tree. - * -A, AA, AB are indexable. - * -AAA, AAAA, AAAB, AAB, ABA and ABB are not indexable - */ -static void -test_indexing_tree_024 (TestCommonContext *fixture, - gconstpointer data) -{ - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A], - TRACKER_DIRECTORY_FLAG_MONITOR); - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_AA], - TRACKER_DIRECTORY_FLAG_MONITOR | TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_indexing_tree_remove (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_AA]); - - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_A); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAB); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); -} - -/* If A is monitored (recursively) and AA is ignored, then A is removed - * from tree. - * -A, AA, AAA, AAAA, AAAB, AAB, AB, ABA and ABB are not indexable - */ -static void -test_indexing_tree_025 (TestCommonContext *fixture, - gconstpointer data) -{ - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A], - TRACKER_DIRECTORY_FLAG_MONITOR | TRACKER_DIRECTORY_FLAG_RECURSE); - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_AA], - TRACKER_DIRECTORY_FLAG_IGNORE); - - tracker_indexing_tree_remove (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A]); - - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_A); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); -} - -/* If A is monitored (recursively) and AA is ignored, then AA is removed - * from tree. - * -A, AA, AAA, AAAA, AAAB, AAB, AB, ABA and ABB are indexable - */ -static void -test_indexing_tree_026 (TestCommonContext *fixture, - gconstpointer data) -{ - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A], - TRACKER_DIRECTORY_FLAG_MONITOR | TRACKER_DIRECTORY_FLAG_RECURSE); - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_AA], - TRACKER_DIRECTORY_FLAG_IGNORE); - - tracker_indexing_tree_remove (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_AA]); - - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_A); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAAA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAAB); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAB); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AB); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); -} - -/* If A is monitored (recursively) and AA is monitored (not recursively), then - * A is removed from tree. - * -AA, AAA, AAB are indexable - * -A, AAAA, AAAB, AB, ABA and ABB are not indexable - */ -static void -test_indexing_tree_027 (TestCommonContext *fixture, - gconstpointer data) -{ - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A], - TRACKER_DIRECTORY_FLAG_MONITOR | TRACKER_DIRECTORY_FLAG_RECURSE); - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_AA], - TRACKER_DIRECTORY_FLAG_MONITOR); - - tracker_indexing_tree_remove (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A]); - - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_A); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AAAB); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); -} - -/* If A is monitored (recursively) and AA is monitored (not recursively), then - * AA is removed from tree. - * -A, AA, AAA, AAAA, AAAB, AAB, AB, ABA and ABB are indexable - */ -static void -test_indexing_tree_028 (TestCommonContext *fixture, - gconstpointer data) -{ - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A], - TRACKER_DIRECTORY_FLAG_MONITOR | TRACKER_DIRECTORY_FLAG_RECURSE); - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_AA], - TRACKER_DIRECTORY_FLAG_MONITOR); - - tracker_indexing_tree_remove (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_AA]); - - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_A); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAAA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAAB); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAB); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AB); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); -} - -/* If A is monitored (recursively) and AA is monitored (recursively), - * then A is removed from tree. - * -AA, AAA, AAAA, AAAB, AAB are indexable - * -A, AB, ABA and ABB are not indexable - */ -static void -test_indexing_tree_029 (TestCommonContext *fixture, - gconstpointer data) -{ - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A], - TRACKER_DIRECTORY_FLAG_MONITOR | TRACKER_DIRECTORY_FLAG_RECURSE); - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_AA], - TRACKER_DIRECTORY_FLAG_MONITOR | TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_indexing_tree_remove (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A]); - - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_A); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAAA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAAB); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_AB); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); - ASSERT_NOT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); -} - -/* If A is monitored (recursively) and AA is monitored (recursively), - * then AA is removed from tree. - * -A, AA, AAA, AAAA, AAAB, AAB, AB, ABA and ABB are indexable - */ -static void -test_indexing_tree_030 (TestCommonContext *fixture, - gconstpointer data) -{ - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_A], - TRACKER_DIRECTORY_FLAG_MONITOR | TRACKER_DIRECTORY_FLAG_RECURSE); - tracker_indexing_tree_add (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_AA], - TRACKER_DIRECTORY_FLAG_MONITOR | TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_indexing_tree_remove (fixture->tree, - fixture->test_dir[TEST_DIRECTORY_AA]); - - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_A); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAAA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAAB); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AAB); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_AB); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); - ASSERT_INDEXABLE (fixture, TEST_DIRECTORY_ABA); -} - -gint -main (gint argc, - gchar **argv) -{ - g_test_init (&argc, &argv, NULL); - - g_test_message ("Testing indexing tree"); - - test_add ("/libtracker-miner/indexing-tree/001", test_indexing_tree_001); - test_add ("/libtracker-miner/indexing-tree/002", test_indexing_tree_002); - test_add ("/libtracker-miner/indexing-tree/003", test_indexing_tree_003); - test_add ("/libtracker-miner/indexing-tree/004", test_indexing_tree_004); - test_add ("/libtracker-miner/indexing-tree/005", test_indexing_tree_005); - test_add ("/libtracker-miner/indexing-tree/006", test_indexing_tree_006); - test_add ("/libtracker-miner/indexing-tree/007", test_indexing_tree_007); - test_add ("/libtracker-miner/indexing-tree/008", test_indexing_tree_008); - test_add ("/libtracker-miner/indexing-tree/009", test_indexing_tree_009); - test_add ("/libtracker-miner/indexing-tree/010", test_indexing_tree_010); - test_add ("/libtracker-miner/indexing-tree/011", test_indexing_tree_011); - test_add ("/libtracker-miner/indexing-tree/012", test_indexing_tree_012); - test_add ("/libtracker-miner/indexing-tree/013", test_indexing_tree_013); - test_add ("/libtracker-miner/indexing-tree/014", test_indexing_tree_014); - test_add ("/libtracker-miner/indexing-tree/015", test_indexing_tree_015); - test_add ("/libtracker-miner/indexing-tree/016", test_indexing_tree_016); - test_add ("/libtracker-miner/indexing-tree/017", test_indexing_tree_017); - test_add ("/libtracker-miner/indexing-tree/018", test_indexing_tree_018); - test_add ("/libtracker-miner/indexing-tree/019", test_indexing_tree_019); - test_add ("/libtracker-miner/indexing-tree/020", test_indexing_tree_020); - test_add ("/libtracker-miner/indexing-tree/021", test_indexing_tree_021); - test_add ("/libtracker-miner/indexing-tree/022", test_indexing_tree_022); - test_add ("/libtracker-miner/indexing-tree/023", test_indexing_tree_023); - test_add ("/libtracker-miner/indexing-tree/024", test_indexing_tree_024); - test_add ("/libtracker-miner/indexing-tree/025", test_indexing_tree_025); - test_add ("/libtracker-miner/indexing-tree/026", test_indexing_tree_026); - test_add ("/libtracker-miner/indexing-tree/027", test_indexing_tree_027); - test_add ("/libtracker-miner/indexing-tree/028", test_indexing_tree_028); - test_add ("/libtracker-miner/indexing-tree/029", test_indexing_tree_029); - test_add ("/libtracker-miner/indexing-tree/030", test_indexing_tree_030); - - return g_test_run (); -} diff --git a/tests/libtracker-miner/tracker-miner-fs-test.c b/tests/libtracker-miner/tracker-miner-fs-test.c deleted file mode 100644 index 39a48f959..000000000 --- a/tests/libtracker-miner/tracker-miner-fs-test.c +++ /dev/null @@ -1,2256 +0,0 @@ -#include <glib.h> -#include <libtracker-miner/tracker-miner.h> -#include <libtracker-common/tracker-common.h> - -typedef struct { - TrackerMinerFS parent_instance; - guint n_process_file; - guint n_events; - guint finished : 1; -} TestMiner; - -typedef struct { - TrackerMinerFSClass parent_class; -} TestMinerClass; - -/* Fixture object type */ -typedef struct { - TrackerMinerFS *miner; - TrackerSparqlConnection *connection; - gchar *test_root_path; - GFile *test_root; -} TrackerMinerFSTestFixture; - -G_DEFINE_TYPE (TestMiner, test_miner, TRACKER_TYPE_MINER_FS) - -#define ADD_TEST(name, func) \ - g_test_add ("/libtracker-miner/tracker-miner-fs/" name, \ - TrackerMinerFSTestFixture, NULL, \ - fixture_setup, func, fixture_teardown) - -static gboolean -test_miner_process_file (TrackerMinerFS *miner, - GFile *file, - GTask *task) -{ - TrackerResource *resource; - GError *error = NULL; - GFileInfo *info; - GTimeVal timeval; - gchar *sparql, *str; - gchar *urn; - GFile *parent; - - ((TestMiner *) miner)->n_process_file++; - info = g_file_query_info (file, "standard::*,time::*", 0, NULL, &error); - g_assert_no_error (error); - - urn = tracker_miner_fs_query_urn (miner, file); - if (g_strcmp0 (tracker_miner_fs_get_urn (miner, file), urn) != 0) { - g_critical ("File %s did not get up to date URN", - g_file_get_uri (file)); - } - g_free (urn); - - resource = tracker_resource_new (tracker_miner_fs_get_urn (miner, file)); - - if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) { - tracker_resource_add_uri (resource, "rdf:type", "nfo:Folder"); - } - - tracker_resource_add_uri (resource, "rdf:type", "nfo:FileDataObject"); - - g_file_info_get_modification_time (info, &timeval); - str = tracker_date_to_string (timeval.tv_sec, 0); - tracker_resource_set_string (resource, "nfo:fileLastModified", str); - g_free (str); - - str = g_file_get_uri (file); - tracker_resource_set_string (resource, "nie:url", str); - g_free (str); - - parent = g_file_get_parent (file); - urn = tracker_miner_fs_query_urn (miner, parent); - g_object_unref (parent); - - if (urn) { - tracker_resource_set_string (resource, "nfo:belongsToContainer", urn); - g_free (urn); - } - - sparql = tracker_resource_print_sparql_update (resource, NULL, TRACKER_OWN_GRAPH_URN); - tracker_miner_fs_notify_finish (miner, task, sparql, NULL); - g_object_unref (resource); - g_free (sparql); - g_object_unref (info); - - return TRUE; -} - -static gchar * -test_miner_remove_file (TrackerMinerFS *miner, - GFile *file) -{ - gchar *sparql, *uri; - - uri = g_file_get_uri (file); - sparql = g_strdup_printf ("WITH <" TRACKER_OWN_GRAPH_URN "> " - "DELETE {" - " ?u a rdfs:Resource . " - "} WHERE {" - " ?u nie:url ?url ." - " FILTER (?url = '%s' || STRSTARTS (?url, '%s/'))" - "}", uri, uri); - g_free (uri); - - return sparql; -} - -static gchar * -test_miner_remove_children (TrackerMinerFS *miner, - GFile *file) -{ - gchar *sparql, *uri; - - uri = g_file_get_uri (file); - sparql = g_strdup_printf ("WITH <" TRACKER_OWN_GRAPH_URN "> " - "DELETE {" - " ?u a rdfs:Resource . " - "} WHERE {" - " ?u nie:url ?url ." - " FILTER (STRSTARTS (?url, '%s/'))" - "}", uri); - g_free (uri); - - return sparql; -} - -static gchar * -test_miner_move_file (TrackerMinerFS *miner, - GFile *dest, - GFile *source, - gboolean recursive) -{ - gchar *sparql, *uri, *dest_uri; - - uri = g_file_get_uri (source); - dest_uri = g_file_get_uri (dest); - sparql = g_strdup_printf ("WITH <" TRACKER_OWN_GRAPH_URN "> " - "DELETE {" - " ?u nie:url ?url . " - "} INSERT {" - " ?u nie:url '%s' . " - "} WHERE {" - " ?u nie:url ?url . " - " FILTER (?url = '%s')" - "}", dest_uri, uri); - g_free (dest_uri); - g_free (uri); - - return sparql; -} - -static gboolean -test_miner_filter_event (TrackerMinerFS *miner, - TrackerMinerFSEventType type, - GFile *file, - GFile *source_file) -{ - TestMiner *m = (TestMiner *) miner; - - m->n_events++; - return FALSE; -} - -static void -test_miner_finished (TrackerMinerFS *miner, - gdouble elapsed, - gint directories_found, - gint directories_ignored, - gint files_found, - gint files_ignored) -{ - ((TestMiner *) miner)->finished = TRUE; -} - -static void -test_miner_class_init (TestMinerClass *klass) -{ - TrackerMinerFSClass *fs_class = TRACKER_MINER_FS_CLASS (klass); - - fs_class->process_file = test_miner_process_file; - fs_class->process_file_attributes = test_miner_process_file; - fs_class->remove_file = test_miner_remove_file; - fs_class->remove_children = test_miner_remove_children; - fs_class->move_file = test_miner_move_file; - fs_class->filter_event = test_miner_filter_event; - - fs_class->finished = test_miner_finished; -} - -static void -test_miner_init (TestMiner *miner) -{ -} - -static TrackerMinerFS * -test_miner_new (TrackerSparqlConnection *conn, - GError **error) -{ - return g_initable_new (test_miner_get_type (), - NULL, error, - "connection", conn, - NULL); -} - -static gboolean -test_miner_is_finished (TestMiner *miner) -{ - gboolean finished; - - finished = miner->finished; - miner->finished = FALSE; - - return finished; -} - -static void -test_miner_reset_counters (TestMiner *miner) -{ - miner->n_process_file = 0; - miner->n_events = 0; -} - -static void -perform_file_operation (TrackerMinerFSTestFixture *fixture, - gchar *command, - gchar *filename, - gchar *other_filename) -{ - gchar *path, *other_path, *call; - - path = g_build_filename (fixture->test_root_path, filename, NULL); - - if (other_filename) { - other_path = g_build_filename (fixture->test_root_path, other_filename, NULL); - call = g_strdup_printf ("%s %s %s", command, path, other_path); - g_free (other_path); - } else { - call = g_strdup_printf ("%s %s", command, path); - } - - system (call); - - g_free (call); - g_free (path); -} - -#define CREATE_FOLDER(fixture,p) perform_file_operation((fixture),"mkdir",(p),NULL) -#define CREATE_UPDATE_FILE(fixture,p) perform_file_operation((fixture),"touch",(p),NULL) -#define DELETE_FILE(fixture,p) perform_file_operation((fixture),"rm",(p),NULL) -#define DELETE_FOLDER(fixture,p) perform_file_operation((fixture),"rm -rf",(p),NULL) -#define MOVE_FILE(fixture,p1,p2) perform_file_operation((fixture),"mv",(p1),(p2)) -#define UPDATE_FILE_ATOMIC(fixture,p,tmpname) \ - G_STMT_START { \ - CREATE_UPDATE_FILE((fixture), (tmpname)); \ - MOVE_FILE ((fixture), (tmpname), (p)); \ - } G_STMT_END - -static void -fixture_setup (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - GError *error = NULL; - GFile *file, *ontology; - gchar *path; - - path = g_build_filename (g_get_tmp_dir (), "tracker-miner-fs-test-XXXXXX", NULL); - fixture->test_root_path = g_mkdtemp_full (path, 0700); - fixture->test_root = g_file_new_for_path (fixture->test_root_path); - - file = g_file_get_child (fixture->test_root, ".db"); - ontology = g_file_new_for_path (TEST_ONTOLOGIES_DIR); - fixture->connection = tracker_sparql_connection_local_new (0, file, file, ontology, NULL, &error); - g_assert_no_error (error); - g_object_unref (file); - g_object_unref (ontology); - - fixture->miner = test_miner_new (fixture->connection, &error); - g_assert_no_error (error); -} - -static void -fixture_teardown (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - DELETE_FOLDER (fixture, "/"); - - g_object_unref (fixture->test_root); - g_object_unref (fixture->miner); - g_object_unref (fixture->connection); - g_free (fixture->test_root_path); -} - -static GFile * -fixture_get_relative_file (TrackerMinerFSTestFixture *fixture, - const gchar *rel_path) -{ - GFile *file; - gchar *path; - - path = g_build_filename (fixture->test_root_path, rel_path, NULL); - file = g_file_new_for_path (path); - g_free (path); - - return file; -} - -static void -fixture_add_indexed_folder (TrackerMinerFSTestFixture *fixture, - const gchar *rel_path, - TrackerDirectoryFlags flags) -{ - GFile *file; - - file = fixture_get_relative_file (fixture, rel_path); - tracker_indexing_tree_add (tracker_miner_fs_get_indexing_tree (fixture->miner), - file, flags); - g_object_unref (file); -} - -static void -fixture_remove_indexed_folder (TrackerMinerFSTestFixture *fixture, - const gchar *rel_path) -{ - GFile *file; - - file = fixture_get_relative_file (fixture, rel_path); - tracker_indexing_tree_remove (tracker_miner_fs_get_indexing_tree (fixture->miner), - file); - g_object_unref (file); -} - -static gboolean -fixture_query_exists (TrackerMinerFSTestFixture *fixture, - const gchar *rel_path) -{ - GFile *file = fixture_get_relative_file (fixture, rel_path); - TrackerSparqlCursor *cursor; - gchar *sparql, *uri; - GError *error = NULL; - - uri = g_file_get_uri (file); - sparql = g_strdup_printf ("SELECT ?u { ?u nie:url '%s' }", uri); - g_free (uri); - - cursor = tracker_sparql_connection_query (fixture->connection, sparql, - NULL, &error); - g_assert_no_error (error); - g_free (sparql); - - if (tracker_sparql_cursor_next (cursor, NULL, &error)) { - g_object_unref (cursor); - return TRUE; - } else { - g_assert_no_error (error); - return FALSE; - } -} - -static gchar * -fixture_get_content (TrackerMinerFSTestFixture *fixture) -{ - TrackerSparqlCursor *cursor; - GString *str = g_string_new (""); - GError *error = NULL; - gchar *query, *root_uri; - - root_uri = g_file_get_uri (fixture->test_root); - query = g_strdup_printf ("SELECT ?path " - "{ ?u a nfo:FileDataObject ;" - " nie:url ?url ." - " BIND (SUBSTR (?url, %d) AS ?path)" - "} ORDER BY ?path", - (int)strlen (root_uri) + 2); - g_free (root_uri); - - - cursor = tracker_sparql_connection_query (fixture->connection, query, - NULL, &error); - g_assert_no_error (error); - g_free (query); - - while (tracker_sparql_cursor_next (cursor, NULL, &error)) { - if (str->len > 0) - g_string_append_c (str, ','); - g_string_append (str, tracker_sparql_cursor_get_string (cursor, 0, NULL)); - } - - g_assert_no_error (error); - - tracker_sparql_cursor_close (cursor); - g_object_unref (cursor); - - return g_string_free (str, FALSE); -} - -static void -fixture_iterate (TrackerMinerFSTestFixture *fixture) -{ - while (!test_miner_is_finished ((TestMiner *) fixture->miner)) - g_main_context_iteration (NULL, TRUE); -} - -static void -fixture_iterate_filter (TrackerMinerFSTestFixture *fixture, - guint n_events) -{ - TestMiner *miner = (TestMiner *) fixture->miner; - - miner->n_events = 0; - - while (miner->n_events < n_events) - g_main_context_iteration (NULL, TRUE); -} - -static void -test_recursive_indexing (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - gchar *content; - - CREATE_FOLDER (fixture, "recursive"); - CREATE_FOLDER (fixture, "recursive/1"); - CREATE_FOLDER (fixture, "recursive/1/2"); - CREATE_FOLDER (fixture, "recursive/1/empty"); - CREATE_UPDATE_FILE (fixture, "recursive/1/a"); - CREATE_UPDATE_FILE (fixture, "recursive/1/b"); - CREATE_UPDATE_FILE (fixture, "recursive/1/2/c"); - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/1," - "recursive/1/2," - "recursive/1/2/c," - "recursive/1/a," - "recursive/1/b," - "recursive/1/empty"); - g_free (content); -} - -static void -test_non_recursive_indexing (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - gchar *content; - - CREATE_FOLDER (fixture, "non-recursive"); - CREATE_FOLDER (fixture, "non-recursive/1"); - CREATE_FOLDER (fixture, "non-recursive/1/2"); - CREATE_FOLDER (fixture, "non-recursive/empty"); - CREATE_UPDATE_FILE (fixture, "non-recursive/a"); - CREATE_UPDATE_FILE (fixture, "non-recursive/1/b"); - - fixture_add_indexed_folder (fixture, "non-recursive", - TRACKER_DIRECTORY_FLAG_CHECK_MTIME); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "non-recursive," - "non-recursive/1," - "non-recursive/a," - "non-recursive/empty"); - g_free (content); -} - -static void -test_separate_recursive_and_non_recursive (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - gchar *content; - - CREATE_FOLDER (fixture, "recursive"); - CREATE_FOLDER (fixture, "recursive/1"); - CREATE_FOLDER (fixture, "recursive/1/2"); - CREATE_FOLDER (fixture, "non-recursive"); - CREATE_FOLDER (fixture, "non-recursive/1"); - CREATE_FOLDER (fixture, "non-recursive/1/2"); - CREATE_UPDATE_FILE (fixture, "recursive/a"); - CREATE_UPDATE_FILE (fixture, "recursive/1/b"); - CREATE_UPDATE_FILE (fixture, "non-recursive/a"); - CREATE_UPDATE_FILE (fixture, "non-recursive/1/b"); - - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_RECURSE); - fixture_add_indexed_folder (fixture, "non-recursive", - TRACKER_DIRECTORY_FLAG_CHECK_MTIME); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "non-recursive," - "non-recursive/1," - "non-recursive/a," - "recursive," - "recursive/1," - "recursive/1/2," - "recursive/1/b," - "recursive/a"); - g_free (content); -} - -static void -test_recursive_in_non_recursive (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - gchar *content; - - CREATE_FOLDER (fixture, "non-recursive"); - CREATE_FOLDER (fixture, "non-recursive/1"); - CREATE_FOLDER (fixture, "non-recursive/1/recursive"); - CREATE_FOLDER (fixture, "non-recursive/1/recursive/2"); - CREATE_UPDATE_FILE (fixture, "non-recursive/a"); - CREATE_UPDATE_FILE (fixture, "non-recursive/1/b"); - CREATE_UPDATE_FILE (fixture, "non-recursive/1/recursive/c"); - CREATE_UPDATE_FILE (fixture, "non-recursive/1/recursive/2/d"); - - fixture_add_indexed_folder (fixture, "non-recursive/1/recursive", - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_RECURSE); - fixture_add_indexed_folder (fixture, "non-recursive", - TRACKER_DIRECTORY_FLAG_CHECK_MTIME); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "non-recursive," - "non-recursive/1," - "non-recursive/1/recursive," - "non-recursive/1/recursive/2," - "non-recursive/1/recursive/2/d," - "non-recursive/1/recursive/c," - "non-recursive/a"); - g_free (content); -} - -static void -test_non_recursive_in_recursive (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - gchar *content; - - CREATE_FOLDER (fixture, "recursive"); - CREATE_FOLDER (fixture, "recursive/1"); - CREATE_FOLDER (fixture, "recursive/1/non-recursive"); - CREATE_FOLDER (fixture, "recursive/1/non-recursive/2"); - CREATE_UPDATE_FILE (fixture, "recursive/a"); - CREATE_UPDATE_FILE (fixture, "recursive/1/b"); - CREATE_UPDATE_FILE (fixture, "recursive/1/non-recursive/c"); - CREATE_UPDATE_FILE (fixture, "recursive/1/non-recursive/2/d"); - - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_RECURSE); - fixture_add_indexed_folder (fixture, "recursive/1/non-recursive", - TRACKER_DIRECTORY_FLAG_CHECK_MTIME); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/1," - "recursive/1/b," - "recursive/1/non-recursive," - "recursive/1/non-recursive/2," - "recursive/1/non-recursive/c," - "recursive/a"); - g_free (content); -} - -static void -test_empty_root (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - gchar *content; - - CREATE_FOLDER (fixture, "empty"); - - fixture_add_indexed_folder (fixture, "empty", - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, "empty"); - g_free (content); -} - -static void -test_missing_root (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - gchar *content; - - fixture_add_indexed_folder (fixture, "missing", - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, ""); - g_free (content); -} - -static void -test_skip_hidden_files (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - TrackerIndexingTree *indexing_tree; - gchar *content; - - CREATE_FOLDER (fixture, "recursive"); - CREATE_FOLDER (fixture, "recursive/1"); - CREATE_FOLDER (fixture, "recursive/1/.hidden"); - CREATE_FOLDER (fixture, "recursive/1/.hidden/2"); - CREATE_UPDATE_FILE (fixture, "recursive/.hidden-file"); - CREATE_UPDATE_FILE (fixture, "recursive/1/.hidden/2/a"); - - indexing_tree = tracker_miner_fs_get_indexing_tree (fixture->miner); - tracker_indexing_tree_set_filter_hidden (indexing_tree, TRUE); - - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/1"); - g_free (content); -} - -static void -test_index_hidden_files (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - gchar *content; - - CREATE_FOLDER (fixture, "recursive"); - CREATE_FOLDER (fixture, "recursive/1"); - CREATE_FOLDER (fixture, "recursive/1/.hidden"); - CREATE_FOLDER (fixture, "recursive/1/.hidden/2"); - CREATE_UPDATE_FILE (fixture, "recursive/.hidden-file"); - CREATE_UPDATE_FILE (fixture, "recursive/1/.hidden/2/a"); - - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/.hidden-file," - "recursive/1," - "recursive/1/.hidden," - "recursive/1/.hidden/2," - "recursive/1/.hidden/2/a"); - g_free (content); -} - -static void -test_file_filter_default_accept (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - TrackerIndexingTree *indexing_tree; - gchar *content; - - CREATE_FOLDER (fixture, "recursive"); - CREATE_FOLDER (fixture, "recursive/aa"); - CREATE_FOLDER (fixture, "recursive/bb"); - CREATE_UPDATE_FILE (fixture, "recursive/aa/a1"); - CREATE_UPDATE_FILE (fixture, "recursive/aa/b2"); - CREATE_UPDATE_FILE (fixture, "recursive/bb/ab"); - CREATE_UPDATE_FILE (fixture, "recursive/bb/bb"); - - indexing_tree = tracker_miner_fs_get_indexing_tree (fixture->miner); - tracker_indexing_tree_set_default_policy (indexing_tree, - TRACKER_FILTER_FILE, - TRACKER_FILTER_POLICY_ACCEPT); - tracker_indexing_tree_add_filter (indexing_tree, TRACKER_FILTER_FILE, "a*"); - - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/aa," - "recursive/aa/b2," - "recursive/bb," - "recursive/bb/bb"); - g_free (content); -} - -static void -test_file_filter_default_deny (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - TrackerIndexingTree *indexing_tree; - gchar *content; - - CREATE_FOLDER (fixture, "recursive"); - CREATE_FOLDER (fixture, "recursive/aa"); - CREATE_FOLDER (fixture, "recursive/bb"); - CREATE_UPDATE_FILE (fixture, "recursive/aa/a1"); - CREATE_UPDATE_FILE (fixture, "recursive/aa/b2"); - CREATE_UPDATE_FILE (fixture, "recursive/bb/ab"); - CREATE_UPDATE_FILE (fixture, "recursive/bb/bb"); - - indexing_tree = tracker_miner_fs_get_indexing_tree (fixture->miner); - tracker_indexing_tree_set_default_policy (indexing_tree, - TRACKER_FILTER_FILE, - TRACKER_FILTER_POLICY_DENY); - tracker_indexing_tree_add_filter (indexing_tree, TRACKER_FILTER_FILE, "a*"); - - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/aa," - "recursive/aa/a1," - "recursive/bb," - "recursive/bb/ab"); - g_free (content); -} - -static void -test_directory_filter_default_accept (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - TrackerIndexingTree *indexing_tree; - gchar *content; - - CREATE_FOLDER (fixture, "recursive"); - CREATE_FOLDER (fixture, "recursive/aa"); - CREATE_FOLDER (fixture, "recursive/bb"); - CREATE_UPDATE_FILE (fixture, "recursive/aa/a1"); - CREATE_UPDATE_FILE (fixture, "recursive/aa/b2"); - CREATE_UPDATE_FILE (fixture, "recursive/bb/ab"); - CREATE_UPDATE_FILE (fixture, "recursive/bb/bb"); - - indexing_tree = tracker_miner_fs_get_indexing_tree (fixture->miner); - tracker_indexing_tree_set_default_policy (indexing_tree, - TRACKER_FILTER_DIRECTORY, - TRACKER_FILTER_POLICY_ACCEPT); - tracker_indexing_tree_add_filter (indexing_tree, TRACKER_FILTER_DIRECTORY, "a*"); - - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/bb," - "recursive/bb/ab," - "recursive/bb/bb"); - g_free (content); -} - -static void -test_directory_filter_default_deny (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - TrackerIndexingTree *indexing_tree; - gchar *content; - - CREATE_FOLDER (fixture, "recursive"); - CREATE_FOLDER (fixture, "recursive/aa"); - CREATE_FOLDER (fixture, "recursive/bb"); - CREATE_UPDATE_FILE (fixture, "recursive/aa/a1"); - CREATE_UPDATE_FILE (fixture, "recursive/aa/b2"); - CREATE_UPDATE_FILE (fixture, "recursive/bb/ab"); - CREATE_UPDATE_FILE (fixture, "recursive/bb/bb"); - - indexing_tree = tracker_miner_fs_get_indexing_tree (fixture->miner); - tracker_indexing_tree_set_default_policy (indexing_tree, - TRACKER_FILTER_DIRECTORY, - TRACKER_FILTER_POLICY_DENY); - tracker_indexing_tree_add_filter (indexing_tree, TRACKER_FILTER_DIRECTORY, "a*"); - - /* Guess what, the folder gets filtered otherwise */ - tracker_indexing_tree_add_filter (indexing_tree, TRACKER_FILTER_DIRECTORY, "recursive"); - - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/aa," - "recursive/aa/a1," - "recursive/aa/b2"); - g_free (content); -} - -static void -test_content_filter_default_accept (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - TrackerIndexingTree *indexing_tree; - gchar *content; - - CREATE_FOLDER (fixture, "recursive"); - CREATE_FOLDER (fixture, "recursive/aa"); - CREATE_FOLDER (fixture, "recursive/bb"); - CREATE_UPDATE_FILE (fixture, "recursive/aa/a1"); - CREATE_UPDATE_FILE (fixture, "recursive/aa/b2"); - CREATE_UPDATE_FILE (fixture, "recursive/aa/ignore"); - CREATE_UPDATE_FILE (fixture, "recursive/bb/ab"); - CREATE_UPDATE_FILE (fixture, "recursive/bb/bb"); - - indexing_tree = tracker_miner_fs_get_indexing_tree (fixture->miner); - tracker_indexing_tree_set_default_policy (indexing_tree, - TRACKER_FILTER_PARENT_DIRECTORY, - TRACKER_FILTER_POLICY_ACCEPT); - tracker_indexing_tree_add_filter (indexing_tree, - TRACKER_FILTER_PARENT_DIRECTORY, "ignore"); - - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/aa," - "recursive/bb," - "recursive/bb/ab," - "recursive/bb/bb"); - g_free (content); -} - -static void -test_content_filter_default_deny (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - TrackerIndexingTree *indexing_tree; - gchar *content; - - CREATE_FOLDER (fixture, "recursive"); - CREATE_FOLDER (fixture, "recursive/aa"); - CREATE_FOLDER (fixture, "recursive/bb"); - CREATE_UPDATE_FILE (fixture, "recursive/allow"); - CREATE_UPDATE_FILE (fixture, "recursive/aa/a1"); - CREATE_UPDATE_FILE (fixture, "recursive/aa/b2"); - CREATE_UPDATE_FILE (fixture, "recursive/aa/allow"); - CREATE_UPDATE_FILE (fixture, "recursive/bb/ab"); - CREATE_UPDATE_FILE (fixture, "recursive/bb/bb"); - - indexing_tree = tracker_miner_fs_get_indexing_tree (fixture->miner); - tracker_indexing_tree_set_default_policy (indexing_tree, - TRACKER_FILTER_PARENT_DIRECTORY, - TRACKER_FILTER_POLICY_DENY); - tracker_indexing_tree_add_filter (indexing_tree, - TRACKER_FILTER_PARENT_DIRECTORY, "allow"); - - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/aa," - "recursive/aa/a1," - "recursive/aa/allow," - "recursive/aa/b2," - "recursive/allow," - "recursive/bb"); - g_free (content); -} - -static void -test_content_filter_on_parent_root (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - TrackerIndexingTree *indexing_tree; - gchar *content; - - CREATE_FOLDER (fixture, "non-recursive"); - CREATE_FOLDER (fixture, "non-recursive/recursive"); - CREATE_FOLDER (fixture, "non-recursive/recursive/a"); - CREATE_UPDATE_FILE (fixture, "non-recursive/.ignore"); - CREATE_UPDATE_FILE (fixture, "non-recursive/recursive/c"); - CREATE_UPDATE_FILE (fixture, "non-recursive/recursive/a/d"); - - indexing_tree = tracker_miner_fs_get_indexing_tree (fixture->miner); - tracker_indexing_tree_set_filter_hidden (indexing_tree, TRUE); - tracker_indexing_tree_add_filter (indexing_tree, - TRACKER_FILTER_PARENT_DIRECTORY, ".ignore"); - - fixture_add_indexed_folder (fixture, "non-recursive", - TRACKER_DIRECTORY_FLAG_PRESERVE | - TRACKER_DIRECTORY_FLAG_CHECK_DELETED | - TRACKER_DIRECTORY_FLAG_CHECK_MTIME); - fixture_add_indexed_folder (fixture, "non-recursive/recursive", - TRACKER_DIRECTORY_FLAG_PRESERVE | - TRACKER_DIRECTORY_FLAG_CHECK_DELETED | - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "non-recursive," - "non-recursive/recursive," - "non-recursive/recursive/a," - "non-recursive/recursive/a/d," - "non-recursive/recursive/c"); - g_free (content); - - /* Check it is ok after the content is already indexed. All - * files should stay and no events should be generated as - * there's no changes. - */ - fixture_remove_indexed_folder (fixture, "non-recursive"); - fixture_remove_indexed_folder (fixture, "non-recursive/recursive"); - - fixture_add_indexed_folder (fixture, "non-recursive", - TRACKER_DIRECTORY_FLAG_PRESERVE | - TRACKER_DIRECTORY_FLAG_CHECK_DELETED | - TRACKER_DIRECTORY_FLAG_CHECK_MTIME); - fixture_add_indexed_folder (fixture, "non-recursive/recursive", - TRACKER_DIRECTORY_FLAG_PRESERVE | - TRACKER_DIRECTORY_FLAG_CHECK_DELETED | - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_RECURSE); - - test_miner_reset_counters ((TestMiner *) fixture->miner); - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "non-recursive," - "non-recursive/recursive," - "non-recursive/recursive/a," - "non-recursive/recursive/a/d," - "non-recursive/recursive/c"); - g_free (content); - - g_assert_cmpint (((TestMiner *) fixture->miner)->n_events, ==, 0); -} - -static void -test_non_monitored_create (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - gchar *content; - - CREATE_FOLDER (fixture, "recursive"); - CREATE_UPDATE_FILE (fixture, "recursive/a"); - - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_PRESERVE | - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/a"); - g_free (content); - - fixture_remove_indexed_folder (fixture, "recursive"); - - CREATE_FOLDER (fixture, "recursive/new"); - CREATE_UPDATE_FILE (fixture, "recursive/b"); - CREATE_UPDATE_FILE (fixture, "recursive/new/c"); - - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_RECURSE); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/a," - "recursive/b," - "recursive/new," - "recursive/new/c"); - g_free (content); -} - -static void -test_non_monitored_update (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - gchar *content; - - CREATE_FOLDER (fixture, "recursive"); - CREATE_UPDATE_FILE (fixture, "recursive/a"); - - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_PRESERVE | - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/a"); - g_free (content); - - fixture_remove_indexed_folder (fixture, "recursive"); - test_miner_reset_counters ((TestMiner *) fixture->miner); - - /* Ensure mtime will really change */ - sleep (1); - - UPDATE_FILE_ATOMIC (fixture, "recursive/a", "b"); - - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_RECURSE); - - fixture_iterate (fixture); - - g_assert_cmpint (((TestMiner *) fixture->miner)->n_process_file, >=, 1); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/a"); - g_free (content); -} - -static void -test_non_monitored_delete (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - gchar *content; - - CREATE_FOLDER (fixture, "recursive"); - CREATE_FOLDER (fixture, "recursive/1"); - CREATE_FOLDER (fixture, "recursive/1/2"); - CREATE_FOLDER (fixture, "recursive/1/2/3"); - CREATE_UPDATE_FILE (fixture, "recursive/a"); - CREATE_UPDATE_FILE (fixture, "recursive/1/2/b"); - CREATE_UPDATE_FILE (fixture, "recursive/1/2/3/c"); - - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_PRESERVE | - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_CHECK_DELETED | - TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/1," - "recursive/1/2," - "recursive/1/2/3," - "recursive/1/2/3/c," - "recursive/1/2/b," - "recursive/a"); - g_free (content); - - fixture_remove_indexed_folder (fixture, "recursive"); - - DELETE_FILE (fixture, "recursive/a"); - DELETE_FOLDER (fixture, "recursive/1/2"); - - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_CHECK_DELETED | - TRACKER_DIRECTORY_FLAG_RECURSE); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/1"); - g_free (content); -} - -static void -test_non_monitored_move (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - gchar *content; - - CREATE_FOLDER (fixture, "recursive"); - CREATE_FOLDER (fixture, "recursive/1"); - CREATE_FOLDER (fixture, "non-recursive"); - CREATE_FOLDER (fixture, "non-recursive/2"); - CREATE_FOLDER (fixture, "not-indexed/"); - CREATE_UPDATE_FILE (fixture, "recursive/a"); - CREATE_UPDATE_FILE (fixture, "recursive/1/b"); - CREATE_UPDATE_FILE (fixture, "non-recursive/2/c"); - CREATE_UPDATE_FILE (fixture, "recursive/d"); - - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_PRESERVE | - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_CHECK_DELETED | - TRACKER_DIRECTORY_FLAG_RECURSE); - fixture_add_indexed_folder (fixture, "non-recursive", - TRACKER_DIRECTORY_FLAG_PRESERVE | - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_CHECK_DELETED); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "non-recursive," - "non-recursive/2," - "recursive," - "recursive/1," - "recursive/1/b," - "recursive/a," - "recursive/d"); - g_free (content); - - fixture_remove_indexed_folder (fixture, "recursive"); - fixture_remove_indexed_folder (fixture, "non-recursive"); - - MOVE_FILE (fixture, "recursive/a", "non-recursive/e"); - MOVE_FILE (fixture, "recursive/1", "non-recursive/3"); - MOVE_FILE (fixture, "non-recursive/2", "recursive/4"); - MOVE_FILE (fixture, "recursive/d", "not-indexed/f"); - - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_CHECK_DELETED | - TRACKER_DIRECTORY_FLAG_RECURSE); - fixture_add_indexed_folder (fixture, "non-recursive", - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_CHECK_DELETED); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "non-recursive," - "non-recursive/3," - "non-recursive/e," - "recursive," - "recursive/4," - "recursive/4/c"); - g_free (content); -} - -static void -test_monitored_create (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - gchar *content; - - CREATE_FOLDER (fixture, "recursive"); - CREATE_UPDATE_FILE (fixture, "recursive/a"); - - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_MONITOR | - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/a"); - g_free (content); - - CREATE_FOLDER (fixture, "recursive/new"); - CREATE_UPDATE_FILE (fixture, "recursive/b"); - CREATE_UPDATE_FILE (fixture, "recursive/new/c"); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/a," - "recursive/b," - "recursive/new," - "recursive/new/c"); - g_free (content); -} - -static void -test_monitored_update (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - gchar *content; - - CREATE_FOLDER (fixture, "recursive"); - CREATE_UPDATE_FILE (fixture, "recursive/a"); - - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_MONITOR | - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/a"); - g_free (content); - - test_miner_reset_counters ((TestMiner *) fixture->miner); - - UPDATE_FILE_ATOMIC (fixture, "recursive/a", "b"); - - fixture_iterate (fixture); - - g_assert_cmpint (((TestMiner *) fixture->miner)->n_process_file, ==, 1); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/a"); - g_free (content); -} - -static void -test_monitored_delete (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - gchar *content; - gint n_tries = 0; - - CREATE_FOLDER (fixture, "recursive"); - CREATE_FOLDER (fixture, "recursive/1"); - CREATE_FOLDER (fixture, "recursive/1/2"); - CREATE_FOLDER (fixture, "recursive/1/2/3"); - CREATE_UPDATE_FILE (fixture, "recursive/a"); - CREATE_UPDATE_FILE (fixture, "recursive/1/2/b"); - CREATE_UPDATE_FILE (fixture, "recursive/1/2/3/c"); - - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_MONITOR | - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_CHECK_DELETED | - TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/1," - "recursive/1/2," - "recursive/1/2/3," - "recursive/1/2/3/c," - "recursive/1/2/b," - "recursive/a"); - g_free (content); - - DELETE_FOLDER (fixture, "recursive/1/2"); - - /* This may take several ::finished callbacks, never - * more than the number of files deleted, possibly less - * due to coalescing. - */ - while (fixture_query_exists (fixture, "recursive/1/2")) { - g_assert_cmpint (n_tries, <, 3); - fixture_iterate (fixture); - n_tries++; - } - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/1," - "recursive/a"); - g_free (content); - - DELETE_FILE (fixture, "recursive/a"); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/1"); - g_free (content); -} - -static void -test_monitored_move (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - gchar *content; - gint n_tries = 0; - - CREATE_FOLDER (fixture, "recursive"); - CREATE_FOLDER (fixture, "recursive/1"); - CREATE_FOLDER (fixture, "non-recursive"); - CREATE_FOLDER (fixture, "non-recursive/2"); - CREATE_FOLDER (fixture, "not-indexed/"); - CREATE_UPDATE_FILE (fixture, "recursive/a"); - CREATE_UPDATE_FILE (fixture, "recursive/1/b"); - CREATE_UPDATE_FILE (fixture, "non-recursive/2/c"); - CREATE_UPDATE_FILE (fixture, "recursive/d"); - - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_MONITOR | - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_CHECK_DELETED | - TRACKER_DIRECTORY_FLAG_RECURSE); - fixture_add_indexed_folder (fixture, "non-recursive", - TRACKER_DIRECTORY_FLAG_MONITOR | - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_CHECK_DELETED); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "non-recursive," - "non-recursive/2," - "recursive," - "recursive/1," - "recursive/1/b," - "recursive/a," - "recursive/d"); - g_free (content); - - MOVE_FILE (fixture, "recursive/a", "non-recursive/e"); - MOVE_FILE (fixture, "recursive/1", "non-recursive/3"); - MOVE_FILE (fixture, "recursive/d", "not-indexed/f"); - MOVE_FILE (fixture, "non-recursive/2", "recursive/4"); - - while (!fixture_query_exists (fixture, "recursive/4/c")) { - g_assert_cmpint (n_tries, <, 4); - fixture_iterate (fixture); - n_tries++; - } - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "non-recursive," - "non-recursive/3," - "non-recursive/e," - "recursive," - "recursive/4," - "recursive/4/c"); - g_free (content); -} - -static void -test_monitored_atomic_replace (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - gchar *content; - - CREATE_FOLDER (fixture, "recursive"); - CREATE_UPDATE_FILE (fixture, "recursive/a"); - - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_MONITOR | - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_CHECK_DELETED | - TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/a"); - g_free (content); - - UPDATE_FILE_ATOMIC (fixture, "recursive/a", "recursive/b"); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/a"); - g_free (content); -} - -static void -test_changes_after_no_mtime_check (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - gchar *content; - - CREATE_FOLDER (fixture, "recursive"); - CREATE_FOLDER (fixture, "recursive/1"); - CREATE_FOLDER (fixture, "recursive/1/2"); - CREATE_UPDATE_FILE (fixture, "recursive/a"); - CREATE_UPDATE_FILE (fixture, "recursive/1/2/b"); - - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_PRESERVE | - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_CHECK_DELETED | - TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/1," - "recursive/1/2," - "recursive/1/2/b," - "recursive/a"); - g_free (content); - - fixture_remove_indexed_folder (fixture, "recursive"); - - CREATE_FOLDER (fixture, "recursive/1/3"); - CREATE_UPDATE_FILE (fixture, "recursive/c"); - DELETE_FOLDER (fixture, "recursive/1/2"); - - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_MONITOR | - TRACKER_DIRECTORY_FLAG_RECURSE); - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/1," - "recursive/1/2," - "recursive/1/2/b," - "recursive/a"); - g_free (content); - - CREATE_UPDATE_FILE (fixture, "recursive/1/3/c"); - CREATE_UPDATE_FILE (fixture, "recursive/1/2"); - CREATE_UPDATE_FILE (fixture, "recursive/c"); - - while (!fixture_query_exists (fixture, "recursive/c")) - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/1," - "recursive/1/2," - "recursive/1/2/b," /* FIXME: this file should disappear */ - "recursive/1/3," - "recursive/1/3/c," - "recursive/a," - "recursive/c"); - g_free (content); -} - -static void -test_event_queue_create_and_update (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - gchar *content; - - CREATE_FOLDER (fixture, "recursive"); - - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_MONITOR | - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, "recursive"); - g_free (content); - - tracker_miner_pause (TRACKER_MINER (fixture->miner)); - - CREATE_UPDATE_FILE (fixture, "recursive/a"); - fixture_iterate_filter (fixture, 1); - UPDATE_FILE_ATOMIC (fixture, "recursive/a", "recursive/b"); - fixture_iterate_filter (fixture, 1); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, "recursive"); - g_free (content); - - tracker_miner_resume (TRACKER_MINER (fixture->miner)); - - g_assert_cmpint (((TestMiner *) fixture->miner)->n_process_file, ==, 1); - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/a"); - g_free (content); -} - -static void -test_event_queue_create_and_delete (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - gchar *content; - - CREATE_FOLDER (fixture, "recursive"); - - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_MONITOR | - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, "recursive"); - g_free (content); - - tracker_miner_pause (TRACKER_MINER (fixture->miner)); - - CREATE_UPDATE_FILE (fixture, "recursive/a"); - fixture_iterate_filter (fixture, 1); - g_assert (tracker_miner_fs_has_items_to_process (fixture->miner) == TRUE); - - DELETE_FILE (fixture, "recursive/a"); - fixture_iterate_filter (fixture, 1); - - tracker_miner_resume (TRACKER_MINER (fixture->miner)); - fixture_iterate (fixture); - g_assert (tracker_miner_fs_has_items_to_process (fixture->miner) == FALSE); -} - -static void -test_event_queue_create_and_move (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - gchar *content; - - CREATE_FOLDER (fixture, "recursive"); - - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_MONITOR | - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, "recursive"); - g_free (content); - - tracker_miner_pause (TRACKER_MINER (fixture->miner)); - - CREATE_UPDATE_FILE (fixture, "recursive/a"); - fixture_iterate_filter (fixture, 1); - MOVE_FILE (fixture, "recursive/a", "recursive/b"); - fixture_iterate_filter (fixture, 1); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, "recursive"); - g_free (content); - - tracker_miner_resume (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/b"); - g_free (content); -} - -static void -test_event_queue_update_and_update (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - gchar *content; - - CREATE_FOLDER (fixture, "recursive"); - CREATE_UPDATE_FILE (fixture, "recursive/a"); - - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_MONITOR | - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/a"); - g_free (content); - - tracker_miner_pause (TRACKER_MINER (fixture->miner)); - test_miner_reset_counters ((TestMiner *) fixture->miner); - - UPDATE_FILE_ATOMIC (fixture, "recursive/a", "b"); - fixture_iterate_filter (fixture, 1); - CREATE_UPDATE_FILE (fixture, "b"); - MOVE_FILE (fixture, "b", "recursive/a"); - fixture_iterate_filter (fixture, 1); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/a"); - g_free (content); - - tracker_miner_resume (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - /* Coalescing desirable, but not mandatory */ - g_assert_cmpint (((TestMiner *) fixture->miner)->n_process_file, >=, 1); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/a"); - g_free (content); -} - -static void -test_event_queue_update_and_delete (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - gchar *content; - - CREATE_FOLDER (fixture, "recursive"); - CREATE_UPDATE_FILE (fixture, "recursive/a"); - - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_MONITOR | - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/a"); - g_free (content); - - tracker_miner_pause (TRACKER_MINER (fixture->miner)); - - UPDATE_FILE_ATOMIC (fixture, "recursive/a", "b"); - fixture_iterate_filter (fixture, 1); - DELETE_FILE (fixture, "recursive/a"); - fixture_iterate_filter (fixture, 1); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/a"); - g_free (content); - - tracker_miner_resume (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, "recursive"); - g_free (content); -} - -static void -test_event_queue_update_and_move (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - gchar *content; - - CREATE_FOLDER (fixture, "recursive"); - CREATE_UPDATE_FILE (fixture, "recursive/a"); - - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_MONITOR | - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/a"); - g_free (content); - - tracker_miner_pause (TRACKER_MINER (fixture->miner)); - - DELETE_FILE (fixture, "recursive/a"); - CREATE_UPDATE_FILE (fixture, "recursive/a"); - fixture_iterate_filter (fixture, 1); - MOVE_FILE (fixture, "recursive/a", "recursive/b"); - fixture_iterate_filter (fixture, 1); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/a"); - g_free (content); - - tracker_miner_resume (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/b"); - g_free (content); -} - -static void -test_event_queue_delete_and_create (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - gchar *content; - - CREATE_FOLDER (fixture, "recursive"); - CREATE_UPDATE_FILE (fixture, "recursive/a"); - - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_MONITOR | - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/a"); - g_free (content); - - tracker_miner_pause (TRACKER_MINER (fixture->miner)); - - DELETE_FILE (fixture, "recursive/a"); - fixture_iterate_filter (fixture, 1); - CREATE_UPDATE_FILE (fixture, "recursive/a"); - fixture_iterate_filter (fixture, 1); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/a"); - g_free (content); - - tracker_miner_resume (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/a"); - g_free (content); -} - -static void -test_event_queue_move_and_update (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - gchar *content; - - CREATE_FOLDER (fixture, "recursive"); - CREATE_UPDATE_FILE (fixture, "recursive/a"); - - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_MONITOR | - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/a"); - g_free (content); - - tracker_miner_pause (TRACKER_MINER (fixture->miner)); - - test_miner_reset_counters ((TestMiner *) fixture->miner); - - MOVE_FILE (fixture, "recursive/a", "recursive/b"); - fixture_iterate_filter (fixture, 1); - UPDATE_FILE_ATOMIC (fixture, "recursive/b", "c"); - fixture_iterate_filter (fixture, 1); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/a"); - g_free (content); - - tracker_miner_resume (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - g_assert_cmpint (((TestMiner *) fixture->miner)->n_process_file, ==, 1); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/b"); - g_free (content); -} - -static void -test_event_queue_move_and_create_origin (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - gchar *content; - - CREATE_FOLDER (fixture, "recursive"); - CREATE_UPDATE_FILE (fixture, "recursive/a"); - - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_MONITOR | - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/a"); - g_free (content); - - tracker_miner_pause (TRACKER_MINER (fixture->miner)); - - MOVE_FILE (fixture, "recursive/a", "recursive/b"); - fixture_iterate_filter (fixture, 1); - CREATE_UPDATE_FILE (fixture, "recursive/a"); - fixture_iterate_filter (fixture, 1); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/a"); - g_free (content); - - tracker_miner_resume (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/a," - "recursive/b"); - g_free (content); -} - -static void -test_event_queue_move_and_delete (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - gchar *content; - - CREATE_FOLDER (fixture, "recursive"); - CREATE_UPDATE_FILE (fixture, "recursive/a"); - - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_MONITOR | - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/a"); - g_free (content); - - tracker_miner_pause (TRACKER_MINER (fixture->miner)); - - MOVE_FILE (fixture, "recursive/a", "recursive/b"); - fixture_iterate_filter (fixture, 1); - DELETE_FILE (fixture, "recursive/b"); - fixture_iterate_filter (fixture, 1); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/a"); - g_free (content); - - tracker_miner_resume (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive"); - g_free (content); -} - -static void -test_event_queue_move_and_move (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - gchar *content; - - CREATE_FOLDER (fixture, "recursive"); - CREATE_UPDATE_FILE (fixture, "recursive/a"); - - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_MONITOR | - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/a"); - g_free (content); - - tracker_miner_pause (TRACKER_MINER (fixture->miner)); - - MOVE_FILE (fixture, "recursive/a", "recursive/b"); - fixture_iterate_filter (fixture, 1); - MOVE_FILE (fixture, "recursive/b", "recursive/c"); - fixture_iterate_filter (fixture, 1); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/a"); - g_free (content); - - tracker_miner_resume (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/c"); - g_free (content); -} - -static void -test_event_queue_move_and_move_back (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - gchar *content; - - CREATE_FOLDER (fixture, "recursive"); - CREATE_UPDATE_FILE (fixture, "recursive/a"); - - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_MONITOR | - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/a"); - g_free (content); - - tracker_miner_pause (TRACKER_MINER (fixture->miner)); - - MOVE_FILE (fixture, "recursive/a", "recursive/b"); - fixture_iterate_filter (fixture, 1); - MOVE_FILE (fixture, "recursive/b", "recursive/a"); - fixture_iterate_filter (fixture, 1); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/a"); - g_free (content); - - tracker_miner_resume (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/a"); - g_free (content); -} - -static void -test_api_check_file (TrackerMinerFSTestFixture *fixture, - gconstpointer data) -{ - GFile *file; - gchar *content; - - CREATE_FOLDER (fixture, "recursive"); - CREATE_FOLDER (fixture, "not-indexed"); - CREATE_UPDATE_FILE (fixture, "recursive/a"); - CREATE_UPDATE_FILE (fixture, "not-indexed/b"); - CREATE_UPDATE_FILE (fixture, "not-indexed/c"); - - fixture_add_indexed_folder (fixture, "recursive", - TRACKER_DIRECTORY_FLAG_MONITOR | - TRACKER_DIRECTORY_FLAG_CHECK_MTIME | - TRACKER_DIRECTORY_FLAG_RECURSE); - - tracker_miner_start (TRACKER_MINER (fixture->miner)); - - fixture_iterate (fixture); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "recursive," - "recursive/a"); - g_free (content); - - test_miner_reset_counters ((TestMiner *) fixture->miner); - - file = fixture_get_relative_file (fixture, "recursive/a"); - tracker_miner_fs_check_file (fixture->miner, file, G_PRIORITY_DEFAULT, FALSE); - g_object_unref (file); - - file = fixture_get_relative_file (fixture, "not-indexed/b"); - tracker_miner_fs_check_file (fixture->miner, file, G_PRIORITY_DEFAULT, FALSE); - g_object_unref (file); - - file = fixture_get_relative_file (fixture, "not-indexed/c"); - tracker_miner_fs_check_file (fixture->miner, file, G_PRIORITY_DEFAULT, TRUE); - g_object_unref (file); - - fixture_iterate (fixture); - - g_assert_cmpint (((TestMiner *) fixture->miner)->n_process_file, ==, 2); - - content = fixture_get_content (fixture); - g_assert_cmpstr (content, ==, - "not-indexed/b," - "recursive," - "recursive/a"); - g_free (content); -} - -gint -main (gint argc, - gchar **argv) -{ - g_test_init (&argc, &argv, NULL); - - g_test_message ("Testing filesystem miner"); - - ADD_TEST ("/indexing-tree/recursive-indexing", - test_recursive_indexing); - ADD_TEST ("/indexing-tree/non-recursive-indexing", - test_non_recursive_indexing); - /* FIXME: test other directory flags */ - ADD_TEST ("/indexing-tree/separate-recursive-and-non-recursive", - test_separate_recursive_and_non_recursive); - ADD_TEST ("/indexing-tree/recursive-in-non-recursive", - test_recursive_in_non_recursive); - ADD_TEST ("/indexing-tree/non-recursive-in-recursive", - test_non_recursive_in_recursive); - ADD_TEST ("/indexing-tree/empty-root", - test_empty_root); - ADD_TEST ("/indexing-tree/missing-root", - test_missing_root); - ADD_TEST ("/indexing-tree/skip-hidden-files", - test_skip_hidden_files); - ADD_TEST ("/indexing-tree/index-hidden-files", - test_index_hidden_files); - ADD_TEST ("/indexing-tree/file-filter-default-accept", - test_file_filter_default_accept); - ADD_TEST ("/indexing-tree/file-filter-default-deny", - test_file_filter_default_deny); - ADD_TEST ("/indexing-tree/directory-filter-default-accept", - test_directory_filter_default_accept); - ADD_TEST ("/indexing-tree/directory-filter-default-deny", - test_directory_filter_default_deny); - ADD_TEST ("/indexing-tree/content-filter-default-accept", - test_content_filter_default_accept); - ADD_TEST ("/indexing-tree/content-filter-default-deny", - test_content_filter_default_deny); - ADD_TEST ("/indexing-tree/content-filter-on-parent-root", - test_content_filter_on_parent_root); - - /* Tests for non-monitored FS changes (eg. between reindexes) */ - ADD_TEST ("/non-monitored/create", - test_non_monitored_create); - ADD_TEST ("/non-monitored/update", - test_non_monitored_update); - ADD_TEST ("/non-monitored/delete", - test_non_monitored_delete); - ADD_TEST ("/non-monitored/move", - test_non_monitored_move); - - /* Tests for monitored FS changes (from file monitors) */ - ADD_TEST ("/monitored/create", - test_monitored_create); - ADD_TEST ("/monitored/update", - test_monitored_update); - ADD_TEST ("/monitored/delete", - test_monitored_delete); - ADD_TEST ("/monitored/move", - test_monitored_move); - ADD_TEST ("/monitored/atomic-replace", - test_monitored_atomic_replace); - ADD_TEST ("monitored/changes-after-no-mtime-check", - test_changes_after_no_mtime_check); - - /* Tests for event queues */ - ADD_TEST ("event-queue/create-and-update", - test_event_queue_create_and_update); - ADD_TEST ("event-queue/create-and-delete", - test_event_queue_create_and_delete); - ADD_TEST ("event-queue/create-and-move", - test_event_queue_create_and_move); - ADD_TEST ("event-queue/update-and-update", - test_event_queue_update_and_update); - ADD_TEST ("event-queue/update-and-delete", - test_event_queue_update_and_delete); - ADD_TEST ("event-queue/update-and-move", - test_event_queue_update_and_move); - ADD_TEST ("event-queue/delete-and-create", - test_event_queue_delete_and_create); - ADD_TEST ("event-queue/move-and-update", - test_event_queue_move_and_update); - ADD_TEST ("event-queue/move-and-create-origin", - test_event_queue_move_and_create_origin); - ADD_TEST ("event-queue/move-and-delete", - test_event_queue_move_and_delete); - ADD_TEST ("event-queue/move-and-move", - test_event_queue_move_and_move); - ADD_TEST ("event-queue/move-and-move-back", - test_event_queue_move_and_move_back); - - /* API tests */ - ADD_TEST ("api/check_file", - test_api_check_file); - - return g_test_run (); -} diff --git a/tests/libtracker-miner/tracker-miner-mock.vala b/tests/libtracker-miner/tracker-miner-mock.vala deleted file mode 100644 index 302a3387b..000000000 --- a/tests/libtracker-miner/tracker-miner-mock.vala +++ /dev/null @@ -1,70 +0,0 @@ -// -// Copyright (C) 2010, Nokia -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -// 02110-1301, USA. -// - -using GLib; - -public class TrackerMinerMock : GLib.Object { - - public bool is_paused ; - public string pause_reason { get; set; default = ""; } - public string name { get; set; default = ""; } - public string[] apps { get { return _apps; } } - public string[] reasons { get { return _apps; } } - - public signal void progress (string miner, string status, double progress); - public signal void paused (); - public signal void resumed (); - - string[] _apps; - string[] _reasons; - - public TrackerMinerMock (string name) { - this.name = name; - this._apps = {}; - this._reasons = {}; - } - - public void set_paused (bool paused) { this.is_paused = paused; } - public bool get_paused () { return this.is_paused ; } - - public void pause (string app, string reason) { - - if (this._apps.length == 0) { - this._apps = { app }; - } else { - this._apps += app; - } - - if (this._reasons.length == 0) { - this._reasons = { reason }; - } else { - this._reasons += reason; - } - this.is_paused = true; - this.paused (); - } - - public void resume () { - this._apps = null; - this._reasons = null; - this.is_paused = false; - this.resumed (); - } - -} diff --git a/tests/libtracker-miner/tracker-monitor-test.c b/tests/libtracker-miner/tracker-monitor-test.c deleted file mode 100644 index 26a56cbef..000000000 --- a/tests/libtracker-miner/tracker-monitor-test.c +++ /dev/null @@ -1,1542 +0,0 @@ -/* - * Copyright (C) 2010, Nokia <ivan.frade@nokia.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include <string.h> -#include <unistd.h> - -#include <glib.h> -#include <glib/gstdio.h> - -/* Special case, the monitor header is not normally exported */ -#include <libtracker-miner/tracker-monitor.h> - -/* -------------- COMMON FOR ALL FILE EVENT TESTS ----------------- */ - -#define TEST_TIMEOUT 5 /* seconds */ - -typedef enum { - MONITOR_SIGNAL_NONE = 0, - MONITOR_SIGNAL_ITEM_CREATED = 1 << 0, - MONITOR_SIGNAL_ITEM_UPDATED = 1 << 1, - MONITOR_SIGNAL_ITEM_ATTRIBUTE_UPDATED = 1 << 2, - MONITOR_SIGNAL_ITEM_DELETED = 1 << 3, - MONITOR_SIGNAL_ITEM_MOVED_FROM = 1 << 4, - MONITOR_SIGNAL_ITEM_MOVED_TO = 1 << 5 -} MonitorSignal; - -/* Fixture object type */ -typedef struct { - TrackerMonitor *monitor; - GFile *monitored_directory_file; - gchar *monitored_directory; - gchar *not_monitored_directory; - GHashTable *events; - GMainLoop *main_loop; -} TrackerMonitorTestFixture; - -static void -add_event (GHashTable *events, - GFile *file, - MonitorSignal new_event) -{ - gpointer previous_file; - gpointer previous_mask; - - /* Lookup file in HT */ - if (g_hash_table_lookup_extended (events, - file, - &previous_file, - &previous_mask)) { - guint mask; - - mask = GPOINTER_TO_UINT (previous_mask); - mask |= new_event; - g_hash_table_replace (events, - g_object_ref (previous_file), - GUINT_TO_POINTER (mask)); - } -} - -static void -test_monitor_events_created_cb (TrackerMonitor *monitor, - GFile *file, - gboolean is_directory, - gpointer user_data) -{ - gchar *path; - - g_assert (file != NULL); - path = g_file_get_path (file); - g_assert (path != NULL); - - g_debug ("***** '%s' (%s) (CREATED)", - path, - is_directory ? "DIR" : "FILE"); - - g_free (path); - - add_event ((GHashTable *) user_data, - file, - MONITOR_SIGNAL_ITEM_CREATED); -} - -static void -test_monitor_events_updated_cb (TrackerMonitor *monitor, - GFile *file, - gboolean is_directory, - gpointer user_data) -{ - gchar *path; - - g_assert (file != NULL); - path = g_file_get_path (file); - g_assert (path != NULL); - - g_debug ("***** '%s' (%s) (UPDATED)", - path, - is_directory ? "DIR" : "FILE"); - - g_free (path); - - add_event ((GHashTable *) user_data, - file, - MONITOR_SIGNAL_ITEM_UPDATED); -} - -static void -test_monitor_events_attribute_updated_cb (TrackerMonitor *monitor, - GFile *file, - gboolean is_directory, - gpointer user_data) -{ - gchar *path; - - g_assert (file != NULL); - path = g_file_get_path (file); - g_assert (path != NULL); - - g_debug ("***** '%s' (%s) (ATRIBUTE UPDATED)", - path, - is_directory ? "DIR" : "FILE"); - - g_free (path); - - add_event ((GHashTable *) user_data, - file, - MONITOR_SIGNAL_ITEM_ATTRIBUTE_UPDATED); -} - -static void -test_monitor_events_deleted_cb (TrackerMonitor *monitor, - GFile *file, - gboolean is_directory, - gpointer user_data) -{ - gchar *path; - - g_assert (file != NULL); - path = g_file_get_path (file); - g_assert (path != NULL); - - g_debug ("***** '%s' (%s) (DELETED)", - path, - is_directory ? "DIR" : "FILE"); - - g_free (path); - - add_event ((GHashTable *) user_data, - file, - MONITOR_SIGNAL_ITEM_DELETED); -} - -static void -test_monitor_events_moved_cb (TrackerMonitor *monitor, - GFile *file, - GFile *other_file, - gboolean is_directory, - gboolean is_source_monitored, - gpointer user_data) -{ - gchar *path; - gchar *other_path; - - g_assert (file != NULL); - path = g_file_get_path (other_file); - other_path = g_file_get_path (other_file); - - g_debug ("***** '%s'->'%s' (%s) (MOVED) (source %smonitored)", - path, - other_path, - is_directory ? "DIR" : "FILE", - is_source_monitored ? "" : "not "); - - g_free (other_path); - g_free (path); - - /* Add event to the files */ - add_event ((GHashTable *) user_data, - file, - MONITOR_SIGNAL_ITEM_MOVED_FROM); - add_event ((GHashTable *) user_data, - other_file, - MONITOR_SIGNAL_ITEM_MOVED_TO); -} - -static void -test_monitor_common_setup (TrackerMonitorTestFixture *fixture, - gconstpointer data) -{ - gchar *basename; - - /* Create HT to store received events */ - fixture->events = g_hash_table_new_full (g_file_hash, - (GEqualFunc) g_file_equal, - NULL, - NULL); - - /* Create and setup the tracker monitor */ - fixture->monitor = tracker_monitor_new (); - g_assert (fixture->monitor != NULL); - - g_signal_connect (fixture->monitor, "item-created", - G_CALLBACK (test_monitor_events_created_cb), - fixture->events); - g_signal_connect (fixture->monitor, "item-updated", - G_CALLBACK (test_monitor_events_updated_cb), - fixture->events); - g_signal_connect (fixture->monitor, "item-attribute-updated", - G_CALLBACK (test_monitor_events_attribute_updated_cb), - fixture->events); - g_signal_connect (fixture->monitor, "item-deleted", - G_CALLBACK (test_monitor_events_deleted_cb), - fixture->events); - g_signal_connect (fixture->monitor, "item-moved", - G_CALLBACK (test_monitor_events_moved_cb), - fixture->events); - - /* Initially, set it disabled */ - tracker_monitor_set_enabled (fixture->monitor, FALSE); - - /* Create a temp directory to monitor in the test */ - basename = g_strdup_printf ("monitor-test-%d", getpid ()); - fixture->monitored_directory = g_build_path (G_DIR_SEPARATOR_S, g_get_tmp_dir (), basename, NULL); - fixture->monitored_directory_file = g_file_new_for_path (fixture->monitored_directory); - g_assert (fixture->monitored_directory_file != NULL); - g_assert_cmpint (g_file_make_directory_with_parents (fixture->monitored_directory_file, NULL, NULL), ==, TRUE); - g_free (basename); - g_assert_cmpint (tracker_monitor_add (fixture->monitor, fixture->monitored_directory_file), ==, TRUE); - g_assert_cmpint (tracker_monitor_get_count (fixture->monitor), ==, 1); - - /* Setup also not-monitored directory */ - fixture->not_monitored_directory = g_strdup (g_get_tmp_dir ()); - - /* Create new main loop */ - fixture->main_loop = g_main_loop_new (NULL, FALSE); - g_assert (fixture->main_loop != NULL); -} - -static void -test_monitor_common_teardown (TrackerMonitorTestFixture *fixture, - gconstpointer data) -{ - /* Remove the main loop */ - g_main_loop_unref (fixture->main_loop); - - /* Cleanup monitor */ - g_assert_cmpint (tracker_monitor_remove (fixture->monitor, fixture->monitored_directory_file), ==, TRUE); - g_assert_cmpint (tracker_monitor_get_count (fixture->monitor), ==, 0); - - /* Destroy monitor */ - g_assert (fixture->monitor != NULL); - g_object_unref (fixture->monitor); - - /* Remove the HT of events */ - g_hash_table_destroy (fixture->events); - - /* Remove base test directories */ - g_assert (fixture->monitored_directory_file != NULL); - g_assert (fixture->monitored_directory != NULL); - g_assert_cmpint (g_file_delete (fixture->monitored_directory_file, NULL, NULL), ==, TRUE); - g_object_unref (fixture->monitored_directory_file); - g_free (fixture->monitored_directory); - - g_assert (fixture->not_monitored_directory != NULL); - g_free (fixture->not_monitored_directory); -} - -static void -create_directory (const gchar *parent, - const gchar *directory_name, - GFile **outfile) -{ - GFile *dirfile; - gchar *path; - - path = g_build_path (G_DIR_SEPARATOR_S, parent, directory_name, NULL); - dirfile = g_file_new_for_path (path); - g_assert (dirfile != NULL); - g_assert_cmpint (g_file_make_directory_with_parents (dirfile, NULL, NULL), ==, TRUE); - if (outfile) { - *outfile = dirfile; - } else { - g_object_unref (dirfile); - } - g_free (path); -} - -static void -set_file_contents (const gchar *directory, - const gchar *filename, - const gchar *contents, - GFile **outfile) -{ - FILE *file; - size_t length; - gchar *file_path; - - g_assert (directory != NULL); - g_assert (filename != NULL); - g_assert (contents != NULL); - - file_path = g_build_filename (directory, filename, NULL); - - file = g_fopen (file_path, "wb"); - g_assert (file != NULL); - length = strlen (contents); - g_assert_cmpint (fwrite (contents, 1, length, file), >=, length); - g_assert_cmpint (fflush (file), ==, 0); - g_assert_cmpint (fclose (file), !=, EOF); - - if (outfile) { - *outfile = g_file_new_for_path (file_path); - } - g_free (file_path); -} - -static void -set_file_permissions (const gchar *directory, - const gchar *filename, - gint permissions) -{ - gchar *file_path; - - g_assert (directory != NULL); - g_assert (filename != NULL); - - file_path = g_build_filename (directory, filename, NULL); - g_assert_cmpint (g_chmod (file_path, permissions), ==, 0); - g_free (file_path); -} - -static void -print_file_events_cb (gpointer key, - gpointer value, - gpointer user_data) -{ - GFile *file; - guint events; - gchar *uri; - - file = key; - events = GPOINTER_TO_UINT (value); - uri = g_file_get_uri (file); - - g_print ("Signals received for '%s': \n" - " CREATED: %s\n" - " UPDATED: %s\n" - " ATTRIBUTE UPDATED: %s\n" - " DELETED: %s\n" - " MOVED_FROM: %s\n" - " MOVED_TO: %s\n", - uri, - events & MONITOR_SIGNAL_ITEM_CREATED ? "yes" : "no", - events & MONITOR_SIGNAL_ITEM_UPDATED ? "yes" : "no", - events & MONITOR_SIGNAL_ITEM_ATTRIBUTE_UPDATED ? "yes" : "no", - events & MONITOR_SIGNAL_ITEM_DELETED ? "yes" : "no", - events & MONITOR_SIGNAL_ITEM_MOVED_FROM ? "yes" : "no", - events & MONITOR_SIGNAL_ITEM_MOVED_TO ? "yes" : "no"); - - g_free (uri); -} - -static gboolean -timeout_cb (gpointer data) -{ - g_main_loop_quit ((GMainLoop *) data); - return FALSE; -} - -static void -events_wait (TrackerMonitorTestFixture *fixture) -{ - /* Setup timeout to stop the main loop after some seconds */ - g_timeout_add_seconds (TEST_TIMEOUT, timeout_cb, fixture->main_loop); - g_debug ("Waiting %u seconds for monitor events...", TEST_TIMEOUT); - g_main_loop_run (fixture->main_loop); - - /* Print signals received for each file */ - g_hash_table_foreach (fixture->events, print_file_events_cb, NULL); -} - -/* ----------------------------- FILE EVENT TESTS --------------------------------- */ - -static void -test_monitor_file_event_created (TrackerMonitorTestFixture *fixture, - gconstpointer data) -{ - GFile *test_file; - guint file_events; - - /* Set up environment */ - tracker_monitor_set_enabled (fixture->monitor, TRUE); - - /* Create file to test with */ - set_file_contents (fixture->monitored_directory, "created.txt", "foo", &test_file); - g_assert (test_file != NULL); - g_hash_table_insert (fixture->events, - g_object_ref (test_file), - GUINT_TO_POINTER (MONITOR_SIGNAL_NONE)); - - /* Wait for events */ - events_wait (fixture); - - /* Get events in the file */ - file_events = GPOINTER_TO_UINT (g_hash_table_lookup (fixture->events, test_file)); - - /* Fail if we didn't get the CREATE signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_CREATED), >, 0); - - /* Fail if we got a MOVE or DELETE signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_FROM), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_TO), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_DELETED), ==, 0); - /* We may get an UPDATE due to the way the file is created */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_ATTRIBUTE_UPDATED), ==, 0); - - /* Cleanup environment */ - tracker_monitor_set_enabled (fixture->monitor, FALSE); - - /* Remove the test file */ - g_assert_cmpint (g_file_delete (test_file, NULL, NULL), ==, TRUE); - g_object_unref (test_file); -} - -static void -test_monitor_file_event_updated (TrackerMonitorTestFixture *fixture, - gconstpointer data) -{ - GFile *test_file; - guint file_events; - - /* Create file to test with, before setting up environment */ - set_file_contents (fixture->monitored_directory, "created.txt", "foo", NULL); - - /* Set up environment */ - tracker_monitor_set_enabled (fixture->monitor, TRUE); - - /* Now, trigger update of the already created file */ - set_file_contents (fixture->monitored_directory, "created.txt", "barrrr", &test_file); - g_assert (test_file != NULL); - g_hash_table_insert (fixture->events, - g_object_ref (test_file), - GUINT_TO_POINTER (MONITOR_SIGNAL_NONE)); - - /* Wait for events */ - events_wait (fixture); - - /* Get events in the file */ - file_events = GPOINTER_TO_UINT (g_hash_table_lookup (fixture->events, test_file)); - - /* Fail if we didn't get the UPDATE signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_UPDATED), >, 0); - - /* Fail if we got a CREATE, MOVE or DELETE signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_CREATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_FROM), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_TO), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_DELETED), ==, 0); - - /* Cleanup environment */ - tracker_monitor_set_enabled (fixture->monitor, FALSE); - - /* Remove the test file */ - g_assert_cmpint (g_file_delete (test_file, NULL, NULL), ==, TRUE); - g_object_unref (test_file); -} - -static void -test_monitor_file_event_attribute_updated (TrackerMonitorTestFixture *fixture, - gconstpointer data) -{ - GFile *test_file; - guint file_events; - - /* Create file to test with, before setting up environment */ - set_file_contents (fixture->monitored_directory, "created.txt", "foo", &test_file); - g_assert (test_file != NULL); - - /* Set up environment */ - tracker_monitor_set_enabled (fixture->monitor, TRUE); - - /* Now, trigger attribute update of the already created file */ - set_file_permissions (fixture->monitored_directory, - "created.txt", - S_IRWXU); - - g_hash_table_insert (fixture->events, - g_object_ref (test_file), - GUINT_TO_POINTER (MONITOR_SIGNAL_NONE)); - - /* Wait for events */ - events_wait (fixture); - - /* Get events in the file */ - file_events = GPOINTER_TO_UINT (g_hash_table_lookup (fixture->events, test_file)); - - /* Fail if we didn't get the ATTRIBUTE UPDATE signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_ATTRIBUTE_UPDATED), >, 0); - - /* Fail if we got a UPDATE, CREATE, MOVE or DELETE signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_UPDATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_CREATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_FROM), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_TO), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_DELETED), ==, 0); - - /* Cleanup environment */ - tracker_monitor_set_enabled (fixture->monitor, FALSE); - - /* Remove the test file */ - g_assert_cmpint (g_file_delete (test_file, NULL, NULL), ==, TRUE); - g_object_unref (test_file); -} - -static void -test_monitor_file_event_deleted (TrackerMonitorTestFixture *fixture, - gconstpointer data) -{ - GFile *test_file; - guint file_events; - - /* Create file to test with, before setting up environment */ - set_file_contents (fixture->monitored_directory, "created.txt", "foo", &test_file); - g_assert (test_file != NULL); - - /* Set up environment */ - tracker_monitor_set_enabled (fixture->monitor, TRUE); - - /* Now, remove file */ - g_assert_cmpint (g_file_delete (test_file, NULL, NULL), ==, TRUE); - g_hash_table_insert (fixture->events, - g_object_ref (test_file), - GUINT_TO_POINTER (MONITOR_SIGNAL_NONE)); - - /* Wait for events */ - events_wait (fixture); - - /* Get events in the file */ - file_events = GPOINTER_TO_UINT (g_hash_table_lookup (fixture->events, test_file)); - - /* Fail if we didn't get the DELETED signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_DELETED), >, 0); - - /* Fail if we got a CREATE, UDPATE or MOVE signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_CREATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_UPDATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_ATTRIBUTE_UPDATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_FROM), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_TO), ==, 0); - - /* Cleanup environment */ - tracker_monitor_set_enabled (fixture->monitor, FALSE); - g_object_unref (test_file); -} - -static void -test_monitor_file_event_moved_to_monitored (TrackerMonitorTestFixture *fixture, - gconstpointer data) -{ - GFile *source_file; - gchar *source_path; - GFile *dest_file; - gchar *dest_path; - guint file_events; - - /* Create file to test with, before setting up environment */ - set_file_contents (fixture->monitored_directory, "created.txt", "foo", &source_file); - g_assert (source_file != NULL); - - /* Set up environment */ - tracker_monitor_set_enabled (fixture->monitor, TRUE); - - /* Now, rename the file */ - source_path = g_file_get_path (source_file); - dest_path = g_build_filename (fixture->monitored_directory, "renamed.txt", NULL); - dest_file = g_file_new_for_path (dest_path); - g_assert (dest_file != NULL); - - g_assert_cmpint (g_rename (source_path, dest_path), ==, 0); - - g_hash_table_insert (fixture->events, - g_object_ref (source_file), - GUINT_TO_POINTER (MONITOR_SIGNAL_NONE)); - g_hash_table_insert (fixture->events, - g_object_ref (dest_file), - GUINT_TO_POINTER (MONITOR_SIGNAL_NONE)); - - /* Wait for events */ - events_wait (fixture); - - /* Get events in the source file */ - file_events = GPOINTER_TO_UINT (g_hash_table_lookup (fixture->events, source_file)); - /* Fail if we didn't get the MOVED_FROM signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_FROM), >, 0); - /* Fail if we got a CREATE, UPDATE, DELETE or MOVE_TO signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_CREATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_UPDATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_ATTRIBUTE_UPDATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_TO), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_DELETED), ==, 0); - - /* Get events in the dest file */ - file_events = GPOINTER_TO_UINT (g_hash_table_lookup (fixture->events, dest_file)); - /* Fail if we didn't get the MOVED_TO signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_TO), >, 0); - /* Fail if we got a CREATE, DELETE or MOVE_FROM signal (UPDATE may actually be possible) */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_CREATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_FROM), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_DELETED), ==, 0); - - /* Cleanup environment */ - tracker_monitor_set_enabled (fixture->monitor, FALSE); - g_assert_cmpint (g_file_delete (dest_file, NULL, NULL), ==, TRUE); - g_object_unref (source_file); - g_object_unref (dest_file); - g_free (source_path); - g_free (dest_path); -} - -static void -test_monitor_file_event_moved_to_not_monitored (TrackerMonitorTestFixture *fixture, - gconstpointer data) -{ - GFile *source_file; - gchar *source_path; - GFile *dest_file; - gchar *dest_path; - guint file_events; - - /* Create file to test with, before setting up environment */ - set_file_contents (fixture->monitored_directory, "created.txt", "foo", &source_file); - g_assert (source_file != NULL); - - /* Set up environment */ - tracker_monitor_set_enabled (fixture->monitor, TRUE); - - /* Now, rename the file */ - source_path = g_file_get_path (source_file); - dest_path = g_build_filename (fixture->not_monitored_directory, "out.txt", NULL); - dest_file = g_file_new_for_path (dest_path); - g_assert (dest_file != NULL); - - g_assert_cmpint (g_rename (source_path, dest_path), ==, 0); - - g_hash_table_insert (fixture->events, - g_object_ref (source_file), - GUINT_TO_POINTER (MONITOR_SIGNAL_NONE)); - g_hash_table_insert (fixture->events, - g_object_ref (dest_file), - GUINT_TO_POINTER (MONITOR_SIGNAL_NONE)); - - /* Wait for events */ - events_wait (fixture); - - /* Get events in the source file */ - file_events = GPOINTER_TO_UINT (g_hash_table_lookup (fixture->events, source_file)); - /* Fail if we didn't get the DELETED signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_DELETED), >, 0); - /* Fail if we got a CREATE, UPDATE or MOVE signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_CREATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_UPDATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_ATTRIBUTE_UPDATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_TO), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_FROM), ==, 0); - - /* Get events in the dest file */ - file_events = GPOINTER_TO_UINT (g_hash_table_lookup (fixture->events, dest_file)); - /* Fail if we got a CREATE, UPDATE, DELETE or MOVE signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_CREATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_UPDATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_ATTRIBUTE_UPDATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_DELETED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_FROM), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_TO), ==, 0); - - /* Cleanup environment */ - tracker_monitor_set_enabled (fixture->monitor, FALSE); - g_assert_cmpint (g_file_delete (dest_file, NULL, NULL), ==, TRUE); - g_object_unref (source_file); - g_object_unref (dest_file); - g_free (source_path); - g_free (dest_path); -} - -static void -test_monitor_file_event_moved_from_not_monitored (TrackerMonitorTestFixture *fixture, - gconstpointer data) -{ - GFile *source_file; - gchar *source_path; - GFile *dest_file; - gchar *dest_path; - guint file_events; - - /* Create file to test with, before setting up environment */ - set_file_contents (fixture->not_monitored_directory, "created.txt", "foo", &source_file); - g_assert (source_file != NULL); - - /* Set up environment */ - tracker_monitor_set_enabled (fixture->monitor, TRUE); - - /* Now, rename the file */ - source_path = g_file_get_path (source_file); - dest_path = g_build_filename (fixture->monitored_directory, "in.txt", NULL); - dest_file = g_file_new_for_path (dest_path); - g_assert (dest_file != NULL); - - g_assert_cmpint (g_rename (source_path, dest_path), ==, 0); - - g_hash_table_insert (fixture->events, - g_object_ref (source_file), - GUINT_TO_POINTER (MONITOR_SIGNAL_NONE)); - g_hash_table_insert (fixture->events, - g_object_ref (dest_file), - GUINT_TO_POINTER (MONITOR_SIGNAL_NONE)); - - /* Wait for events */ - events_wait (fixture); - - /* Get events in the source file */ - file_events = GPOINTER_TO_UINT (g_hash_table_lookup (fixture->events, source_file)); - /* Fail if we got a CREATE, UPDATE, DELETE or MOVE signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_CREATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_UPDATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_ATTRIBUTE_UPDATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_DELETED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_FROM), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_TO), ==, 0); - - /* Get events in the dest file */ - file_events = GPOINTER_TO_UINT (g_hash_table_lookup (fixture->events, dest_file)); - /* Fail if we didn't get the CREATED signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_CREATED), >, 0); - /* Fail if we got a DELETE, UPDATE or MOVE signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_DELETED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_UPDATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_ATTRIBUTE_UPDATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_TO), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_FROM), ==, 0); - - /* Cleanup environment */ - tracker_monitor_set_enabled (fixture->monitor, FALSE); - g_assert_cmpint (g_file_delete (dest_file, NULL, NULL), ==, TRUE); - g_object_unref (source_file); - g_object_unref (dest_file); - g_free (source_path); - g_free (dest_path); -} - -/* ----------------------------- DIRECTORY EVENT TESTS --------------------------------- */ - -static void -test_monitor_directory_event_created (TrackerMonitorTestFixture *fixture, - gconstpointer data) -{ - GFile *test_dir; - guint file_events; - - /* Set up environment */ - tracker_monitor_set_enabled (fixture->monitor, TRUE); - - /* Create directory to test with */ - create_directory (fixture->monitored_directory, "foo", &test_dir); - g_assert (test_dir != NULL); - g_hash_table_insert (fixture->events, - g_object_ref (test_dir), - GUINT_TO_POINTER (MONITOR_SIGNAL_NONE)); - - /* Wait for events */ - events_wait (fixture); - - /* Get events in the file */ - file_events = GPOINTER_TO_UINT (g_hash_table_lookup (fixture->events, test_dir)); - - /* Fail if we didn't get the CREATE signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_CREATED), >, 0); - - /* Fail if we got a MOVE or DELETE signal (update may actually happen) */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_FROM), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_TO), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_DELETED), ==, 0); - - /* Cleanup environment */ - tracker_monitor_set_enabled (fixture->monitor, FALSE); - - /* Remove the test dir */ - g_assert_cmpint (g_file_delete (test_dir, NULL, NULL), ==, TRUE); - g_object_unref (test_dir); -} - -static void -test_monitor_directory_event_deleted (TrackerMonitorTestFixture *fixture, - gconstpointer data) -{ - GFile *source_dir; - gchar *source_path; - guint file_events; - - /* Create directory to test with in a monitored place, - * before setting up the environment */ - create_directory (fixture->monitored_directory, "foo", &source_dir); - source_path = g_file_get_path (source_dir); - g_assert (source_dir != NULL); - - /* Set to monitor the new dir also */ - g_assert_cmpint (tracker_monitor_add (fixture->monitor, source_dir), ==, TRUE); - - /* Set up environment */ - tracker_monitor_set_enabled (fixture->monitor, TRUE); - - /* Now, delete the directory */ - g_assert_cmpint (g_file_delete (source_dir, NULL, NULL), ==, TRUE); - - g_hash_table_insert (fixture->events, - g_object_ref (source_dir), - GUINT_TO_POINTER (MONITOR_SIGNAL_NONE)); - - /* Wait for events */ - events_wait (fixture); - - /* Get events in the source dir */ - file_events = GPOINTER_TO_UINT (g_hash_table_lookup (fixture->events, source_dir)); - /* Fail if we didn't get DELETED signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_DELETED), >, 0); - /* Fail if we got a CREATEd, UPDATED, MOVED_FROM or MOVED_TO signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_CREATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_UPDATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_ATTRIBUTE_UPDATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_FROM), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_TO), ==, 0); - - /* Cleanup environment */ - tracker_monitor_set_enabled (fixture->monitor, FALSE); - g_assert_cmpint (tracker_monitor_remove (fixture->monitor, source_dir), ==, TRUE); - g_object_unref (source_dir); - g_free (source_path); -} - - -static void -test_monitor_directory_event_moved_to_monitored (TrackerMonitorTestFixture *fixture, - gconstpointer data) -{ - GFile *source_dir; - gchar *source_path; - GFile *dest_dir; - gchar *dest_path; - GFile *file_in_source_dir; - GFile *file_in_dest_dir; - gchar *file_in_dest_dir_path; - guint file_events; - - /* Create directory to test with, before setting up the environment */ - create_directory (fixture->monitored_directory, "foo", &source_dir); - source_path = g_file_get_path (source_dir); - g_assert (source_dir != NULL); - - /* Add some file to the new dir */ - set_file_contents (source_path, "lalala.txt", "whatever", &file_in_source_dir); - - /* Set up environment */ - tracker_monitor_set_enabled (fixture->monitor, TRUE); - - /* Set to monitor the new dir also */ - g_assert_cmpint (tracker_monitor_add (fixture->monitor, source_dir), ==, TRUE); - - /* Get final path of the file */ - file_in_dest_dir_path = g_build_path (G_DIR_SEPARATOR_S, - fixture->monitored_directory, - "renamed", - "lalala.txt", - NULL); - file_in_dest_dir = g_file_new_for_path (file_in_dest_dir_path); - g_assert (file_in_dest_dir != NULL); - - /* Now, rename the directory */ - dest_dir = g_file_get_parent (file_in_dest_dir); - dest_path = g_file_get_path (dest_dir); - - g_assert_cmpint (g_rename (source_path, dest_path), ==, 0); - - g_hash_table_insert (fixture->events, - g_object_ref (source_dir), - GUINT_TO_POINTER (MONITOR_SIGNAL_NONE)); - g_hash_table_insert (fixture->events, - g_object_ref (dest_dir), - GUINT_TO_POINTER (MONITOR_SIGNAL_NONE)); - g_hash_table_insert (fixture->events, - g_object_ref (file_in_dest_dir), - GUINT_TO_POINTER (MONITOR_SIGNAL_NONE)); - g_hash_table_insert (fixture->events, - g_object_ref (file_in_source_dir), - GUINT_TO_POINTER (MONITOR_SIGNAL_NONE)); - - /* Wait for events */ - events_wait (fixture); - - /* Get events in the source dir */ - file_events = GPOINTER_TO_UINT (g_hash_table_lookup (fixture->events, source_dir)); - /* Fail if we didn't get the MOVED_FROM signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_FROM), >, 0); - /* Fail if we got a CREATE, UPDATE, DELETE or MOVE_TO signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_CREATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_UPDATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_ATTRIBUTE_UPDATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_DELETED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_TO), ==, 0); - - /* Get events in the dest file */ - file_events = GPOINTER_TO_UINT (g_hash_table_lookup (fixture->events, dest_dir)); - /* Fail if we didn't get the MOVED_TO signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_TO), >, 0); - /* Fail if we got a CREATE, DELETE or MOVE_FROM signal (UPDATE may actually be possible) */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_CREATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_FROM), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_DELETED), ==, 0); - - /* Get events in the file in source dir */ - file_events = GPOINTER_TO_UINT (g_hash_table_lookup (fixture->events, file_in_source_dir)); - /* Fail if we got ANY signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_CREATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_UPDATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_ATTRIBUTE_UPDATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_DELETED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_FROM), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_TO), ==, 0); - - /* Get events in the file in dest dir */ - file_events = GPOINTER_TO_UINT (g_hash_table_lookup (fixture->events, file_in_dest_dir)); - /* Fail if we got ANY signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_CREATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_UPDATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_ATTRIBUTE_UPDATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_DELETED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_FROM), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_TO), ==, 0); - - - /* Cleanup environment */ - tracker_monitor_set_enabled (fixture->monitor, FALSE); - /* Since tracker 0.9.33, monitors are NOT moved to the new location directly when the - * directory is moved, that is done by the upper layers. - * Note that monitor is now in dest_dir */ - g_assert_cmpint (tracker_monitor_remove (fixture->monitor, source_dir), ==, TRUE); - g_assert_cmpint (tracker_monitor_remove (fixture->monitor, dest_dir), !=, TRUE); - g_assert_cmpint (g_file_delete (file_in_dest_dir, NULL, NULL), ==, TRUE); - g_assert_cmpint (g_file_delete (dest_dir, NULL, NULL), ==, TRUE); - g_object_unref (source_dir); - g_object_unref (file_in_source_dir); - g_object_unref (dest_dir); - g_object_unref (file_in_dest_dir); - g_free (source_path); - g_free (file_in_dest_dir_path); - g_free (dest_path); -} - -/* Same test as before, BUT, creating a new file in the directory while it's being monitored. - * In this case, GIO dumps an extra DELETE event after the MOVE - */ -static void -test_monitor_directory_event_moved_to_monitored_after_file_create (TrackerMonitorTestFixture *fixture, - gconstpointer data) -{ - GFile *source_dir; - gchar *source_path; - GFile *dest_dir; - gchar *dest_path; - GFile *file_in_source_dir; - GFile *file_in_dest_dir; - gchar *file_in_dest_dir_path; - guint file_events; - - /* Create directory to test with, before setting up the environment */ - create_directory (fixture->monitored_directory, "foo", &source_dir); - source_path = g_file_get_path (source_dir); - g_assert (source_dir != NULL); - - /* Set up environment */ - tracker_monitor_set_enabled (fixture->monitor, TRUE); - - /* Set to monitor the new dir also */ - g_assert_cmpint (tracker_monitor_add (fixture->monitor, source_dir), ==, TRUE); - - /* Add some file to the new dir, WHILE ALREADY MONITORING */ - set_file_contents (source_path, "lalala.txt", "whatever", &file_in_source_dir); - - /* Ignore the events thus far */ - events_wait (fixture); - g_hash_table_remove_all (fixture->events); - - /* Get final path of the file */ - file_in_dest_dir_path = g_build_path (G_DIR_SEPARATOR_S, - fixture->monitored_directory, - "renamed", - "lalala.txt", - NULL); - file_in_dest_dir = g_file_new_for_path (file_in_dest_dir_path); - g_assert (file_in_dest_dir != NULL); - - /* Now, rename the directory */ - dest_dir = g_file_get_parent (file_in_dest_dir); - dest_path = g_file_get_path (dest_dir); - - g_assert_cmpint (g_rename (source_path, dest_path), ==, 0); - - g_hash_table_insert (fixture->events, - g_object_ref (source_dir), - GUINT_TO_POINTER (MONITOR_SIGNAL_NONE)); - g_hash_table_insert (fixture->events, - g_object_ref (dest_dir), - GUINT_TO_POINTER (MONITOR_SIGNAL_NONE)); - g_hash_table_insert (fixture->events, - g_object_ref (file_in_dest_dir), - GUINT_TO_POINTER (MONITOR_SIGNAL_NONE)); - g_hash_table_insert (fixture->events, - g_object_ref (file_in_source_dir), - GUINT_TO_POINTER (MONITOR_SIGNAL_NONE)); - - /* Wait for events */ - events_wait (fixture); - - /* Get events in the source dir */ - file_events = GPOINTER_TO_UINT (g_hash_table_lookup (fixture->events, source_dir)); - /* Fail if we didn't get the MOVED_FROM signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_FROM), >, 0); - /* Fail if we got a CREATE, UPDATE, DELETE or MOVE_TO signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_CREATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_UPDATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_ATTRIBUTE_UPDATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_DELETED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_TO), ==, 0); - - /* Get events in the dest file */ - file_events = GPOINTER_TO_UINT (g_hash_table_lookup (fixture->events, dest_dir)); - /* Fail if we didn't get the MOVED_TO signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_TO), >, 0); - /* Fail if we got a CREATE, DELETE or MOVE_FROM signal (UPDATE may actually be possible) */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_CREATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_FROM), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_DELETED), ==, 0); - - /* Get events in the file in source dir */ - file_events = GPOINTER_TO_UINT (g_hash_table_lookup (fixture->events, file_in_source_dir)); - /* Fail if we got ANY signal != CREATED/UPDATED (we created the file while monitoring) */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_ATTRIBUTE_UPDATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_DELETED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_FROM), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_TO), ==, 0); - - /* Get events in the file in dest dir */ - file_events = GPOINTER_TO_UINT (g_hash_table_lookup (fixture->events, file_in_dest_dir)); - /* Fail if we got ANY signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_CREATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_UPDATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_ATTRIBUTE_UPDATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_DELETED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_FROM), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_TO), ==, 0); - - - /* Cleanup environment */ - tracker_monitor_set_enabled (fixture->monitor, FALSE); - /* Since tracker 0.9.33, monitors are NOT moved to the new location directly when the - * directory is moved, that is done by the upper layers. - * Note that monitor is now in dest_dir */ - g_assert_cmpint (tracker_monitor_remove (fixture->monitor, source_dir), ==, TRUE); - g_assert_cmpint (tracker_monitor_remove (fixture->monitor, dest_dir), !=, TRUE); - g_assert_cmpint (g_file_delete (file_in_dest_dir, NULL, NULL), ==, TRUE); - g_assert_cmpint (g_file_delete (dest_dir, NULL, NULL), ==, TRUE); - g_object_unref (source_dir); - g_object_unref (file_in_source_dir); - g_object_unref (dest_dir); - g_object_unref (file_in_dest_dir); - g_free (source_path); - g_free (file_in_dest_dir_path); - g_free (dest_path); -} - -/* Same test as before, BUT, updating an existing file in the directory while it's being monitored. - * In this case, GIO dumps an extra DELETE event after the MOVE - */ -static void -test_monitor_directory_event_moved_to_monitored_after_file_update (TrackerMonitorTestFixture *fixture, - gconstpointer data) -{ - GFile *source_dir; - gchar *source_path; - GFile *dest_dir; - gchar *dest_path; - GFile *file_in_source_dir; - GFile *file_in_dest_dir; - gchar *file_in_dest_dir_path; - guint file_events; - - /* Create directory to test with, before setting up the environment */ - create_directory (fixture->monitored_directory, "foo", &source_dir); - source_path = g_file_get_path (source_dir); - g_assert (source_dir != NULL); - - /* Add some file to the new dir */ - set_file_contents (source_path, "lalala.txt", "whatever", &file_in_source_dir); - - /* Set up environment */ - tracker_monitor_set_enabled (fixture->monitor, TRUE); - - /* Set to monitor the new dir also */ - g_assert_cmpint (tracker_monitor_add (fixture->monitor, source_dir), ==, TRUE); - - /* Ignore the events thus far */ - events_wait (fixture); - g_hash_table_remove_all (fixture->events); - - /* Get final path of the file */ - file_in_dest_dir_path = g_build_path (G_DIR_SEPARATOR_S, - fixture->monitored_directory, - "renamed", - "lalala.txt", - NULL); - file_in_dest_dir = g_file_new_for_path (file_in_dest_dir_path); - g_assert (file_in_dest_dir != NULL); - - /* Update file contents */ - set_file_contents (source_path, "lalala.txt", "hohoho", &file_in_source_dir); - - /* Now, rename the directory */ - dest_dir = g_file_get_parent (file_in_dest_dir); - dest_path = g_file_get_path (dest_dir); - - g_assert_cmpint (g_rename (source_path, dest_path), ==, 0); - - g_hash_table_insert (fixture->events, - g_object_ref (source_dir), - GUINT_TO_POINTER (MONITOR_SIGNAL_NONE)); - g_hash_table_insert (fixture->events, - g_object_ref (dest_dir), - GUINT_TO_POINTER (MONITOR_SIGNAL_NONE)); - g_hash_table_insert (fixture->events, - g_object_ref (file_in_dest_dir), - GUINT_TO_POINTER (MONITOR_SIGNAL_NONE)); - g_hash_table_insert (fixture->events, - g_object_ref (file_in_source_dir), - GUINT_TO_POINTER (MONITOR_SIGNAL_NONE)); - - /* Wait for events */ - events_wait (fixture); - - /* Get events in the source dir */ - file_events = GPOINTER_TO_UINT (g_hash_table_lookup (fixture->events, source_dir)); - /* Fail if we didn't get the MOVED_FROM signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_FROM), >, 0); - /* Fail if we got a CREATE, UPDATE, DELETE or MOVE_TO signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_CREATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_UPDATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_ATTRIBUTE_UPDATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_DELETED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_TO), ==, 0); - - /* Get events in the dest file */ - file_events = GPOINTER_TO_UINT (g_hash_table_lookup (fixture->events, dest_dir)); - /* Fail if we didn't get the MOVED_TO signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_TO), >, 0); - /* Fail if we got a CREATE, DELETE or MOVE_FROM signal (UPDATE may actually be possible) */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_CREATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_FROM), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_DELETED), ==, 0); - - /* Get events in the file in source dir */ - file_events = GPOINTER_TO_UINT (g_hash_table_lookup (fixture->events, file_in_source_dir)); - /* Fail if we didn't get the UPDATE signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_UPDATED), >=, 0); - /* Fail if we got ANY signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_CREATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_DELETED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_FROM), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_TO), ==, 0); - - /* Get events in the file in dest dir */ - file_events = GPOINTER_TO_UINT (g_hash_table_lookup (fixture->events, file_in_dest_dir)); - /* Fail if we got ANY signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_CREATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_UPDATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_ATTRIBUTE_UPDATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_DELETED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_FROM), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_TO), ==, 0); - - - /* Cleanup environment */ - tracker_monitor_set_enabled (fixture->monitor, FALSE); - /* Since tracker 0.9.33, monitors are NOT moved to the new location directly when the - * directory is moved, that is done by the upper layers. - * Note that monitor is now in dest_dir */ - g_assert_cmpint (tracker_monitor_remove (fixture->monitor, source_dir), ==, TRUE); - g_assert_cmpint (tracker_monitor_remove (fixture->monitor, dest_dir), !=, TRUE); - g_assert_cmpint (g_file_delete (file_in_dest_dir, NULL, NULL), ==, TRUE); - g_assert_cmpint (g_file_delete (dest_dir, NULL, NULL), ==, TRUE); - g_object_unref (source_dir); - g_object_unref (file_in_source_dir); - g_object_unref (dest_dir); - g_object_unref (file_in_dest_dir); - g_free (source_path); - g_free (file_in_dest_dir_path); - g_free (dest_path); -} - -static void -test_monitor_directory_event_moved_to_not_monitored (TrackerMonitorTestFixture *fixture, - gconstpointer data) -{ - GFile *source_dir; - gchar *source_path; - GFile *dest_dir; - gchar *dest_path; - guint file_events; - - /* Create directory to test with, before setting up the environment */ - create_directory (fixture->monitored_directory, "foo", &source_dir); - source_path = g_file_get_path (source_dir); - g_assert (source_dir != NULL); - - /* Set to monitor the new dir also */ - g_assert_cmpint (tracker_monitor_add (fixture->monitor, source_dir), ==, TRUE); - - /* Set up environment */ - tracker_monitor_set_enabled (fixture->monitor, TRUE); - - /* Now, rename the directory */ - dest_path = g_build_path (G_DIR_SEPARATOR_S, fixture->not_monitored_directory, "foo", NULL); - dest_dir = g_file_new_for_path (dest_path); - - g_assert_cmpint (g_rename (source_path, dest_path), ==, 0); - - g_hash_table_insert (fixture->events, - g_object_ref (source_dir), - GUINT_TO_POINTER (MONITOR_SIGNAL_NONE)); - g_hash_table_insert (fixture->events, - g_object_ref (dest_dir), - GUINT_TO_POINTER (MONITOR_SIGNAL_NONE)); - - /* Wait for events */ - events_wait (fixture); - - /* Get events in the source dir */ - file_events = GPOINTER_TO_UINT (g_hash_table_lookup (fixture->events, source_dir)); - /* Fail if we didn't get the DELETED signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_DELETED), >, 0); - /* Fail if we got a CREATE, UPDATE, MOVE_FROM or MOVE_TO signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_CREATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_UPDATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_ATTRIBUTE_UPDATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_FROM), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_TO), ==, 0); - - /* Get events in the dest file */ - file_events = GPOINTER_TO_UINT (g_hash_table_lookup (fixture->events, dest_dir)); - /* Fail if we got any signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_CREATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_UPDATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_ATTRIBUTE_UPDATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_FROM), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_TO), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_DELETED), ==, 0); - - /* Cleanup environment */ - tracker_monitor_set_enabled (fixture->monitor, FALSE); - g_assert_cmpint (tracker_monitor_remove (fixture->monitor, source_dir), ==, TRUE); - /* Note that monitor is NOT in dest_dir, so FAIL if we could remove it */ - g_assert_cmpint (tracker_monitor_remove (fixture->monitor, dest_dir), !=, TRUE); - g_assert_cmpint (g_file_delete (dest_dir, NULL, NULL), ==, TRUE); - g_object_unref (source_dir); - g_object_unref (dest_dir); - g_free (source_path); - g_free (dest_path); -} - -static void -test_monitor_directory_event_moved_from_not_monitored (TrackerMonitorTestFixture *fixture, - gconstpointer data) -{ - GFile *source_dir; - gchar *source_path; - GFile *dest_dir; - gchar *dest_path; - guint file_events; - - /* Create directory to test with in a not-monitored place, - * before setting up the environment */ - create_directory (fixture->not_monitored_directory, "foo", &source_dir); - source_path = g_file_get_path (source_dir); - g_assert (source_dir != NULL); - - /* Set up environment */ - tracker_monitor_set_enabled (fixture->monitor, TRUE); - - /* Now, rename the directory to somewhere monitored */ - dest_path = g_build_path (G_DIR_SEPARATOR_S, fixture->monitored_directory, "foo", NULL); - dest_dir = g_file_new_for_path (dest_path); - - g_assert_cmpint (g_rename (source_path, dest_path), ==, 0); - - g_hash_table_insert (fixture->events, - g_object_ref (source_dir), - GUINT_TO_POINTER (MONITOR_SIGNAL_NONE)); - g_hash_table_insert (fixture->events, - g_object_ref (dest_dir), - GUINT_TO_POINTER (MONITOR_SIGNAL_NONE)); - - /* Wait for events */ - events_wait (fixture); - - /* Get events in the source dir */ - file_events = GPOINTER_TO_UINT (g_hash_table_lookup (fixture->events, source_dir)); - /* Fail if we got any signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_CREATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_UPDATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_ATTRIBUTE_UPDATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_FROM), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_TO), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_DELETED), ==, 0); - - /* Get events in the dest file */ - file_events = GPOINTER_TO_UINT (g_hash_table_lookup (fixture->events, dest_dir)); - /* Fail if we didn't get the CREATED signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_CREATED), >, 0); - /* Fail if we got a CREATE, UPDATE, MOVE_FROM or MOVE_TO signal */ - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_UPDATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_ATTRIBUTE_UPDATED), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_FROM), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_MOVED_TO), ==, 0); - g_assert_cmpuint ((file_events & MONITOR_SIGNAL_ITEM_DELETED), ==, 0); - - /* Cleanup environment */ - tracker_monitor_set_enabled (fixture->monitor, FALSE); - /* Note that monitor is now in dest_dir, BUT TrackerMonitor should - * NOT add automatically a new monitor, so FAIL if we can remove it */ - g_assert_cmpint (tracker_monitor_remove (fixture->monitor, dest_dir), !=, TRUE); - g_assert_cmpint (g_file_delete (dest_dir, NULL, NULL), ==, TRUE); - g_object_unref (source_dir); - g_object_unref (dest_dir); - g_free (source_path); - g_free (dest_path); -} - -/* ----------------------------- BASIC API TESTS --------------------------------- */ - -static void -test_monitor_basic (void) -{ - TrackerMonitor *monitor; - gchar *basename; - gchar *path_for_monitor; - GFile *file_for_monitor; - GFile *file_for_tmp; - - /* Setup directories */ - basename = g_strdup_printf ("monitor-test-%d", getpid ()); - path_for_monitor = g_build_path (G_DIR_SEPARATOR_S, g_get_tmp_dir (), basename, NULL); - g_free (basename); - g_assert_cmpint (g_mkdir_with_parents (path_for_monitor, 00755), ==, 0); - - file_for_monitor = g_file_new_for_path (path_for_monitor); - g_assert (G_IS_FILE (file_for_monitor)); - - file_for_tmp = g_file_new_for_path (g_get_tmp_dir ()); - g_assert (G_IS_FILE (file_for_tmp)); - - /* Create a monitor */ - monitor = tracker_monitor_new (); - g_assert (monitor != NULL); - - /* Test general API with monitors enabled */ - tracker_monitor_set_enabled (monitor, TRUE); - g_assert_cmpint (tracker_monitor_get_enabled (monitor), ==, TRUE); - - g_assert_cmpint (tracker_monitor_get_count (monitor), ==, 0); - g_assert_cmpint (tracker_monitor_add (monitor, file_for_monitor), ==, TRUE); - g_assert_cmpint (tracker_monitor_add (monitor, file_for_monitor), ==, TRUE); /* Test double add on purpose */ - g_assert_cmpint (tracker_monitor_get_count (monitor), ==, 1); - g_assert_cmpint (tracker_monitor_is_watched (monitor, file_for_monitor), ==, TRUE); - g_assert_cmpint (tracker_monitor_is_watched_by_string (monitor, path_for_monitor), ==, TRUE); - g_assert_cmpint (tracker_monitor_remove (monitor, file_for_monitor), ==, TRUE); - g_assert_cmpint (tracker_monitor_is_watched (monitor, file_for_monitor), ==, FALSE); - g_assert_cmpint (tracker_monitor_is_watched_by_string (monitor, path_for_monitor), ==, FALSE); - g_assert_cmpint (tracker_monitor_get_count (monitor), ==, 0); - - tracker_monitor_add (monitor, file_for_monitor); - tracker_monitor_add (monitor, file_for_tmp); - g_assert_cmpint (tracker_monitor_get_count (monitor), ==, 2); - g_assert_cmpint (tracker_monitor_remove_recursively (monitor, file_for_tmp), ==, TRUE); - g_assert_cmpint (tracker_monitor_get_count (monitor), ==, 0); - - /* Test general API with monitors disabled */ - tracker_monitor_set_enabled (monitor, FALSE); - g_assert_cmpint (tracker_monitor_get_enabled (monitor), ==, FALSE); - - g_assert_cmpint (tracker_monitor_get_count (monitor), ==, 0); - g_assert_cmpint (tracker_monitor_add (monitor, file_for_monitor), ==, TRUE); - g_assert_cmpint (tracker_monitor_get_count (monitor), ==, 1); - g_assert_cmpint (tracker_monitor_is_watched (monitor, file_for_monitor), ==, FALSE); - g_assert_cmpint (tracker_monitor_is_watched_by_string (monitor, path_for_monitor), ==, FALSE); - g_assert_cmpint (tracker_monitor_remove (monitor, file_for_monitor), ==, TRUE); - g_assert_cmpint (tracker_monitor_is_watched (monitor, file_for_monitor), ==, FALSE); - g_assert_cmpint (tracker_monitor_is_watched_by_string (monitor, path_for_monitor), ==, FALSE); - g_assert_cmpint (tracker_monitor_get_count (monitor), ==, 0); - - tracker_monitor_add (monitor, file_for_monitor); - tracker_monitor_add (monitor, file_for_tmp); - g_assert_cmpint (tracker_monitor_get_count (monitor), ==, 2); - g_assert_cmpint (tracker_monitor_remove_recursively (monitor, file_for_tmp), ==, TRUE); - g_assert_cmpint (tracker_monitor_get_count (monitor), ==, 0); - - /* Cleanup */ - g_assert_cmpint (g_rmdir (path_for_monitor), ==, 0); - g_assert (file_for_tmp != NULL); - g_object_unref (file_for_tmp); - g_assert (file_for_monitor != NULL); - g_object_unref (file_for_monitor); - g_assert (path_for_monitor != NULL); - g_free (path_for_monitor); - g_assert (monitor != NULL); - g_object_unref (monitor); -} - -gint -main (gint argc, - gchar **argv) -{ - g_test_init (&argc, &argv, NULL); - - tracker_log_init (0, NULL); - - g_test_message ("Testing filesystem monitor"); - - /* Basic API tests */ - g_test_add_func ("/libtracker-miner/tracker-monitor/basic", - test_monitor_basic); - - /* File Event tests */ - g_test_add ("/libtracker-miner/tracker-monitor/file-event/created", - TrackerMonitorTestFixture, - NULL, - test_monitor_common_setup, - test_monitor_file_event_created, - test_monitor_common_teardown); - g_test_add ("/libtracker-miner/tracker-monitor/file-event/updated", - TrackerMonitorTestFixture, - NULL, - test_monitor_common_setup, - test_monitor_file_event_updated, - test_monitor_common_teardown); - g_test_add ("/libtracker-miner/tracker-monitor/file-event/attribute-updated", - TrackerMonitorTestFixture, - NULL, - test_monitor_common_setup, - test_monitor_file_event_attribute_updated, - test_monitor_common_teardown); - g_test_add ("/libtracker-miner/tracker-monitor/file-event/deleted", - TrackerMonitorTestFixture, - NULL, - test_monitor_common_setup, - test_monitor_file_event_deleted, - test_monitor_common_teardown); - g_test_add ("/libtracker-miner/tracker-monitor/file-event/moved/to-monitored", - TrackerMonitorTestFixture, - NULL, - test_monitor_common_setup, - test_monitor_file_event_moved_to_monitored, - test_monitor_common_teardown); - g_test_add ("/libtracker-miner/tracker-monitor/file-event/moved/to-not-monitored", - TrackerMonitorTestFixture, - NULL, - test_monitor_common_setup, - test_monitor_file_event_moved_to_not_monitored, - test_monitor_common_teardown); - g_test_add ("/libtracker-miner/tracker-monitor/file-event/moved/from-not-monitored", - TrackerMonitorTestFixture, - NULL, - test_monitor_common_setup, - test_monitor_file_event_moved_from_not_monitored, - test_monitor_common_teardown); - - /* Directory Event tests */ - g_test_add ("/libtracker-miner/tracker-monitor/directory-event/created", - TrackerMonitorTestFixture, - NULL, - test_monitor_common_setup, - test_monitor_directory_event_created, - test_monitor_common_teardown); - g_test_add ("/libtracker-miner/tracker-monitor/directory-event/deleted", - TrackerMonitorTestFixture, - NULL, - test_monitor_common_setup, - test_monitor_directory_event_deleted, - test_monitor_common_teardown); - g_test_add ("/libtracker-miner/tracker-monitor/directory-event/moved/to-monitored", - TrackerMonitorTestFixture, - NULL, - test_monitor_common_setup, - test_monitor_directory_event_moved_to_monitored, - test_monitor_common_teardown); - g_test_add ("/libtracker-miner/tracker-monitor/directory-event/moved/to-monitored-after-file-create", - TrackerMonitorTestFixture, - NULL, - test_monitor_common_setup, - test_monitor_directory_event_moved_to_monitored_after_file_create, - test_monitor_common_teardown); - g_test_add ("/libtracker-miner/tracker-monitor/directory-event/moved/to-monitored-after-file-update", - TrackerMonitorTestFixture, - NULL, - test_monitor_common_setup, - test_monitor_directory_event_moved_to_monitored_after_file_update, - test_monitor_common_teardown); - g_test_add ("/libtracker-miner/tracker-monitor/directory-event/moved/to-not-monitored", - TrackerMonitorTestFixture, - NULL, - test_monitor_common_setup, - test_monitor_directory_event_moved_to_not_monitored, - test_monitor_common_teardown); - g_test_add ("/libtracker-miner/tracker-monitor/directory-event/moved/from-not-monitored", - TrackerMonitorTestFixture, - NULL, - test_monitor_common_setup, - test_monitor_directory_event_moved_from_not_monitored, - test_monitor_common_teardown); - - return g_test_run (); -} diff --git a/tests/libtracker-miner/tracker-priority-queue-test.c b/tests/libtracker-miner/tracker-priority-queue-test.c deleted file mode 100644 index 2d5c6333c..000000000 --- a/tests/libtracker-miner/tracker-priority-queue-test.c +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright (C) 2010, Nokia <ivan.frade@nokia.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include <glib-object.h> - -/* NOTE: We're not including tracker-miner.h here because this is private. */ -#include <libtracker-miner/tracker-priority-queue.h> - -static void -test_priority_queue_ref_unref (void) -{ - TrackerPriorityQueue *one, *two; - - one = tracker_priority_queue_new (); - two = tracker_priority_queue_ref (one); - - tracker_priority_queue_unref (two); - tracker_priority_queue_unref (one); -} - -static void -test_priority_queue_emptiness (void) -{ - TrackerPriorityQueue *one; - - one = tracker_priority_queue_new (); - - g_assert (tracker_priority_queue_is_empty (one)); - g_assert_cmpint (tracker_priority_queue_get_length (one), ==, 0); - - tracker_priority_queue_unref (one); -} - -static void -test_priority_queue_insertion_pop (void) -{ - TrackerPriorityQueue *queue; - int i, priority; - gchar *text, *expected; - - queue = tracker_priority_queue_new (); - - /* Insert in to loops to "mix" priorities in the insertion */ - for (i = 1; i <= 10; i+=2) { - tracker_priority_queue_add (queue, g_strdup_printf ("test content %i", i), i); - } - - for (i = 2; i <= 10; i+=2) { - tracker_priority_queue_add (queue, g_strdup_printf ("test content %i", i), i); - } - - for (i = 1; i <= 10; i++) { - expected = g_strdup_printf ("test content %i", i); - - text = (gchar *)tracker_priority_queue_pop (queue, &priority); - - g_assert_cmpint (priority, ==, i); - g_assert_cmpstr (text, ==, expected); - - g_free (expected); - g_free (text); - } - - g_assert (tracker_priority_queue_is_empty (queue)); - tracker_priority_queue_unref (queue); -} - -static void -test_priority_queue_peek (void) -{ - TrackerPriorityQueue *queue; - gchar *result; - gint priority; - - queue = tracker_priority_queue_new (); - - result = tracker_priority_queue_peek (queue, &priority); - g_assert (result == NULL); - - tracker_priority_queue_add (queue, g_strdup ("Low prio"), 10); - tracker_priority_queue_add (queue, g_strdup ("High prio"), 1); - - result = tracker_priority_queue_peek (queue, &priority); - g_assert_cmpint (priority, ==, 1); - g_assert_cmpstr (result, ==, "High prio"); - - result = tracker_priority_queue_pop (queue, &priority); - g_free (result); - - result = tracker_priority_queue_peek (queue, &priority); - g_assert_cmpint (priority, ==, 10); - g_assert_cmpstr (result, ==, "Low prio"); - - result = tracker_priority_queue_pop (queue, &priority); - g_free (result); - - tracker_priority_queue_unref (queue); -} - -static void -test_priority_queue_find (void) -{ - TrackerPriorityQueue *queue; - gchar *result; - int priority; - - queue = tracker_priority_queue_new (); - - tracker_priority_queue_add (queue, g_strdup ("search me"), 10); - tracker_priority_queue_add (queue, g_strdup ("Not me"), 1); - tracker_priority_queue_add (queue, g_strdup ("Not me either"), 20); - - result = (gchar *) tracker_priority_queue_find (queue, &priority, g_str_equal, "search me"); - g_assert_cmpstr (result, !=, NULL); - g_assert_cmpint (priority, ==, 10); - - while (!tracker_priority_queue_is_empty (queue)) { - gchar *text = (gchar *) tracker_priority_queue_pop (queue, NULL); - g_free (text); - } - - tracker_priority_queue_unref (queue); -} - -static void -foreach_testing_cb (G_GNUC_UNUSED gpointer data, - gpointer user_data) -{ - gint *counter = (gint *)user_data; - (*counter) += 1; -} - -static void -test_priority_queue_foreach (void) -{ - TrackerPriorityQueue *queue; - gint counter = 0; - - queue = tracker_priority_queue_new (); - - tracker_priority_queue_add (queue, g_strdup ("x"), 10); - tracker_priority_queue_add (queue, g_strdup ("x"), 20); - tracker_priority_queue_add (queue, g_strdup ("x"), 30); - - tracker_priority_queue_foreach (queue, foreach_testing_cb, &counter); - - g_assert_cmpint (counter, ==, 3); - - while (!tracker_priority_queue_is_empty (queue)) { - gchar *text = (gchar *) tracker_priority_queue_pop (queue, NULL); - g_free (text); - } - - tracker_priority_queue_unref (queue); -} - -static void -test_priority_queue_foreach_remove (void) -{ - TrackerPriorityQueue *queue; - - queue = tracker_priority_queue_new (); - - tracker_priority_queue_add (queue, g_strdup ("y"), 1); - tracker_priority_queue_add (queue, g_strdup ("x"), 2); - tracker_priority_queue_add (queue, g_strdup ("y"), 3); - tracker_priority_queue_add (queue, g_strdup ("x"), 4); - tracker_priority_queue_add (queue, g_strdup ("y"), 5); - g_assert_cmpint (tracker_priority_queue_get_length (queue), ==, 5); - - tracker_priority_queue_foreach_remove (queue, g_str_equal, "y", g_free); - g_assert_cmpint (tracker_priority_queue_get_length (queue), ==, 2); - - tracker_priority_queue_foreach_remove (queue, g_str_equal, "x", g_free); - g_assert_cmpint (tracker_priority_queue_get_length (queue), ==, 0); - - tracker_priority_queue_unref (queue); -} - -static void -test_priority_queue_branches (void) -{ - - /* Few specific testing to improve the branch coverage */ - - TrackerPriorityQueue *queue; - gchar *result; - gint priority; - - queue = tracker_priority_queue_new (); - - /* Removal on empty list */ - tracker_priority_queue_foreach_remove (queue, g_str_equal, "y", g_free); - - - /* Insert multiple elements in the same priority */ - tracker_priority_queue_add (queue, g_strdup ("x"), 5); - tracker_priority_queue_add (queue, g_strdup ("y"), 5); - tracker_priority_queue_add (queue, g_strdup ("z"), 5); - - g_assert_cmpint (tracker_priority_queue_get_length (queue), ==, 3); - - /* Removal with multiple elements in same priority*/ - g_assert (tracker_priority_queue_foreach_remove (queue, g_str_equal, "z", g_free)); - g_assert (tracker_priority_queue_foreach_remove (queue, g_str_equal, "x", g_free)); - - - /* Pop those elements */ - result = tracker_priority_queue_pop (queue, &priority); - g_assert_cmpint (priority, ==, 5); - g_free (result); - - g_assert_cmpint (tracker_priority_queue_get_length (queue), ==, 0); - /* Pop on empty queue */ - result = tracker_priority_queue_pop (queue, &priority); - g_assert (result == NULL); - - tracker_priority_queue_unref (queue); -} - -int -main (int argc, - char **argv) -{ - g_test_init (&argc, &argv, NULL); - - g_test_add_func ("/libtracker-miner/tracker-priority-queue/emptiness", - test_priority_queue_emptiness); - g_test_add_func ("/libtracker-miner/tracker-priority-queue/ref_unref", - test_priority_queue_ref_unref); - g_test_add_func ("/libtracker-miner/tracker-priority-queue/insertion", - test_priority_queue_insertion_pop); - g_test_add_func ("/libtracker-miner/tracker-priority-queue/peek", - test_priority_queue_peek); - g_test_add_func ("/libtracker-miner/tracker-priority-queue/find", - test_priority_queue_find); - g_test_add_func ("/libtracker-miner/tracker-priority-queue/foreach", - test_priority_queue_foreach); - g_test_add_func ("/libtracker-miner/tracker-priority-queue/foreach_remove", - test_priority_queue_foreach_remove); - - g_test_add_func ("/libtracker-miner/tracker-priority-queue/branches", - test_priority_queue_branches); - - return g_test_run (); -} diff --git a/tests/libtracker-miner/tracker-task-pool-test.c b/tests/libtracker-miner/tracker-task-pool-test.c deleted file mode 100644 index 0ece7c39f..000000000 --- a/tests/libtracker-miner/tracker-task-pool-test.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (C) 2011, Nokia <ivan.frade@nokia.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ -#include <glib.h> - -/* NOTE: We're not including tracker-miner.h here because this is private. */ -#include <libtracker-miner/tracker-task-pool.h> - -static void -test_task_pool_limit_set (void) -{ - TrackerTaskPool *pool; - - pool = tracker_task_pool_new (5); - g_assert_cmpint (tracker_task_pool_get_limit(pool), ==, 5); - - tracker_task_pool_set_limit (pool, 3); - g_assert_cmpint (tracker_task_pool_get_limit(pool), ==, 3); - - g_assert (tracker_task_pool_limit_reached (pool) == FALSE); - g_object_unref (pool); -} - -static void -add_task (TrackerTaskPool *pool, - const gchar *filename, - gint expected_size, - gboolean hit_limit) -{ - TrackerTask *task; - - task = tracker_task_new (g_file_new_for_path (filename), NULL, NULL); - tracker_task_pool_add (pool, task); - - g_assert_cmpint (tracker_task_pool_get_size (pool), ==, expected_size); - g_assert (tracker_task_pool_limit_reached (pool) == hit_limit); - - g_object_unref (tracker_task_get_file (task)); - tracker_task_unref (task); -} - -static void -remove_task (TrackerTaskPool *pool, - const gchar *filename, - gint expected_size, - gboolean hit_limit) -{ - TrackerTask *task; - - task = tracker_task_new (g_file_new_for_path (filename), NULL, NULL); - tracker_task_pool_remove (pool, task); - - g_assert_cmpint (tracker_task_pool_get_size (pool), ==, expected_size); - g_assert (hit_limit == tracker_task_pool_limit_reached (pool)); - - g_object_unref (tracker_task_get_file (task)); - tracker_task_unref (task); -} - -static void -test_task_pool_add_remove (void) -{ - TrackerTaskPool *pool; - - pool = tracker_task_pool_new (3); - - /* Additions ... */ - add_task (pool, "/dev/null", 1, FALSE); - add_task (pool, "/dev/null2", 2, FALSE); - add_task (pool, "/dev/null3", 3, TRUE); - - /* We can go over the limit */ - add_task (pool, "/dev/null4", 4, TRUE); - - /* Remove something that doesn't exist */ - remove_task (pool, "/dev/null/imNotInThePool", 4, TRUE); - - /* Removals ... (in different order)*/ - remove_task (pool, "/dev/null4", 3, TRUE); - remove_task (pool, "/dev/null2", 2, FALSE); - remove_task (pool, "/dev/null3", 1, FALSE); - remove_task (pool, "/dev/null", 0, FALSE); - - /* Remove in empty queue */ - remove_task (pool, "/dev/null/random", 0, FALSE); - - g_object_unref (pool); -} - -static void -test_task_pool_find (void) -{ - TrackerTaskPool *pool; - TrackerTask *task; - GFile *goal; - - pool = tracker_task_pool_new (3); - - add_task (pool, "/dev/null", 1, FALSE); - add_task (pool, "/dev/null2", 2, FALSE); - add_task (pool, "/dev/null3", 3, TRUE); - - /* Search first, last, in the middle... */ - goal = g_file_new_for_path ("/dev/null2"); - task = tracker_task_pool_find (pool, goal); - g_assert (task); - g_object_unref (goal); - - goal = g_file_new_for_path ("/dev/null"); - task = tracker_task_pool_find (pool, goal); - g_assert (task); - g_object_unref (goal); - - goal = g_file_new_for_path ("/dev/null3"); - task = tracker_task_pool_find (pool, goal); - g_assert (task); - g_object_unref (goal); - - goal = g_file_new_for_path ("/dev/thisDoesntExists"); - task = tracker_task_pool_find (pool, goal); - g_assert (task == NULL); - g_object_unref (goal); - - g_object_unref (pool); -} - -static void -count_elements_cb (gpointer data, - gpointer user_data) -{ - gint *counter = (gint*)user_data; - (*counter) += 1; -} - -static void -test_task_pool_foreach (void) -{ - TrackerTaskPool *pool; - int counter = 0; - - pool = tracker_task_pool_new (3); - - add_task (pool, "/dev/null", 1, FALSE); - add_task (pool, "/dev/null2", 2, FALSE); - add_task (pool, "/dev/null3", 3, TRUE); - - tracker_task_pool_foreach (pool, count_elements_cb, &counter); - - g_assert_cmpint (counter, ==, 3); -} - -gint -main (gint argc, gchar **argv) -{ - g_test_init (&argc, &argv, NULL); - - g_test_add_func ("/libtracker-miner/tracker-task-pool/limit_set", - test_task_pool_limit_set); - - g_test_add_func ("/libtracker-miner/tracker-task-pool/add_remove", - test_task_pool_add_remove); - - g_test_add_func ("/libtracker-miner/tracker-task-pool/find", - test_task_pool_find); - - g_test_add_func ("/libtracker-miner/tracker-task-pool/foreach", - test_task_pool_foreach); - - return g_test_run (); -} diff --git a/tests/libtracker-miner/tracker-thumbnailer-test.c b/tests/libtracker-miner/tracker-thumbnailer-test.c deleted file mode 100644 index 9c05a1024..000000000 --- a/tests/libtracker-miner/tracker-thumbnailer-test.c +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (C) 2010, Nokia <ivan.frade@nokia.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include <glib.h> -#include <glib-object.h> -#include <libtracker-miner/tracker-miner.h> -#include "thumbnailer-mock.h" - -#if 0 -/* port thumbnailer-mock.c to gdbus first */ - -static void -test_thumbnailer_init () -{ - g_assert (tracker_thumbnailer_init ()); - - tracker_thumbnailer_shutdown (); -} - -static void -test_thumbnailer_send_empty () -{ - GList *dbus_calls = NULL; - - dbus_mock_call_log_reset (); - - tracker_thumbnailer_init (); - tracker_thumbnailer_send (); - - dbus_calls = dbus_mock_call_log_get (); - g_assert (dbus_calls == NULL); - - tracker_thumbnailer_shutdown (); -} - -static void -test_thumbnailer_send_moves () -{ - GList *dbus_calls = NULL; - - dbus_mock_call_log_reset (); - - tracker_thumbnailer_init (); - /* Returns TRUE, but there is no dbus call */ - g_assert (tracker_thumbnailer_move_add ("file://a.jpeg", "mock/one", "file://b.jpeg")); - g_assert (dbus_mock_call_log_get () == NULL); - - /* Returns FALSE, unsupported mime */ - g_assert (!tracker_thumbnailer_move_add ("file://a.jpeg", "unsupported", "file://b.jpeg")); - g_assert (dbus_mock_call_log_get () == NULL); - - tracker_thumbnailer_send (); - - /* One call to "move" method */ - dbus_calls = dbus_mock_call_log_get (); - g_assert_cmpint (g_list_length (dbus_calls), ==, 1); - g_assert_cmpstr (dbus_calls->data, ==, "Move"); - - tracker_thumbnailer_shutdown (); - dbus_mock_call_log_reset (); -} - -static void -test_thumbnailer_send_removes () -{ - GList *dbus_calls = NULL; - - dbus_mock_call_log_reset (); - - - tracker_thumbnailer_init (); - - /* Returns TRUE, but there is no dbus call */ - g_assert (tracker_thumbnailer_remove_add ("file://a.jpeg", "mock/one")); - g_assert (dbus_mock_call_log_get () == NULL); - - /* Returns FALSE, unsupported mime */ - g_assert (!tracker_thumbnailer_remove_add ("file://a.jpeg", "unsupported")); - g_assert (dbus_mock_call_log_get () == NULL); - - tracker_thumbnailer_send (); - - /* One call to "Delete" method */ - dbus_calls = dbus_mock_call_log_get (); - g_assert_cmpint (g_list_length (dbus_calls), ==, 1); - g_assert_cmpstr (dbus_calls->data, ==, "Delete"); - - tracker_thumbnailer_shutdown (); - dbus_mock_call_log_reset (); -} - -static void -test_thumbnailer_send_cleanup () -{ - GList *dbus_calls = NULL; - - dbus_mock_call_log_reset (); - - tracker_thumbnailer_init (); - - /* Returns TRUE, and there is a dbus call */ - g_assert (tracker_thumbnailer_cleanup ("file://tri/lu/ri")); - - /* One call to "Clean" method */ - dbus_calls = dbus_mock_call_log_get (); - g_assert_cmpint (g_list_length (dbus_calls), ==, 1); - g_assert_cmpstr (dbus_calls->data, ==, "Cleanup"); - - tracker_thumbnailer_shutdown (); - dbus_mock_call_log_reset (); -} - -#endif - -int -main (int argc, - char **argv) -{ - g_test_init (&argc, &argv, NULL); - - g_test_message ("Testing thumbnailer"); - -#if 0 -/* port thumbnailer-mock.c to gdbus first */ - - g_test_add_func ("/libtracker-miner/tracker-thumbnailer/init", - test_thumbnailer_init); - g_test_add_func ("/libtracker-miner/tracker-thumbnailer/send_empty", - test_thumbnailer_send_empty); - g_test_add_func ("/libtracker-minter/tracker-thumbnailer/send_moves", - test_thumbnailer_send_moves); - g_test_add_func ("/libtracker-minter/tracker-thumbnailer/send_removes", - test_thumbnailer_send_removes); - g_test_add_func ("/libtracker-minter/tracker-thumbnailer/send_cleanup", - test_thumbnailer_send_cleanup); - -#endif - - return g_test_run (); -} diff --git a/tests/meson.build b/tests/meson.build index c7467781a..aaa0ea0ae 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -10,7 +10,6 @@ if enable_fts subdir('libtracker-fts') endif -subdir('libtracker-miner') subdir('libtracker-sparql') subdir('tracker-steroids') |