=pod

=head1 NAME

Webservice::InterMine::Cookbook::Recipe1 - The Bare Basics

=head1 SYNOPSIS

  # Get a list of the organisms in the database

  use Webservice::InterMine 'www.flymine.org/query';

  my $query = Webservice::InterMine->new_query(class => "Organism");

  # Print out all the genera and taxons of the organisms in the database

  $query->select('taxonId', 'genus');
  $query->show();

  # Also get the species associated with the organism, and order by genus

  $query->add_view('species');
  $query->order_by('genus');
  $query->show();

=head1 DESCRIPTION

At its heart a query is just a description of what you want to get out
of the database - and the first part of that is the view, which specifies
the fields for each row of results you get back. In the InterMine webapp the 
output columns are often referred to as the "view". That terminology is supported here, as
well as what may be more familiar SQL-ish syntax.

Every query should have a root class, or if you prefer, a table to select from. 
It is good practice to declare this root with the optional C<< class => "Gene" >>
parameters. If these are not provided, the first root class found will be assumed to
be the root class. The following are equivalent:

  my $query = $service->new_query(class => "Gene");
  $query->select("symbol", "primaryIdentifier", "length");

and

  my $query = $service->new_query();
  $query->select("Gene.symbol", "Gene.primaryIdentifier", "Gene.length");

Choose whatever seems best to you.

=head2 PATHS

The view is a list of strings which represent 'paths' in Webservice::InterMine terminology.
C<Organism.name> is such a path, which says you want to know the name
of each organism. This kind of notation may be familiar to you as object/property
notation in many computing languages, or as the table/column notation of SQL. In InterMine,
the properties of an object/columns of a table, may themselves be references to other 
objects/other tables, and so have properties/columns of their own. Joins are implicit 
in this system, and you can freely add as many further columns as you wish:

  $query->select("Organism.chromosomes.name")

Note that here the "chromosomes" property is a reference to not just one object/record,
but potentially many chromosomes. If these are selected for output, there will
be as many rows in the output as there are chromosomes to display.

This system of objects/tables, properties/columns, and joined references/nested/objects
is encapsulated in InterMine terminology which refers to:

=over

=item: Classes (tables)

=item: Fields (columns)

=item: Attributes: (fields of a class which hold data)

=item: References: (fields of a class which refer to objects)

=item: Collections: (fields which may refer to more than one object)

=back

The output columns must eventually end in a data field to display (an attribute).

The view list can be specified in a couple of ways, either as a list of paths,
as in:

  $query->add_view('Organism.name', 'Organism.taxonId');

or as a space or comma delimited string, as in:

  $query->add_view('Organism.name Organism.taxonId');

or any mixture of the two. C<add_view> can also be called multiple times,
with each call appending the view(s) onto the list.

By default the results returned to you will be sorted by the values in the first
column (the first item in the view list), and in an ascending direction. You can
override this default by specifying any of the view columns to sort by. You do
not have to specify a direction - C<asc> will be the default if none is provided.
The following are all(1) valid ways of defining the sort order, and would all have
the same result:

  $query->add_sort_order('Organism.taxonId');

or

  $query->add_sort_order('Organism.taxonId', 'asc');

or

  $query->add_sort_order('Organism.taxonId' => 'asc');

or

  $query->add_sort_order(
      path      => 'Organism.taxonId',
      direction => 'asc',
  );

In addition there is a more SQL-like C<order_by>, which is slightly different, in that
instead of adding elements to the sort order, it replaces what is currently in there. The 
following are equivalent:
 
  # Sort first by name (asc), and then by symbol (desc)
  $query = $service->new_query(class => 'Gene');
  $query->add_view('symbol', 'name');
  $query->add_sort_order('name')
  $query->add_sort_order('symbol', 'desc');

  # Note that it is possible to chain the SQL-ish method calls
  $query = $service->new_query(class => 'Gene');
  $query->select('symbol', 'name')->order_by(name => 'asc', symbol => 'desc');

C<order_by> supports multiple orders being given at once, but in which case
the directions should be specified. It does not however support the names argument syntax.

The two valid directions are 'asc' or 'desc' (case is irrelevant), and you must
specify the view before you select the sort order.

Once we have a defined view, we have a valid query, which can be run and will
return results. Without constraints these queries will just return I<every>
item of the specified type from the database, so these queries will list I<all>
organisms that the www.flymine.org database has data on. Obviously it is more useful to
be able to specify I<which> items you want, and for this we need constraints,
which we deal with in the next recipe.

=head1 CONCLUSION

A query is at heart just a view list with (optionally) some constraints on
the items you want back. This recipe demonstrates the mimimum you need to
set up a valid query.


=head1 FOOTNOTES

1) Perl is famous for its philosophy of TIMTOWTDI (There is more than one way to
do it) - and that is in evidence here as well: there are generally serveral ways
to call the methods in the Perl API, and none is categorically I<right> or
I<wrong>. In the above example with C<sort_order>, you can see a progression from
terser to more declarative styles; it is perhaps good practice to use declarative
styles if you want your code to be robust and readable, and thus more
maintainable.

=head1 SEE ALSO

L<http://www.intermine.org/perlapi>

=head1 AUTHOR

Alex Kalderimis <perldev@flymine.org>

=head1 COPYRIGHT AND LICENSE

Copyright 2004-2010 by Webservice::InterMine

L<http://www.intermine.org>

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

=cut

  # Get a list of the organisms in the database

  use Webservice::InterMine 'www.flymine.org/query';

  my $query = Webservice::InterMine->new_query(class => "Organism");

  # Print out all the genera and taxons of the organisms in the database

  $query->select('taxonId', 'genus');
  $query->show();

  # Also get the species associated with the organism, and order by genus

  $query->add_view('species');
  $query->order_by('genus');
  $query->show();

  my $query = Webservice::InterMine->new_query(class => "Organism");
  $query->select('genus', 'species', 'taxonId')->order_by(genus => 'desc', taxonId => 'asc');
  $query->show();


