You are browsing the documentation for iTop 2.4 which is not the current version.

Consider browsing to iTop 2.6 documentation

A Bookstore Database

How can we use OQL on a database designed to manage for example a Bookstore?

The most basic query is simply a SELECT with just a class name:

SELECT
    Book

This query returns any Book existing in the database. As you can notice, there is no need to specify the expected columns, as we would do in a SQL SELECT statement, because OQL queries always return complete objects.

Joining classes together

I would like to list all books written by someone whose name starts with 'Camus'

SELECT
    Book
    JOIN Artist ON Book.written_by = Artist.id
    WHERE Artist.name LIKE 'Camus%'

Note that there is no need to specify whether the JOIN is an INNER JOIN, or LEFT JOIN. This is well-known in the data model. The OQL engine will in turn create a SQL query based on the relevant option, but we do not want to care about it, do we?

Now, you may consider that the name of the author of a book is of importance. This is the case if it should be displayed anytime you will list a set of books, or if it is an important key to search for.

Then you have the option to change the data model, and define the name of the author as an external field. Such an external field would be defined by the external key written_by and the target attribute name. Let's define this new field as writer_name.

The query could then be simplified to:

SELECT
    Book
    WHERE Book.writer_name LIKE 'Camus%'

The join will actually be performed by the underlying SQL query, but this is completely transparent to the OQL. It will happen each and every time those objects are queried so that the attribute writer_name becomes part of the properties of a book – though it will be read-only.

It is also possible to retrieve the authors and their books in one query. For example let's retrieve, for each author, a list of the books written in 2001 and after. This can be achieved using the query:

SELECT
    Artist, Book FROM
    Book
    JOIN Artist ON Book.written_by = Artist.id
    WHERE Book.issued > '2001-01-01'

The data set resulting from this query will have two columns for each “row” of the set: an Artist and a Book.

Classes Inheritance

Now, as this is a modern bookstore, several types of media are available: Audio, Video, Book. All of them have been declared as classes derived from Item in the data model, as shown below:

  • Item
    • Audio
    • Video
    • Book

Since Audio, Video and Book objects are also Items (thanks to the class inheritance), all of them can retrieved in one single query. For example let's retrieve all Items not being produced by in France:

SELECT
    Item
    JOIN Producer ON Item.produced_by = Producer.id
    WHERE Producer.country != ’France’

This query will return books as well, because a Book is an Item… that’s due to classes inheritance: a Book inherits from Item, or we can say that a Book is a specialized item.

Data Hierarchies

Let's imagine that a book is characterized by one Topic.

Topics are organized as a hierarchy of objects. Therefore a Topic can have a parent Topic:

Let's consider the following hierarchy of Topics:

  • Art
  • History
    • Archaeology
      • Civilizations
      • Archeologists
      • Egyptology
    • History of science
    • War

Books can be attached at any level.

Let’s list all books about History:

SELECT
    Book
    JOIN Topic AS NodeTopic ON Book.topic_id = NodeTopic.id
    JOIN Topic AS RootTopic ON NodeTopic.parent_id BELOW RootTopic.id
    WHERE RootTopic.name = ’History’

This query will return all books related to the Topic 'History', 'Archaeology', 'Civilizations', 'Egyptology', etc. but not 'Arts'. All the topics being in the tree under 'History' will be considered, whatever the depth of the hierarchy.

The following query will return only the Books which Topics is strictly below 'Archaeology', e.g. only 'Civilizations', 'Archeologists' and 'Egyptology':

SELECT
    Book
    JOIN Topic AS NodeTopic ON Book.topic_id = NodeTopic.id
    JOIN Topic AS RootTopic ON NodeTopic.parent_id BELOW STRICT RootTopic.id
    WHERE RootTopic.name = ’Archaeology’
2_4_0/oql/example.txt · Last modified: 2018/12/19 11:40 (external edit)
Back to top
Contact us