summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2023-03-19 22:28:15 +0000
committerCarlos Garnacho <carlosg@gnome.org>2023-03-19 22:28:15 +0000
commitc193deb5cec38c48f3331a72314bdb776963efde (patch)
tree186bd96c0f467d91a07ff4a43cce7704e0cf6301
parenta9fb50417dd4cd5a8a00efdf5400cb63e8c07d8e (diff)
parentcc9aa412bb8c3c2836af5944b96b9fa3baf1f7f2 (diff)
downloadtracker-c193deb5cec38c48f3331a72314bdb776963efde.tar.gz
Merge branch 'wip/carlosg/docs-improvements' into 'master'
Documentation improvements See merge request https://gitlab.gnome.org/GNOME/tracker/-/merge_requests/584
-rw-r--r--docs/manpages/tracker-xdg-portal-3.1.txt4
-rw-r--r--docs/reference/libtracker-sparql/images/graph-example-diagram.dot29
-rw-r--r--docs/reference/libtracker-sparql/images/graph-example-diagram.svg89
-rw-r--r--docs/reference/libtracker-sparql/images/sandbox-diagram.dot46
-rw-r--r--docs/reference/libtracker-sparql/images/sandbox-diagram.svg101
-rw-r--r--docs/reference/libtracker-sparql/meson.build7
-rw-r--r--docs/reference/libtracker-sparql/overview.md59
-rw-r--r--docs/reference/libtracker-sparql/overview.md.in83
-rw-r--r--docs/reference/libtracker-sparql/sandboxing.md.in122
-rw-r--r--docs/reference/libtracker-sparql/style.xml8
-rw-r--r--docs/reference/libtracker-sparql/tutorial.md.in2
-rw-r--r--docs/tools/tracker-docgen-md.c4
12 files changed, 491 insertions, 63 deletions
diff --git a/docs/manpages/tracker-xdg-portal-3.1.txt b/docs/manpages/tracker-xdg-portal-3.1.txt
index 664db5b77..fe2884cdf 100644
--- a/docs/manpages/tracker-xdg-portal-3.1.txt
+++ b/docs/manpages/tracker-xdg-portal-3.1.txt
@@ -34,7 +34,9 @@ This will allow access to the endpoints behind the *org.example.SparqlEndpoint1*
This policy can be set when building or running the sandboxed application through the --add-policy option. This can be set via **finish-args** in the flatpak manifest, specified along the build chain in *flatpak-build-finish*(1), or modified at start time with *flatpak-run*(1). For example:
$ flatpak run \
- --add-policy=Tracker3.dbus:org.example.SparqlEndpoint1=graphA;graphB;default \
+ --add-policy=Tracker3.dbus:org.example.SparqlEndpoint1=graphA \
+ --add-policy=Tracker3.dbus:org.example.SparqlEndpoint1=graphB \
+ --add-policy=Tracker3.dbus:org.example.SparqlEndpoint1=default \
--add-policy=Tracker3.dbus:org.example.SparqlEndpoint2=* \
org.freedesktop.TrackerSandbox
diff --git a/docs/reference/libtracker-sparql/images/graph-example-diagram.dot b/docs/reference/libtracker-sparql/images/graph-example-diagram.dot
new file mode 100644
index 000000000..22b7b646e
--- /dev/null
+++ b/docs/reference/libtracker-sparql/images/graph-example-diagram.dot
@@ -0,0 +1,29 @@
+digraph {
+ rankdir=LR;
+ bgcolor=transparent;
+ fontname="sans-serif";
+ compound=true;
+ node [shape="box", style="rounded", border=0, fontname="sans-serif"];
+
+ subgraph cluster_graph2 {
+ style="rounded";
+ color="lightgrey";
+ label = "example:B"
+ tooltip = "example:B"
+ fontsize=10;
+ item2[label="example:item2",tooltip="example:item2"];
+ type2[label="rdfs:Resource",tooltip="rdfs:Resource"];
+ item2 -> type2 [label="rdf:type",fontsize=10,fontname="sans-serif",tooltip="rdf:type",labeltooltip="rdf:type"];
+ }
+
+ subgraph cluster_graph1 {
+ style="rounded";
+ color="lightgrey";
+ label = "example:A"
+ tooltip = "example:A"
+ fontsize=10;
+ item1[label="example:item1",tooltip="example:item1"];
+ type1[label="rdfs:Resource",tooltip="rdfs:Resource"];
+ item1 -> type1 [label="rdf:type",fontsize=10,fontname="sans-serif",tooltip="rdf:type",labeltooltip="rdf:type"];
+ }
+}
diff --git a/docs/reference/libtracker-sparql/images/graph-example-diagram.svg b/docs/reference/libtracker-sparql/images/graph-example-diagram.svg
new file mode 100644
index 000000000..18ae08536
--- /dev/null
+++ b/docs/reference/libtracker-sparql/images/graph-example-diagram.svg
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
+ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<!-- Generated by graphviz version 7.1.0 (0)
+ -->
+<!-- Pages: 1 -->
+<svg width="335pt" height="174pt"
+ viewBox="0.00 0.00 335.00 174.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 170)">
+<g id="clust1" class="cluster">
+<title>cluster_graph2</title>
+<g id="a_clust1"><a xlink:title="example:B">
+<path fill="none" stroke="lightgrey" d="M20,-8C20,-8 307,-8 307,-8 313,-8 319,-14 319,-20 319,-20 319,-67 319,-67 319,-73 313,-79 307,-79 307,-79 20,-79 20,-79 14,-79 8,-73 8,-67 8,-67 8,-20 8,-20 8,-14 14,-8 20,-8"/>
+<text text-anchor="middle" x="163.5" y="-67" font-family="sans-serif" font-size="10.00">example:B</text>
+</a>
+</g>
+</g>
+<g id="clust2" class="cluster">
+<title>cluster_graph1</title>
+<g id="a_clust2"><a xlink:title="example:A">
+<path fill="none" stroke="lightgrey" d="M20,-87C20,-87 307,-87 307,-87 313,-87 319,-93 319,-99 319,-99 319,-146 319,-146 319,-152 313,-158 307,-158 307,-158 20,-158 20,-158 14,-158 8,-152 8,-146 8,-146 8,-99 8,-99 8,-93 14,-87 20,-87"/>
+<text text-anchor="middle" x="163.5" y="-146" font-family="sans-serif" font-size="10.00">example:A</text>
+</a>
+</g>
+</g>
+<!-- item2 -->
+<g id="node1" class="node">
+<title>item2</title>
+<g id="a_node1"><a xlink:title="example:item2">
+<path fill="none" stroke="black" d="M118,-52C118,-52 28,-52 28,-52 22,-52 16,-46 16,-40 16,-40 16,-28 16,-28 16,-22 22,-16 28,-16 28,-16 118,-16 118,-16 124,-16 130,-22 130,-28 130,-28 130,-40 130,-40 130,-46 124,-52 118,-52"/>
+<text text-anchor="middle" x="73" y="-30.3" font-family="sans-serif" font-size="14.00">example:item2</text>
+</a>
+</g>
+</g>
+<!-- type2 -->
+<g id="node2" class="node">
+<title>type2</title>
+<g id="a_node2"><a xlink:title="rdfs:Resource">
+<path fill="none" stroke="black" d="M299,-52C299,-52 216,-52 216,-52 210,-52 204,-46 204,-40 204,-40 204,-28 204,-28 204,-22 210,-16 216,-16 216,-16 299,-16 299,-16 305,-16 311,-22 311,-28 311,-28 311,-40 311,-40 311,-46 305,-52 299,-52"/>
+<text text-anchor="middle" x="257.5" y="-30.3" font-family="sans-serif" font-size="14.00">rdfs:Resource</text>
+</a>
+</g>
+</g>
+<!-- item2&#45;&gt;type2 -->
+<g id="edge1" class="edge">
+<title>item2&#45;&gt;type2</title>
+<g id="a_edge1"><a xlink:title="rdf:type">
+<path fill="none" stroke="black" d="M130.25,-34C149.86,-34 172.02,-34 192.23,-34"/>
+<polygon fill="black" stroke="black" points="192.04,-37.5 202.04,-34 192.04,-30.5 192.04,-37.5"/>
+</a>
+</g>
+<g id="a_edge1&#45;label"><a xlink:title="rdf:type">
+<text text-anchor="middle" x="167" y="-37" font-family="sans-serif" font-size="10.00">rdf:type</text>
+</a>
+</g>
+</g>
+<!-- item1 -->
+<g id="node3" class="node">
+<title>item1</title>
+<g id="a_node3"><a xlink:title="example:item1">
+<path fill="none" stroke="black" d="M118,-131C118,-131 28,-131 28,-131 22,-131 16,-125 16,-119 16,-119 16,-107 16,-107 16,-101 22,-95 28,-95 28,-95 118,-95 118,-95 124,-95 130,-101 130,-107 130,-107 130,-119 130,-119 130,-125 124,-131 118,-131"/>
+<text text-anchor="middle" x="73" y="-109.3" font-family="sans-serif" font-size="14.00">example:item1</text>
+</a>
+</g>
+</g>
+<!-- type1 -->
+<g id="node4" class="node">
+<title>type1</title>
+<g id="a_node4"><a xlink:title="rdfs:Resource">
+<path fill="none" stroke="black" d="M299,-131C299,-131 216,-131 216,-131 210,-131 204,-125 204,-119 204,-119 204,-107 204,-107 204,-101 210,-95 216,-95 216,-95 299,-95 299,-95 305,-95 311,-101 311,-107 311,-107 311,-119 311,-119 311,-125 305,-131 299,-131"/>
+<text text-anchor="middle" x="257.5" y="-109.3" font-family="sans-serif" font-size="14.00">rdfs:Resource</text>
+</a>
+</g>
+</g>
+<!-- item1&#45;&gt;type1 -->
+<g id="edge2" class="edge">
+<title>item1&#45;&gt;type1</title>
+<g id="a_edge2"><a xlink:title="rdf:type">
+<path fill="none" stroke="black" d="M130.25,-113C149.86,-113 172.02,-113 192.23,-113"/>
+<polygon fill="black" stroke="black" points="192.04,-116.5 202.04,-113 192.04,-109.5 192.04,-116.5"/>
+</a>
+</g>
+<g id="a_edge2&#45;label"><a xlink:title="rdf:type">
+<text text-anchor="middle" x="167" y="-116" font-family="sans-serif" font-size="10.00">rdf:type</text>
+</a>
+</g>
+</g>
+</g>
+</svg>
diff --git a/docs/reference/libtracker-sparql/images/sandbox-diagram.dot b/docs/reference/libtracker-sparql/images/sandbox-diagram.dot
new file mode 100644
index 000000000..328995807
--- /dev/null
+++ b/docs/reference/libtracker-sparql/images/sandbox-diagram.dot
@@ -0,0 +1,46 @@
+graph {
+ rankdir=LR;
+ fontname="sans-serif";
+ compound=true;
+ bgcolor=transparent;
+ node [shape="box", style="rounded", border=0, fontname="sans-serif"];
+
+ subgraph cluster_session {
+ style="rounded";
+ color="lightgrey";
+ label = "User session"
+ tooltip = "User session"
+ fontsize=10;
+
+ Portal;
+ node [shape="cylinder"];"Provider #1"; "Provider #2";
+
+ "Provider #1" -- Portal;
+ "Provider #2" -- Portal;
+ }
+
+ subgraph cluster_client1 {
+ style="dashed";
+ color="lightgrey";
+ label = "Sandbox #1"
+ tooltip = "Sandbox #1"
+ fontsize=10;
+ "App A";
+ node [shape="cylinder"]; "Provider #3";
+ "App A" -- "Provider #3";
+ }
+
+ subgraph cluster_client2 {
+ style="dashed";
+ color="lightgrey";
+ label = "Sandbox #2"
+ tooltip = "Sandbox #2"
+ fontsize=10;
+ "App B";
+ node [shape="cylinder";style="invis"]; "Provider #4";
+ "App B" -- "Provider #4" [style="invis"];
+ }
+
+ Portal -- "App A" [lhead=cluster_client1];
+ Portal -- "App B" [lhead=cluster_client2];
+}
diff --git a/docs/reference/libtracker-sparql/images/sandbox-diagram.svg b/docs/reference/libtracker-sparql/images/sandbox-diagram.svg
new file mode 100644
index 000000000..0eff83016
--- /dev/null
+++ b/docs/reference/libtracker-sparql/images/sandbox-diagram.svg
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
+ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<!-- Generated by graphviz version 7.1.0 (0)
+ -->
+<!-- Pages: 1 -->
+<svg width="443pt" height="174pt"
+ viewBox="0.00 0.00 443.00 174.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 170)">
+<g id="clust1" class="cluster">
+<title>cluster_session</title>
+<g id="a_clust1"><a xlink:title="User session">
+<path fill="none" stroke="lightgrey" d="M20,-20C20,-20 196,-20 196,-20 202,-20 208,-26 208,-32 208,-32 208,-133 208,-133 208,-139 202,-145 196,-145 196,-145 20,-145 20,-145 14,-145 8,-139 8,-133 8,-133 8,-32 8,-32 8,-26 14,-20 20,-20"/>
+<text text-anchor="middle" x="108" y="-133" font-family="sans-serif" font-size="10.00">User session</text>
+</a>
+</g>
+</g>
+<g id="clust2" class="cluster">
+<title>cluster_client1</title>
+<g id="a_clust2"><a xlink:title="Sandbox #1">
+<polygon fill="none" stroke="lightgrey" stroke-dasharray="5,2" points="228,-87 228,-158 427,-158 427,-87 228,-87"/>
+<text text-anchor="middle" x="327.5" y="-146" font-family="sans-serif" font-size="10.00">Sandbox #1</text>
+</a>
+</g>
+</g>
+<g id="clust3" class="cluster">
+<title>cluster_client2</title>
+<g id="a_clust3"><a xlink:title="Sandbox #2">
+<polygon fill="none" stroke="lightgrey" stroke-dasharray="5,2" points="228,-8 228,-79 427,-79 427,-8 228,-8"/>
+<text text-anchor="middle" x="327.5" y="-67" font-family="sans-serif" font-size="10.00">Sandbox #2</text>
+</a>
+</g>
+</g>
+<!-- Portal -->
+<g id="node1" class="node">
+<title>Portal</title>
+<path fill="none" stroke="black" d="M188,-91C188,-91 156,-91 156,-91 150,-91 144,-85 144,-79 144,-79 144,-67 144,-67 144,-61 150,-55 156,-55 156,-55 188,-55 188,-55 194,-55 200,-61 200,-67 200,-67 200,-79 200,-79 200,-85 194,-91 188,-91"/>
+<text text-anchor="middle" x="172" y="-69.3" font-family="sans-serif" font-size="14.00">Portal</text>
+</g>
+<!-- App A -->
+<g id="node4" class="node">
+<title>App A</title>
+<path fill="none" stroke="black" d="M279,-131C279,-131 248,-131 248,-131 242,-131 236,-125 236,-119 236,-119 236,-107 236,-107 236,-101 242,-95 248,-95 248,-95 279,-95 279,-95 285,-95 291,-101 291,-107 291,-107 291,-119 291,-119 291,-125 285,-131 279,-131"/>
+<text text-anchor="middle" x="263.5" y="-109.3" font-family="sans-serif" font-size="14.00">App A</text>
+</g>
+<!-- Portal&#45;&#45;App A -->
+<g id="edge5" class="edge">
+<title>Portal&#45;&#45;App A</title>
+<path fill="none" stroke="black" d="M200.34,-85.22C209.06,-89.12 218.84,-93.49 228,-97.58"/>
+</g>
+<!-- App B -->
+<g id="node6" class="node">
+<title>App B</title>
+<path fill="none" stroke="black" d="M279,-52C279,-52 248,-52 248,-52 242,-52 236,-46 236,-40 236,-40 236,-28 236,-28 236,-22 242,-16 248,-16 248,-16 279,-16 279,-16 285,-16 291,-22 291,-28 291,-28 291,-40 291,-40 291,-46 285,-52 279,-52"/>
+<text text-anchor="middle" x="263.5" y="-30.3" font-family="sans-serif" font-size="14.00">App B</text>
+</g>
+<!-- Portal&#45;&#45;App B -->
+<g id="edge6" class="edge">
+<title>Portal&#45;&#45;App B</title>
+<path fill="none" stroke="black" d="M200.34,-61.09C209.06,-57.28 218.84,-53.03 228,-49.03"/>
+</g>
+<!-- Provider #1 -->
+<g id="node2" class="node">
+<title>Provider #1</title>
+<path fill="none" stroke="black" d="M108,-114.73C108,-116.53 87.38,-118 62,-118 36.62,-118 16,-116.53 16,-114.73 16,-114.73 16,-85.27 16,-85.27 16,-83.47 36.62,-82 62,-82 87.38,-82 108,-83.47 108,-85.27 108,-85.27 108,-114.73 108,-114.73"/>
+<path fill="none" stroke="black" d="M108,-114.73C108,-112.92 87.38,-111.45 62,-111.45 36.62,-111.45 16,-112.92 16,-114.73"/>
+<text text-anchor="middle" x="62" y="-96.3" font-family="sans-serif" font-size="14.00">Provider #1</text>
+</g>
+<!-- Provider #1&#45;&#45;Portal -->
+<g id="edge1" class="edge">
+<title>Provider #1&#45;&#45;Portal</title>
+<path fill="none" stroke="black" d="M108.49,-88.63C120.48,-85.63 133.04,-82.49 143.74,-79.82"/>
+</g>
+<!-- Provider #2 -->
+<g id="node3" class="node">
+<title>Provider #2</title>
+<path fill="none" stroke="black" d="M108,-60.73C108,-62.53 87.38,-64 62,-64 36.62,-64 16,-62.53 16,-60.73 16,-60.73 16,-31.27 16,-31.27 16,-29.47 36.62,-28 62,-28 87.38,-28 108,-29.47 108,-31.27 108,-31.27 108,-60.73 108,-60.73"/>
+<path fill="none" stroke="black" d="M108,-60.73C108,-58.92 87.38,-57.45 62,-57.45 36.62,-57.45 16,-58.92 16,-60.73"/>
+<text text-anchor="middle" x="62" y="-42.3" font-family="sans-serif" font-size="14.00">Provider #2</text>
+</g>
+<!-- Provider #2&#45;&#45;Portal -->
+<g id="edge2" class="edge">
+<title>Provider #2&#45;&#45;Portal</title>
+<path fill="none" stroke="black" d="M108.49,-57.37C120.48,-60.37 133.04,-63.51 143.74,-66.18"/>
+</g>
+<!-- Provider #3 -->
+<g id="node5" class="node">
+<title>Provider #3</title>
+<path fill="none" stroke="black" d="M419,-127.73C419,-129.53 398.38,-131 373,-131 347.62,-131 327,-129.53 327,-127.73 327,-127.73 327,-98.27 327,-98.27 327,-96.47 347.62,-95 373,-95 398.38,-95 419,-96.47 419,-98.27 419,-98.27 419,-127.73 419,-127.73"/>
+<path fill="none" stroke="black" d="M419,-127.73C419,-125.92 398.38,-124.45 373,-124.45 347.62,-124.45 327,-125.92 327,-127.73"/>
+<text text-anchor="middle" x="373" y="-109.3" font-family="sans-serif" font-size="14.00">Provider #3</text>
+</g>
+<!-- App A&#45;&#45;Provider #3 -->
+<g id="edge3" class="edge">
+<title>App A&#45;&#45;Provider #3</title>
+<path fill="none" stroke="black" d="M291.35,-113C302.05,-113 314.66,-113 326.69,-113"/>
+</g>
+<!-- Provider #4 -->
+<!-- App B&#45;&#45;Provider #4 -->
+</g>
+</svg>
diff --git a/docs/reference/libtracker-sparql/meson.build b/docs/reference/libtracker-sparql/meson.build
index e49b31d8a..507555b2c 100644
--- a/docs/reference/libtracker-sparql/meson.build
+++ b/docs/reference/libtracker-sparql/meson.build
@@ -87,8 +87,10 @@ foreach doc : generated_ontology_files
endforeach
generated_content_files = [
+ 'overview.md.in',
'examples.md.in',
'tutorial.md.in',
+ 'sandboxing.md.in',
]
generated_content = []
@@ -107,7 +109,6 @@ foreach doc : generated_content_files
])
endforeach
-overview = ['overview.md']
content = [
'ontologies.md',
'sparql-functions.md',
@@ -120,7 +121,7 @@ content = [
# The TOML gi-docgen configuration wants a list of quoted file names.
content_quoted = []
-foreach c : overview + generated_content + content + generated_ontology_content
+foreach c : generated_content + content + generated_ontology_content
content_quoted += '"@0@"'.format(c)
endforeach
@@ -148,7 +149,7 @@ reference = custom_target(
'@INPUT1@',
],
depends: [tracker_sparql_gir[0], generated_targets],
- depend_files: [overview, content])
+ depend_files: [content])
docs_name = 'Tracker-3.0'
meson.add_install_script('install-devhelp.sh', docs_name, reference)
diff --git a/docs/reference/libtracker-sparql/overview.md b/docs/reference/libtracker-sparql/overview.md
deleted file mode 100644
index 949d81c3f..000000000
--- a/docs/reference/libtracker-sparql/overview.md
+++ /dev/null
@@ -1,59 +0,0 @@
-Title: Overview
-
-Tracker SPARQL allows creating and connecting to one or more
-triplestore databases. It is used by the
-[Tracker Miners filesystem indexer](https://gitlab.gnome.org/GNOME/tracker-miners/),
-and can also store and publish any kind of app data.
-
-Querying data is done using the SPARQL graph query language. See the
-[examples](examples.html) to find out how this works.
-Storing data can also be done using SPARQL, or using the [class@Tracker.Resource]
-API.
-
-You can share a database over D-Bus using the [class@Tracker.Endpoint] API,
-allowing other libtracker-sparql users to query from it, either
-by referencing it in a `SELECT { SERVICE ... }` query, or by connecting
-directly with [ctor@Tracker.SparqlConnection.bus_new].
-
-Tracker SPARQL partitions the database into multiple graphs.
-You can implementing access control restrictions based on
-graphs, and we provide a Flatpak portal that does so.
-The number of graphs is [limited](limits.html).
-
-## Connection methods
-
-You can create and access a private store using
-[ctor@Tracker.SparqlConnection.new]. This is useful to store
-app-specific data.
-
-To connect to another database on the same local machine, such as the
-one exposed by Tracker Miner FS, use [ctor@Tracker.SparqlConnection.bus_new].
-
-To connect to another a database on a remote machine, use
-[ctor@Tracker.SparqlConnection.remote_new]. This can be used to query online
-databases that provide a SPARQL endpoint, such as [DBpedia](https://wiki.dbpedia.org/about).
- .
-## Connecting from Flatpak
-
-Tracker SPARQL provides a portal for the [Flatpak](https://flatpak.org/)
-application sandboxing system. This lets you control which parts of a
-database each app can query.
-
-The app's Flatpak manifest needs to specify which graph(s) the app will
-access. See the [example app](https://gitlab.gnome.org/GNOME/tracker/-/blob/master/examples/flatpak/org.example.TrackerSandbox.json)
-and the [portal documentation](https://gnome.pages.gitlab.gnome.org/tracker/docs/commandline/#tracker-xdg-portal-3) to see how.
-
-No code changes are needed in the app, as [ctor@Tracker.SparqlConnection.bus_new]
-will automatically try connect via the portal if it can't talk to the
-given D-Bus name directly.
-
-Tracker SPARQL is included in the
-[GNOME Flatpak SDK and runtime](https://docs.flatpak.org/en/latest/available-runtimes.html#gnome).
-If the app uses a different runtime, you may need to build Tracker
-SPARQL in the app manifest.
-
-The app might use the Tracker Miner FS search index. Ideally this is done via the portal,
-using the search index maintained on the host. Since not all OSes ship tracker-miner-fs-3,
-we recommend that apps bundle it inside the Flatpak and connect to the bundled version as
-a fallback. See [GNOME Music](https://gitlab.gnome.org/GNOME/gnome-music/)
-for an example of how to do this.
diff --git a/docs/reference/libtracker-sparql/overview.md.in b/docs/reference/libtracker-sparql/overview.md.in
new file mode 100644
index 000000000..5c4599623
--- /dev/null
+++ b/docs/reference/libtracker-sparql/overview.md.in
@@ -0,0 +1,83 @@
+Title: Overview
+
+{{ style.xml }}
+
+Tracker is a light-weight RDF [triple store](https://en.wikipedia.org/wiki/Triplestore)
+implementation, with a [SPARQL 1.1](https://en.wikipedia.org/wiki/SPARQL) interface.
+Tracker is implemented as a library, and may be used to create private databases,
+in addition to connecting to remote endpoints for
+[federated queries](https://en.wikipedia.org/wiki/Federated_search) or creating such
+public endpoints.
+
+## Advantages
+
+Tracker offers the following advantages over other traditional databases:
+
+- It is based on open standards. [SPARQL](https://www.w3.org/TR/2013/REC-sparql11-overview-20130321/)
+ is a [W3C recommendation](https://www.w3.org/). So is the [RDF](https://www.w3.org/RDF/) data model
+ and the various file formats available for import/export ([Turtle](https://www.w3.org/TR/turtle/),
+ [Trig](https://www.w3.org/TR/trig/), [JSON-LD](https://www.w3.org/TR/json-ld11/)).
+- Database format and schema updates are automatically managed. The user
+ just needs to write and update the [ontology](ontologies.html) defining
+ the structure of the contained data. Databases will be created and
+ implicitly updated to format changes without the need to write supporting code.
+- It has versatile serialization capabilities. Tracker is able to export RDF data into the same
+ formats it can import and load into databases. It is possible to perform backups, data mirroring,
+ data synchronization…
+- A complete set of CLI tools is included. Tracker databases are fully introspectable
+ and can be opened with no additional supporting files, the command line tools can do
+ anything the library could do, and a number of utilities is provided.
+- Distributed data is a first class citizen. SPARQL has builtin capabilities to
+ operate in a distributed environment, which may make it desirable to manage data
+ that is naturally open to multiple users. Tracker may interoperate with other
+ SPARQL implementations.
+
+The Tracker library is written in C, but may be used from a number of languages
+through [GObject introspection](https://gi.readthedocs.io/en/latest/), including
+Rust, Python, or Javascript (through [GJS](https://gjs.guide/)).
+
+Tracker is designed to be small, fast, and scalable. It is also robust and
+fully [ACID](https://en.wikipedia.org/wiki/ACID). There are ready-made
+[examples](examples.html) on how the Tracker library is put to use.
+
+## Dependencies
+
+Tracker depends on the following libraries:
+
+- **GLib**: General-purpose utility library. GLib provides many useful data types,
+ macros, type conversions, string utilities, file utilities, a main loop abstraction,
+ and so on. More information available on the
+ [GLib API documentation](https://developer.gnome.org/glib/stable/).
+- **GObject**: A library that provides a type system, a collection of fundamental
+ types including an object type, and a signal system. More information available
+ on the [GObject API documentation](https://developer.gnome.org/gobject/stable/).
+- **GIO**: A modern, easy-to-use VFS API including abstractions for files, drives,
+ volumes, stream I/O, as well as network programming and IPC though D-Bus. More
+ information available on the [GIO API documentation](https://developer.gnome.org/gio/stable/).
+- **SQLite**: SQLite is a C-language library that implements a small, fast,
+ self-contained, high-reliability, full-featured, SQL database engine. SQLite
+ is the most used database engine in the world. More information available on the
+ [SQLite website](https://sqlite.org).
+- **Soup**: libsoup is an HTTP and HTTP/2 client/server library for GNOME. It uses
+ GObjects and the GLib main loop to integrate well with GNOME applications. More
+ information available on the [Soup API documentation](https://libsoup.org/libsoup-3.0/index.html)
+- **LibXML2**: Libxml2 is the XML C parser and toolkit developed for the GNOME project.
+ More information at the [libXML2 website](https://gitlab.gnome.org/GNOME/libxml2/-/wikis/home).
+- **JSON-GLib**: JSON-GLib is a library providing serialization and deserialization
+ support for the JavaScript Object Notation (JSON) format. More information at
+ the [API documentation](https://gnome.pages.gitlab.gnome.org/json-glib/).
+
+## Connection methods
+
+It is possible to create private databases in local storage, or to connect to
+remote HTTP or D-Bus SPARQL endpoints. See [class@Tracker.SparqlConnection]
+and its different constructors for each of these methods.
+
+<div class="docblock">
+{{ images/connections-diagram.svg }}
+</div>
+
+It is also possible to create public SPARQL endpoints, see [class@Tracker.Endpoint]
+and its subclasses. Tracker can interoperate with any other SPARQL endpoint over HTTP,
+such as [Wikidata](https://www.wikidata.org/wiki/Wikidata:Main_Page) or
+[DBpedia](https://wiki.dbpedia.org/about).
diff --git a/docs/reference/libtracker-sparql/sandboxing.md.in b/docs/reference/libtracker-sparql/sandboxing.md.in
new file mode 100644
index 000000000..12f6ade67
--- /dev/null
+++ b/docs/reference/libtracker-sparql/sandboxing.md.in
@@ -0,0 +1,122 @@
+Title: Sandboxing and portals
+slug: sandboxing-and-portals
+
+{{ style.xml }}
+
+There are times when it does make sense to lend advanced querying
+capabilities around your data to other processes of the same machine,
+or even widely available to any application that might want to make
+use of it. One real life example of this is [Tracker Miners](https://gitlab.gnome.org/GNOME/tracker-miners)
+used as the [GNOME Desktop](https://gnome.org) indexer.
+
+But in this day and age, it is naive to make this data available
+without constraints on what data can be accessed. Tracker provides a
+portal for the [Flatpak](https://flatpak.org/) application sandboxing
+system. This provides the mechanisms to filter the available data for
+sandboxed users.
+
+# How it works
+
+The portal acts as a single entry point for sandboxed applications
+to have read access to any D-Bus SPARQL endpoint.
+
+<div class="docblock">
+{{ images/sandbox-diagram.svg }}
+</div>
+
+The partitioning of the data is decided by the data provider at
+the time of inserting this data in the RDF triple store, and relies
+on graphs as the natural partitioning scheme of RDF data. As an
+example, consider the following updates:
+
+```SPARQL
+INSERT DATA {
+ GRAPH example:A {
+ example:item1 a rdfs:Resource ;
+ }
+
+ GRAPH example:B {
+ example:item2 a rdfs:Resource ;
+ }
+}
+```
+
+Resulting in the following simple diagram:
+
+<div class="docblock">
+{{ images/graph-example-diagram.svg }}
+</div>
+
+At that point, SPARQL queries may target either, both or any graph, e.g.:
+
+```SPARQL
+# This will return example:item1
+SELECT ?element
+FROM example:A
+{
+ ?element a rdfs:Resource
+}
+```
+
+Or perhaps even poke at non-existing graphs:
+
+```SPARQL
+# This will return no elements
+SELECT ?element
+FROM example:C
+{
+ ?element a rdfs:Resource
+}
+```
+
+Graphs may overlap with other graphs, or extend each other.
+
+The data filtering performed by the portal strongly relies on these RDF
+semantics for graphs, except that graph access is enforced through the
+[`CONSTRAINT` syntax](sparql-and-tracker.html#constraint-syntax). These
+policies prevail over any other SPARQL syntax to specify graphs, and
+will result in filtered graphs being replaced by an empty graph.
+
+Likewise, notification of changes through [class@Tracker.Notifier] will
+be filtered on the way to sandboxed applications, so that there are only
+notifications on changes from the allowed graphs.
+
+# Using it from data providers
+
+Data providers are free to decide the data partitioning scheme available
+to sandboxed applications, by creating graphs and inserting data to
+those. Access to those graphs will be policied by the portal on their
+behalf.
+
+Keep in mind that there are limits on the [number of graphs](limits.html#limits-on-the-number-of-graphs)
+that apply on graph creation.
+
+# Using it from applications
+
+The portal is transparently integrated in the Tracker library. Applications
+may write SPARQL queries so that they work the same while sandboxed or not.
+No code changes are needed in the app, as [ctor@Tracker.SparqlConnection.bus_new]
+will automatically try connect via the portal if it can not talk to the
+given D-Bus name directly.
+
+The policy on the accessed graphs is usually defined in the flatpak manifest
+at the time of bundling the software, e.g.:
+
+```json
+{
+ "finish-args" : [
+ "--add-policy=Tracker3.dbus:org.example.Endpoint=example:A",
+ "--add-policy=Tracker3.dbus:org.example.Endpoint=example:B"
+ ]
+}
+```
+
+The portal will pick the policy from the `/.flatpak-info` file created
+by Flatpak, and (with the example arguments) allow access to graphs `example:A`
+and `example:B` from the `org.example.Endpoint` D-Bus SPARQL endpoint.
+Access to other graphs, or other services will be disallowed.
+
+The Tracker library is included in the
+[GNOME Flatpak SDK and runtime](https://docs.flatpak.org/en/latest/available-runtimes.html#gnome).
+If the app uses a different runtime, you may need to build Tracker
+SPARQL in the app manifest.
diff --git a/docs/reference/libtracker-sparql/style.xml b/docs/reference/libtracker-sparql/style.xml
new file mode 100644
index 000000000..aa0294e3d
--- /dev/null
+++ b/docs/reference/libtracker-sparql/style.xml
@@ -0,0 +1,8 @@
+<style>
+ svg .cluster text { fill: var(--text-color-muted); }
+ svg .node ellipse { stroke: var(--text-color-muted) }
+ svg .node text { text-decoration: none !important; fill: var(--text-color); }
+ svg .edge text { text-decoration: none !important; fill: var(--text-color); }
+ svg .edge path { stroke: var(--text-color-muted); }
+ svg .edge polygon { fill: var(--text-color-muted); stroke: transparent; }
+</style>
diff --git a/docs/reference/libtracker-sparql/tutorial.md.in b/docs/reference/libtracker-sparql/tutorial.md.in
index 6a19663bf..aae3bec09 100644
--- a/docs/reference/libtracker-sparql/tutorial.md.in
+++ b/docs/reference/libtracker-sparql/tutorial.md.in
@@ -2,6 +2,8 @@ Title: SPARQL Tutorial
Slug: sparql-tutorial
...
+{{ style.xml }}
+
This document aims to introduce you to RDF and SPARQL from the ground
up, up to a point where SPARQL queries will become familiar and approachable
to reason about.
diff --git a/docs/tools/tracker-docgen-md.c b/docs/tools/tracker-docgen-md.c
index 0aa099135..98dc92c0c 100644
--- a/docs/tools/tracker-docgen-md.c
+++ b/docs/tools/tracker-docgen-md.c
@@ -135,8 +135,12 @@ print_rdf_diagram (FILE *f,
g_fprintf (f, "<div class=\"docblock\">\n");
g_fprintf (f,
"<style>"
+ "svg .node text { text-decoration: none !important; fill: var(--text-color); } "
+ "svg .edge a { text-decoration: none !important; fill: var(--text-color); } "
"svg .edge:hover a { text-decoration: none !important; fill: var(--primary); } "
+ "svg .edge path { stroke: var(--text-color-muted); } "
"svg .edge:hover path { stroke: var(--primary); } "
+ "svg .edge polygon { fill: var(--text-color-muted); stroke: transparent; }"
"svg .edge:hover polygon { fill: var(--primary); stroke: var(--primary); }"
"</style>\n");
g_fprintf (f, "{{ %s-diagram.svg }}\n", id);