In this documentation, we will describe how to use the EiffelStore library in
an Eiffel project.
This library provides a consistent set of classes for writing object oriented Eiffel applications that need to handle persistent objects.
Before using EiffelStore, we suggest that you read this documentation.
The library interface consists of two sets:
- A set of general purpose classes designed regardless of any data management system used,
found in directory
: $EIFFEL5/library/store/interface, and that you always need in your universe
- Specific classes, referred to by the interface classes, bridging the application to selected data management systems called
"handles''.
The set of handles may be found:
- in directory $EIFFEL5/library/store/dbms
- in directory $EIFFEL5/library/store/dbms/rdbms/{server_name}
where {server_name} correspond to a selected relational database
management system.
Additional support classes are also needed in your universe regardless of the selected handle. They are located in:
- directory $EIFFEL5/library/store/support and $EIFFEL5/library/store/dbms/support
Example classes are located in:
You can find the user's manual of our previous version of EiffelStore (mostly
up-to-date) in pdf format by clicking here. (This manual is more useful more experiments
users)
Our library has been successfully tested with :
- ODBC 3.0
- Oracle 8.04
- Oracle 8i Entreprise Edition.
However you should be able to use it with Sybase and OpenIngres. As far as
ISE's support is concerned we currently only guarantee support for ODBC and
Oracle. Users who want to use Sybase or OpenIngres can still do so, but in the
past couple of years we have removed them from our officially supported
platforms, due essentially to insufficient number of users.
In order to work with EiffelStore you also need to get EiffelTime
library.
We provide you the necessary files to compile an EiffelStore project. They should be located in the directory $EIFFEL5\library\store\spec\$PLATFORM\lib (for Unix) and $EIFFEL5\library\store\spec\$COMPILER\lib two C libraries objects.
If the required files are not installed, please the following steps:
Before starting the compilation of the C libraries:
- Make sure the environment variables EIFFEL5 and PLATFORM are set.
- Make sure that the Database you have chosen is installed
- Install the C library for the EiffelTime library, click here
to have the instructions on how to build it.
Now, you can installl the C libraries. We will describe below the procedure
for both Windows and Unix:
Congratulation, your EiffelStore library has been successfully installed.
Now you can start a new Eiffel Project using EiffelStore.
In order to use EiffelStore in an Eiffel Project, you have to include in your
project, the right clusters and the right external files. Thus, you need to
configure your Ace file.
You can get all the information about Ace files here.
You have to include EiffelStore clusters and EiffelTime clusters.
To include the EiffelStore cluster you have to :
- Include these clusters one by one:
estore_support: "$EIFFEL5\library\store\support";
estore_interface: "$EIFFEL5\library\store\interface";
estore_db_support: "$EIFFEL5\library\store\dbms\support";
THEN
You have to include the cluster referring to your database:
- For Oracle : estore_oracle: "$EIFFEL5\library\store\dbms\rdbms\oracle";
- For ODBC: estore_odbc: "$EIFFEL5\library\store\dbms\rdbms\odbc";
In order to work with EiffelStore you need the EiffelTime
library installed. And so, you need to include its cluster in your Ace file:
time: "$EIFFEL5\library\time";
time_format(time): "$\format";
english_format(time_format): "$\english";
You now have to include all the external files.
You have to include the oci libraries and the C EiffelStore Files. :
include_path: "$(ORACLE_HOME)\OCI\Include",
"$EIFFEL5\library\store\dbms\rdbms\oracle\Clib";
And to include the Oci.lib,oracle_store.lib, datetime.lib and support.lib
objects:
objects: "$(ORACLE_HOME)\OCI\lib\msvc\oci.lib",
"$(EIFFEL5)\library\store\spec\$(COMPILER)\lib\oracle_store.lib",
"$(EIFFEL5)\library\store\spec\$(COMPILER)\lib\datetime.lib",
"$(EIFFEL5)\library\store\spec\$(COMPILER)\lib\support.lib";
Remark: This description is valid only under Windows, if you use Unix, the objects are
: libsupport.a, liboracle.a, libdatetime.a .
Moreover, the first command which include the OCI C library should be : "-L$(ORACLE_HOME)/lib
-lclntsh"
You only need to include the odbc32.lib,odbc_store.lib, datetime.lib,
support.lib objects and the C EiffelStore files.
include_path: "$EIFFEL5\library\store\dbms\rdbms\oracle\Clib";
objects: "your_path\odbc32.lib",
"$(EIFFEL5)\library\store\spec\$(COMPILER)\lib\odbc_store.lib"
"$(EIFFEL5)\library\store\spec\$(COMPILER)\lib\datetime.lib",
"$(EIFFEL5)\library\store\spec\$(COMPILER)\lib\support.lib";
Now your Ace file should be configured. However here you can see the Ace file
of the Insert example, working with Oracle under Windows. (Check the Ace of the examples if
you need to see other Ace file).
System inserter
root
inserter (root_cluster): "make"
default
assertion (all)
console_application (yes)
precompiled ("$EIFFEL5\precomp\spec\$PLATFORM\base")
cluster
root_cluster: "$EIFFEL5\examples\store\insert";
estore_examples_objects:"$EIFFEL5\examples\store\Utilities";
oracle_handle: "$EIFFEL5\examples\store\Utilities\oracle";
-- EiffelBase
all base: "$EIFFEL5/library/base"
exclude
"desc";"table_eiffel3"
end
-- EiffelStore
estore_support: "$EIFFEL5\library\store\support";
estore_interface: "$EIFFEL5\library\store\interface";
estore_db_support: "$EIFFEL5\library\store\dbms\support";
estore_oracle: "$EIFFEL5\library\store\dbms\rdbms\oracle";
-- EiffelTime
time: "$EIFFEL5\library\time";
time_format(time): "$\format";
english_format(time_format): "$\english";
external
include_path: "$(EIFFEL5)\library\store\dbms\rdbms\oracle\Clib",
"$(ORACLE_HOME)\OCI\include"
object:
"$(EIFFEL5)\library\store\spec\$(COMPILER)\lib\support.lib",
"$(EIFFEL5)\library\time\spec\$(COMPILER)\lib\datetime.lib",
"$(EIFFEL5)\library\store\spec\$(COMPILER)\lib\oracle_store.lib",
"$(ORACLE_HOME)\OCI\lib\msvc\oci.lib"
end
|
To see all the step of connecting to your Database, let's see the init
feature of the Insert example:
We use in that case the Oracle example as the connection only ask for a login
name and a password.
init is
-- Init session.
local
tmp_string: STRING
do
-- Ask for user's name and password
io.putstring ("Database user authentication:%N")
io.putstring ("Name: ")
io.readline
tmp_string := clone (io.laststring)
io.putstring ("Password: ")
io.readline
-- Set user's name and password
login (tmp_string, io.laststring)
-- Initialization of the Relational Database:
-- This will set various information to perform a correct
-- connection to the Relational database
set_base
-- Create usefull classes
-- 'session_control' provides information control access and
-- the status of the database.
-- 'base_store' provides updating facilities.
create session_control.make
create base_store.make
-- Start session
session_control.connect
ensure
not (session_control = Void)
not (base_store = Void)
end
|
Now you are connected to your database, and you can perform a query.
To see all the step of a basic query, let's see the make_selection feature of
the Select example.
make_selection is
-- Select books whose author's name match
-- a specific name.
-- The name must be written in upper-case letters, and
-- enclosed in '%' (This caracter is used by SQL to match
-- any string of zero or more character)
local
author: STRING
do
from
io.putstring ("Author? ('exit' to terminate):")
io.readline
until
-- Terminate?
io.laststring.is_equal ("exit")
loop
author := clone (io.laststring)
io.putstring ("Seeking for books whose author's name match: ")
io.putstring (author)
io.new_line
io.new_line
-- A mapped Eiffel object (author) is referred to by a key name
-- "author_name" which can be used in a SQL statement prepended with ':'
base_selection.set_map_name (author, "author_name")
-- Set action to be executed after each 'load_result' iteration step.
-- 'init' and 'execute' method of the current class are to be used.
base_selection.set_action (Current)
-- Query database.
-- The reference ":author_name" will be changed to the value of
-- the Eiffel object referred to by the key "author_name".
base_selection.query ("select * from DB_BOOK where author = :author_name")
-- Iterate through resulting data, and display them
base_selection.load_result
-- Delete "author_name" from the map table
base_selection.unset_map_name ("author_name")
-- Terminate the current order
base_selection.terminate
io.new_line
io.putstring ("Author? ('exit' to terminate):")
io.readline
end
end
|
Thus, to perform a query you need to create a DB_SELECTION object (base_selection
in this example). Then you can follow all the steps of this example.
We developed 7 Examples that you can try to understand EiffelStore.
They are in the directory : "$EIFFEL5\examples\store"
We recommend you to try the examples in the following order:
- Esql
Very useful to test you Database connection.
- Select
The basic example for a query of your Database.
- Insert
The basic example for an insert in you Database
- Nesting
An Example of Nested queries.
- rm2oom
From an Relationnal Model to an Object Oriented Model.
- oo2rm
From an Object Oriente Model to an Relationnal Model.
- convert
to exercise the flat file conversion utilities.
Make sure that you have read the previous explanations
before running this example.
To run esql, you just need to launch : esql.
Then this example illustrates how to access database information.
SQL statements are filtered through a monitor and sent to the RDBMS.
Remarks : Once you made an SQL Statements, you should not ended it using a
semi-colon. Indeed, you can do it with Oracle statement but not with ODBC
statements.
Make sure that you have read the previous explanations
before running this example.
To run this example. launch: book_select
This example illustrates how to perform a select query.
It is very interesting because you can understand the query method of
EiffelStore.
Before running this example you have to copy the right file in the W_code
directory of your project.
Thus for an Oracle Database, you have to copy data.sql.oracle in W_code and
rename it as data.sql.
For an ODBC Database, you have to copy data.sql.odbc in W_code and rename it
as data.sql.
For a Sybase Database, you have to copy data.sql.sybase in W_code and rename
it as data.sql.
For an Ingres Database, you have to copy data.sql.ingres in W_code and rename
it as data.sql.
Make sure that you have read the previous explanations
before running this example.
To run this example launch book_insert.
This example illustrates how Eiffel users may access their selected Database to insert or modify objects in existing tables.
An Eiffel object, say "`a book'', described by class BOOK, is inserted into a repository (instance of class REPOSITORY) defined
with `db_book' access key for instance.
The repository name should match an external RDB table named `db_book'.
In the example, the session terminates on unexisting RDB table.
Class DB_CHANGE encapsulates features supporting insertion statements.
SQL insert statements insert new objects into existing repositories (i.e existing RDM tables).
Class DB_CONTROL provides facilities to manage the session, control the DB status, and query the results.
Make sure that you have read the previous explanations
before running this example.
This example illustrates how to customize actions when retrieved selection
Results.
In that way it does two nested queries to retrieve all the tables and all the
columns of your Database.
Make sure that you have read the previous explanations
before running this example.
This example illustrates how RDBS tables can be translated into Eiffel class definitions where
features are simply attributes matching the DB table fields.
Class descriptions are printed on standard output.
A specific repository is referred to by a name that should match a RDB table name for which an Eiffel
class equivalent is requested.
Make sure that you have read the previous explanations
before running this example.
Object Oriented Model To Relational Model (OOM2RM)
This example illustrates how to dynamically generate the description of a relational schema (with SQL
statements) from the traversal of a network of Eiffel objects.
One Eiffel model sample is given in subdirectory Model1 and serves as the sample to use to generate
the relational schema.
To apply the example on a model of your choice, replace in the Ace file reference to the cluster
Model1 with a reference to your customized cluster.
Remarks:
Some problems have been encountered when using generic containers classes derived with simple type.
To overcome this problem, rather use ARRAY [INTEGER_REF] instead of ARRAY [INTEGER].
Make sure that you have read the previous explanations
before running this example.
This example illustrates the way one can convert Unix flat files into class instances.
Changing a field (it's type or format) in an example.dat file, highlighs the parser error
detection mechanism.
When the example has been compiled, put the two files "example1.dat" and "example2.dat" in the
directory "EIFGEN/W_CODE" or in "EIFGEN/F_code" directory depending on your type of Eiffel
compilation.
|