NAME

TripleStore - An SQL-Free Triple Store API with a Perl Query Language.

SYNOPSIS

use TripleStore;
use TripleStore::Driver::MySQL;

my $::DB = new TripleStore (
    new TripleStore::Driver::MySQL (
        "DBI:mysql:database=test",
        "root",
        "someSecretPassword",
    )
);

$::DB->tx_start();
eval { do_some_stuff() };
$@ ? $::DB->tx_abort() ? $::DB->tx_stop();

$::DB = undef;

SUMMARY

TripleStore is a Perl interface for a triple store. Currently a quite naive MySQL implementation is provided. Alternative SQL implementations can be developed by subclassing TripleStore::Driver or any of its subclasses (such as TripleStore::Driver::SQL).

Note that TripleStore API strives to NOT be connected in any way with SQL (especially for querying). There might be a few common points, but as you will see TripleStore is quite neutral at that level.

BASIC OPERATIONS / HOW IT WORKS

Constructing a triple store object.

To construct a triple store object, you need to instanciate a driver first. Currently there's only one driver available, so that's not so hard :=)

sub gimme_driver
{
    new TripleStore::Driver::MySQL (
        "DBI:mysql:database=test",
        "root",
        "someSecretPassword",
    );
}

Then you need to instanciate a TripleStore object and put it somewhere where you can access it everywhere in your program.

sub main
{
    local $::DB = new TripleStore (gimme_driver());
    $::DB->tx_start(); # starts a transaction
    eval {
        # here we're gonna do
        # plenty of stuff
        # that involves the triple store.
    }
    $@ ? $::DB->tx_abort() : $::DB->tx_stop();
}

Inserting new triples

$::DB->insert ($subject, $predicate, $object);

Deleting existing triples

In order to delete triples you need to define some condition. You do that using a clause object.

# clause that matches all triples with:
#    predicate eq 'price'
#    object    >  100.25
my $clause = $::DB->clause (undef, 'price', [ '>', 125.25 ]);
$::DB->delete ($clause);

The current MySQL driver does not support complex conditions for deletion yet (i.e. $clause1 & ( $clause2 | $clause3 )).

Updating exising triples

Same as delete, except that you define a hashref of elements to set, i.e.

# this is a silly update:
# for everything that has a price greater than
# 125.25, set the price to 90.
my $clause = $::DB->clause (undef, 'price', [ '>', 125.25 ]);
$::DB->update ( { object => 90 }, $clause);

You can update on 'subject', 'predicate' or 'object'.

QUERYING THE TRIPLE STORE

StoreTriple features a quite nice query interface which is inspired from the rdfdb-style queries.

In rdbf, queries are expected to be parsed from a form such as:

select ( ?x ?y ) from triple where (?x worksFor ?y) (?y name 'BBC')

With TripleStore, this translates as:

my $x = $::DB->var();
my $y = $::DB->var();
my $rs = $::DB->select ($x, $y,
    $::DB->clause ($x, 'worksFor', $y) &
    $::DB->clause ($y, 'name', 'BBC')
);

Except that TripleStore lets you do a bit more...

Making complex queries

my $complex = $clause1 & ( $clause2 | $clause3 | ( $clause4 & $clause5 ) );

Sorting variables

# same query, sorted by alphabetical order on $x
# and then by descending numerical order on $y
my $rs = $::DB->select ($x, $y,
    $::DB->clause ($x, 'worksFor', $y) &
    $::DB->clause ($y, 'name', 'BBC')
    $::DB->sort_str_asc ($x), $::DB->sort_num_desc ($y)
);

The available sorting functions are:

$::DB->sort_str_asc  ($variable);
$::DB->sort_str_desc ($variable);
$::DB->sort_num_asc  ($variable);
$::DB->sort_num_desc ($variable);

Limiting

# same query, but limited to the 10 first rows
my $rs = $::DB->select ($x, $y,
    $::DB->clause ($x, 'worksFor', $y) &
    $::DB->clause ($y, 'name', 'BBC')
    $::DB->limit (0, 10) # offset, rows
);

# same as above, but with a different approach
my $rs = $::DB->select ($x, $y,
    $::DB->clause ($x, 'worksFor', $y) &
    $::DB->clause ($y, 'name', 'BBC')
    $::DB->limit_page (1, 10) # first page, 10 rows per page
);

Selecting on...

Strings:

$::DB->clause ($y, 'name', 'BBC') # equality
$::DB->clause ($y, 'name', [ 'ne', 'BBC' ]) # non equality
$::DB->clause ($y, 'name', [ 'lt', 'BBC' ]) # lesser than
$::DB->clause ($y, 'name', [ 'le', 'BBC' ]) # lesser or equals
$::DB->clause ($y, 'name', [ 'gt', 'BBC' ]) # greater than
$::DB->clause ($y, 'name', [ 'ge', 'BBC' ]) # greater or equals
$::DB->clause ($y, 'name', [ 'like', '%BBC%' ]) # like
$::DB->clause ($y, 'name', [ 'unlike', '%BBC%' ]) # unlike

Numeric:

$::DB->clause ($y, 'someNumericValue', [ '==', 12 ] ) # equality
$::DB->clause ($y, 'name', [ '!=', 12 ] ) # non equality
$::DB->clause ($y, 'name', [ '<', 12 ] )  # lesser than
$::DB->clause ($y, 'name', [ '<=', 12 ] ) # lesser or equals
$::DB->clause ($y, 'name', [ '>', 12 ] )  # greater than
$::DB->clause ($y, 'name', [ '>=', 12 ] ) # greater or equals

Looping through the results.

When you invoke the select() method, a ResultSet object is returned. You can use that ResultSet object to loop through the results.

my $rs = $::DB->select ($x, $y,
    $::DB->clause ($x, 'worksFor', $y) &
    $::DB->clause ($y, 'name', 'BBC')
    $::DB->limit_page (1, 10) # first page, 10 rows per page
);

while (my $arrayref = $rs->next())
{
    my $x_variable = $arrayref->[0];
    my $y_variable = $arrayref->[1];
}

KNOWN BUGS

This is an ALPHA release. There is no known bugs, which means that there's plenty of them to find out... reports and patches appreciated!

AUTHOR

Copyright 2002 - Jean-Michel Hiver <jhiver@mkdoc.com>

This module free software and is distributed under the same license as Perl itself.

SEE ALSO

# The TripleStore mailing list
http://www.email-lists.org/mailman/listinfo/triplestore

# Triple Querying with SQL
http://www.picdiary.com/triplequerying/