<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE chapter 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/2001/XInclude'">
]>

<part id="sparql-functions">
  <title>Builtin SPARQL functions</title>
  <partintro>
    Besides the functions built in the SPARQL 1.1 syntax, type casts
    and functional properties, Tracker supports a number of SPARQL
    functions. Some of these functions have correspondences in XPath.
  </partintro>

  <chapter id="string-functions">
    <title>String functions</title>

    <sect2 id="fn:lower-case">
      <title>fn:lower-case</title>
      <programlisting>
	fn:lower-case (?string)
      </programlisting>
      <para>
	Converts a string to lowercase, equivalent to <systemitem>LCASE</systemitem>.
      </para>
    </sect2>

    <sect2 id="fn:upper-case">
      <title>fn:upper-case</title>
      <programlisting>
	fn:upper-case (?string)
      </programlisting>
      <para>
	Converts a string to uppercase, equivalent to
	<systemitem>UCASE</systemitem>.
      </para>
    </sect2>

    <sect2 id="fn:contains">
      <title>fn:contains</title>
      <programlisting>
	fn:contains (?haystack, ?needle)
      </programlisting>
      <para>
	Returns a boolean indicating whether <systemitem>?needle</systemitem> is
	found in <systemitem>?haystack</systemitem>. Equivalent to
	<systemitem>CONTAINS</systemitem>.
      </para>
    </sect2>

    <sect2 id="fn:starts-with">
      <title>fn:starts-with</title>
      <programlisting>
	fn:starts-with (?string, ?prefix)
      </programlisting>
      <para>
	Returns a boolean indicating whether <systemitem>?string</systemitem>
	starts with <systemitem>?prefix</systemitem>. Equivalent to
	<systemitem>STRSTARTS</systemitem>.
      </para>
    </sect2>

    <sect2 id="fn:ends-with">
      <title>fn:ends-with</title>
      <programlisting>
	fn:ends-with (?string, ?suffix)
      </programlisting>
      <para>
	Returns a boolean indicating whether <systemitem>?string</systemitem>
	ends with <systemitem>?suffix</systemitem>. Equivalent to
	<systemitem>STRENDS</systemitem>.
      </para>
    </sect2>

    <sect2 id="fn:substring">
      <title>fn:substring</title>
      <programlisting>
	fn:substring (?string, ?startLoc)
	fn:substring (?string, ?startLoc, ?endLoc)
      </programlisting>
      <para>
	Returns a substring delimited by the integer
	<systemitem>?startLoc</systemitem> and <systemitem>?endLoc</systemitem>
	arguments. If <systemitem>?endLoc</systemitem> is omitted, the end of
	the string is used.
      </para>
    </sect2>

    <sect2 id="fn:concat">
      <title>fn:concat</title>
      <programlisting>
	fn:concat (?string1, ?string2, ..., ?stringN)
      </programlisting>
      <para>
	Takes a variable number of arguments and returns a string concatenation
	of all its returned values. Equivalent to <systemitem>CONCAT</systemitem>.
      </para>
    </sect2>

    <sect2 id="fn:string-join">
      <title>fn:string-join</title>
      <programlisting>
	fn:string-join ((?string1, ?string2, ...), ?separator)
      </programlisting>
      <para>
	Takes a variable number of arguments and returns a string concatenation
	using <systemitem>?separator</systemitem> to join all elements.
      </para>
    </sect2>

    <sect2 id="fn:replace">
      <title>fn:replace</title>
      <programlisting>
	fn:replace (?string, ?regex, ?replacement)
	fn:replace (?string, ?regex, ?replacement, ?flags)
      </programlisting>
      <para>
	Performs string replacement on <systemitem>?string</systemitem>. All
	matches of <systemitem>?regex</systemitem> are replaced by
	<systemitem>?replacement</systemitem> in the returned string. This
	function is similar to <systemitem>REPLACE</systemitem>
      </para>
      <para>
	The <systemitem>?flags</systemitem> argument is optional, a case search
	is performed if not provided.
      </para>
      <para>
	If <systemitem>?flags</systemitem> contains the character
	<systemitem>“s”</systemitem>, a dot metacharacter (".") in
	<systemitem>?regex</systemitem> matches all characters, including
	newlines. Without it, newlines are excluded.
      </para>
      <para>
	If <systemitem>?flags</systemitem> contains the character
	<systemitem>“m”</systemitem>, the “start of line”
	(<systemitem>^</systemitem>) and “end of line”
	(<systemitem>$</systemitem>) constructs match immediately following or
	immediately before any newline in the string. If not set these constructs
	will respectively match the start and end of the full string.
      </para>
      <para>
	If <systemitem>?flags</systemitem> contains the character
	<systemitem>“i”</systemitem>, search is caseless.
      </para>
      <para>
	If <systemitem>?flags</systemitem> contains the character
	<systemitem>“x”</systemitem>, <systemitem>?regex</systemitem> is
	interpreted to be an extended regular expression.
      </para>
    </sect2>

    <sect2 id="tracker:case-fold">
      <title>tracker:case-fold</title>
      <programlisting>
	tracker:case-fold (?string)
      </programlisting>
      <para>
	Converts a string into a form that is independent of case.
      </para>
    </sect2>

    <sect2 id="tracker:title-order">
      <title>tracker:title-order</title>
      <programlisting>
	tracker:title-order (?string)
      </programlisting>
      <para>
	Manipulates a string to remove leading articles for sorting
	purposes, e.g. “Wall, The”. Best used in
	<systemitem>ORDER BY</systemitem> clauses.
      </para>
    </sect2>

    <sect2 id="tracker:ascii-lower-case">
      <title>tracker:ascii-lower-case</title>
      <programlisting>
	tracker:ascii-lower-case (?string)
      </programlisting>
      <para>
	Converts an ASCII string to lowercase, equivalent to
	<systemitem>LCASE</systemitem>.
      </para>
    </sect2>

    <sect2 id="tracker:normalize">
      <title>tracker:normalize</title>
      <programlisting>
	tracker:normalize (?string, ?option)
      </programlisting>
      <para>
	Normalizes <systemitem>?string</systemitem>. The
	<systemitem>?option</systemitem> string must be one of
	<systemitem>nfc</systemitem>, <systemitem>nfd</systemitem>,
	<systemitem>nfkc</systemitem> or <systemitem>nfkd</systemitem>.
      </para>
    </sect2>

    <sect2 id="tracker:unaccent">
      <title>tracker:unaccent</title>
      <programlisting>
	tracker:unaccent (?string)
      </programlisting>
      <para>
	Removes accents from a string.
      </para>
    </sect2>

    <sect2 id="tracker:coalesce">
      <title>tracker:coalesce</title>
      <programlisting>
	tracker:coalesce (?value1, ?value2, ..., ?valueN)
      </programlisting>
      <para>
	Picks the first non-null value. Equivalent to
	<systemitem>COALESCE</systemitem>.
      </para>

    </sect2>
      <sect2 id="tracker:strip-punctuation">
      <title>tracker:strip-punctuation</title>
      <programlisting>
	tracker:strip-punctuation (?string)
      </programlisting>
      <para>
	Removes any Unicode character which has the  General Category value of P (Punctuation) from the string.
      </para>
    </sect2>
  </chapter>

  <chapter id="date-time-functions">
    <title>DateTime functions</title>

    <sect2 id="fn:year-from-dateTime">
      <title>fn:year-from-dateTime</title>
      <programlisting>
	fn:year-from-dateTime (?date)
      </programlisting>
      <para>
	Returns the year from a <systemitem>xsd:date</systemitem> type,
	a <systemitem>xsd:dateTime</systemitem> type, or a ISO8601 date
	string. This function is equivalent to <systemitem>YEAR</systemitem>.
      </para>
    </sect2>

    <sect2 id="fn:month-from-dateTime">
      <title>fn:month-from-dateTime</title>
      <programlisting>
	fn:month-from-dateTime (?date)
      </programlisting>
      <para>
	Returns the month from a <systemitem>xsd:date</systemitem> type,
	a <systemitem>xsd:dateTime</systemitem> type, or a ISO8601 date
	string. This function is equivalent to <systemitem>MONTH</systemitem>.
      </para>
    </sect2>

    <sect2 id="fn:day-from-dateTime">
      <title>fn:day-from-dateTime</title>
      <programlisting>
	fn:day-from-dateTime (?date)
      </programlisting>
      <para>
	Returns the day from a <systemitem>xsd:date</systemitem> type,
	a <systemitem>xsd:dateTime</systemitem> type, or a ISO8601 date
	string. This function is equivalent to <systemitem>DAY</systemitem>.
      </para>
    </sect2>

    <sect2 id="fn:hours-from-dateTime">
      <title>fn:hours-from-dateTime</title>
      <programlisting>
	fn:hours-from-dateTime (?date)
      </programlisting>
      <para>
	Returns the hours from a <systemitem>xsd:dateTime</systemitem> type
	or a ISO8601 datetime string. This function is equivalent to
	<systemitem>HOURS</systemitem>.
      </para>
    </sect2>

    <sect2 id="fn:minutes-from-dateTime">
      <title>fn:minutes-from-dateTime</title>
      <programlisting>
	fn:minutes-from-dateTime (?date)
      </programlisting>
      <para>
	Returns the minutes from a <systemitem>xsd:dateTime</systemitem> type
	or a ISO8601 datetime string. This function is equivalent to
	<systemitem>MINUTES</systemitem>.
      </para>
    </sect2>

    <sect2 id="fn:seconds-from-dateTime">
      <title>fn:seconds-from-dateTime</title>
      <programlisting>
	fn:seconds-from-dateTime (?date)
      </programlisting>
      <para>
	Returns the seconds from a <systemitem>xsd:dateTime</systemitem> type
	or a ISO8601 datetime string. This function is equivalent to
	<systemitem>SECONDS</systemitem>.
      </para>
    </sect2>

    <sect2 id="fn:timezone-from-dateTime">
      <title>fn:timezone-from-dateTime</title>
      <programlisting>
	fn:timezone-from-dateTime (?date)
      </programlisting>
      <para>
	Returns the timezone offset in minutes. This function is similar, but
	not equivalent to <systemitem>TIMEZONE</systemitem> or
	<systemitem>TZ</systemitem>.
      </para>
    </sect2>
  </chapter>

  <chapter id="fts-functions">
    <title>Full-text search functions</title>

    <sect2 id="fts:rank">
      <title>fts:rank</title>
      <programlisting>
	fts:rank (?match)
      </programlisting>
      <para>
	Returns the rank of a full-text search match. Must be
	used in conjunction with <systemitem>fts:match</systemitem>.
      </para>
    </sect2>

    <sect2 id="fts:offsets">
      <title>fts:offsets</title>
      <programlisting>
	fts:offsets (?match)
      </programlisting>
      <para>
	Returns a string describing the offsets of a full-text search
	match. Must be used in conjunction with
	<systemitem>fts:match</systemitem>. The format string has the
	format:
      </para>
      <programlisting>
	prefix:property:offset prefix:property:offset prefix:property:offset
      </programlisting>
    </sect2>

    <sect2 id="fts:snippet">
      <title>fts:snippet</title>
      <programlisting>
	fts:snippet (?match)
	fts:snippet (?match, ?delimStart, ?delimEnd)
	fts:snippet (?match, ?delimStart, ?delimEnd, ?ellipsis)
	fts:snippet (?match, ?delimStart, ?delimEnd, ?ellipsis, ?numTokens)
      </programlisting>
      <para>
	Returns a snippet string in accordance to the full-text search string.
	Must be used in conjunction with <systemitem>fts:match</systemitem>.
      </para>
      <para>
	The <systemitem>?delimStart</systemitem> and
	<systemitem>?delimEnd</systemitem> parameters allow specifying the
	delimiters of the match strings inside the snippet.
      </para>
      <para>
	The <systemitem>?ellipsis</systemitem> parameter allows specifying
	the string used to separate distant matches in the snippet string.
      </para>
      <para>
	The <systemitem>?numTokens</systemitem> parameter specifies the number
	of tokens the returned string should containt at most.
      </para>
    </sect2>
  </chapter>

  <chapter id="uri-functions">
    <title>URI functions</title>

    <sect2 id="tracker:uri-is-parent">
      <title>tracker:uri-is-parent</title>
      <programlisting>
	tracker:uri-is-parent (?parent, ?uri)
      </programlisting>
      <para>
	Returns a boolean value expressing whether
	<systemitem>?parent</systemitem> is a parent of
	<systemitem>?uri</systemitem>.
      </para>
    </sect2>

    <sect2 id="tracker:uri-is-descendant">
      <title>tracker:uri-is-descendant</title>
      <programlisting>
	tracker:uri-is-descendant (?uri1, ?uri2, ..., ?uriN, ?child)
      </programlisting>
      <para>
	Returns a boolean value expressing whether one of the
	given URIs are a parent (direct or indirect) of
	<systemitem>?child</systemitem>.
      </para>
    </sect2>

    <sect2 id="tracker:string-from-filename">
      <title>tracker:string-from-filename</title>
      <programlisting>
	tracker:string-from-filename (?filename)
      </programlisting>
      <para>
	Returns a UTF-8 string from a filename.
      </para>
    </sect2>
  </chapter>

  <chapter id="geo-functions">
    <title>Geolocation functions</title>

    <sect2 id="tracker:cartesian-distance">
      <title>tracker:cartesian-distance</title>
      <programlisting>
	tracker:cartesian-distance (?lat1, ?lat2, ?lon1, ?lon2)
      </programlisting>
      <para>
	Calculates the cartesian distance between 2 points expressed
	by <systemitem>?lat1/?lon1</systemitem> and
	<systemitem>?lat2/?lon2</systemitem>.
      </para>
    </sect2>

    <sect2 id="tracker:haversine-distance">
      <title>tracker:haversine-distance</title>
      <programlisting>
	tracker:haversine-distance (?lat1, ?lat2, ?lon1, ?lon2)
      </programlisting>
      <para>
	Calculates the haversine distance between 2 points expressed
	by <systemitem>?lat1/?lon1</systemitem> and
	<systemitem>?lat2/?lon2</systemitem>.
      </para>
    </sect2>
  </chapter>

  <chapter id="id-functions">
    <title>Identification functions</title>

    <sect2 id="tracker:id">
      <title>tracker:id</title>
      <programlisting>
	tracker:id (?urn)
      </programlisting>
      <para>
	Returns the internal ID corresponding to a URN.
	Its inverse operation is <systemitem>tracker:uri</systemitem>.
      </para>
    </sect2>

    <sect2 id="tracker:uri">
      <title>tracker:uri</title>
      <programlisting>
	tracker:uri (?id)
      </programlisting>
      <para>
	Returns the URN that corresponds to an ID.
	Its inverse operation is <systemitem>tracker:id</systemitem>
      </para>
    </sect2>
  </chapter>
</part>
