Thursday, December 9, 2010

Propel and Oracle - Installing from scratch on Ubuntu 10.04 / 10.10

Propel (http://www.propelorm.org/) is a great ORM package for PHP which is compatible with most popular database systems, including MySQL, PostgreSQL, SQLite, MSSQL, and Oracle.
Nevertheless putting everything up and running can be quite tricky: it depends on phing, php cli, oracle drivers, etc, which are not ready out of the box.

After many hours reading tutorials and source code, and many failed attempts, I was finally able to put it running, which I will explain below.

Rule #1: Don't reinvent the wheel!
There is a crucial element in this story: the database driver. Installing Oracle Call Interface (OCI) and insert all oci modules into php can be tricky. Therefore, if you are installing from scratch I'd HIGHLY recommend to use Zend Server CE, the successor of ZendCore. This is the procedure described in this guide.
If you're willing to do it by hand, I'd suggest you to visit the following resources:
https://help.ubuntu.com/community/PHPOracle


Step #1: Install ZendServer (apache+php+DB drivers)

Go to http://www.zend.com/en/products/server-ce/downloads and download the latest ZendServer CE. (it's free). You could also try setting up a deb source for apt-get, but in the case of Ubuntu 10.10 this didn't work.
Locate and extract the package:
tar -xzf ZendServer-CE-php-xxxx
Move in the newly created directory and begin installation:
cd ZendServerxxxx
sudo ./install.sh

Great! your Apache server should be up and running. Refer to the printed INSTALLATION SUMMARY message to know your Zend administration page address. By default: https://localhost:10082/ZendServer

In the Administration page go to Server Setup -> extensions and check whether oci8 and pdo_oci extensions are "ON". Otherwise your system is probably missing libaiol. In such case install it:
sudo apt-get install libaio1
Back to the administration page hit "Restart PHP".

Finally we need to add php binaries and libraries to the path. In order to do that, append the following lines to the end of your /etc/profile file (check the path according to your installation).

PATH=$PATH:/usr/local/zend/bin
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/zend/lib


and load the new settings:
source /etc/profile


Step 2: Installing and fixing propel

The easiest way to install propel is, without doubt, using php-pear
ZendServer will also provide this utility. If you are installing the system by hand make sure you have php-pear installed before proceeding.

In order to install the Propel packages, you must add new channels from where pear will fetch it and its dependencies:

pear channel-discover pear.propelorm.org
pear channel-discover pear.phing.info

Install propel
pear install -a propel/propel_generator
pear install -a propel/propel_runtime

After the installation is finished, there are two details which must not be forgotten.
In first place, add propel_generator library folder to php include path. The easiest way is to through the zend administration page, under Server Setup->Directives->Paths and directories. Add to the box the path of the libraries, separating with ":", typically:
:/usr/local/zend/share/pear/data/propel_generator/lib
Restart PHP

Further, the current version of phing doesnt support multiple classpaths, which makes Propel to raise the following error every-time it's executed:
Swallowing exception: Could not create task of type: propel-sql [wrapped: Could not instantiate class PropelSQLTask, even though a class was specified. (Make sure that the specified class file contains a class with the correct name.)]

To correct this, edit propel_gen config file:
vi /usr/local/zend/share/pear/data/propel_generator/build-propel.xml

Locate the block:

path id="propelclasses">
pathelement dir="${propel.home}/lib/"/
pathelement dir="${propel.project.dir}/"/ --
/path


and transform it into

path id="propelclasses"
pathelement dir="${propel.home}/lib/"/
!-- pathelement dir="${propel.project.dir}/"/ --
/path

(note the commented second pathelement entry)

After this you should be able to run propel_gen


Step 3: Connecting to the database

The last step is to define the connection to the database. In this case I'll show an example considering a connection to a remote server. Just be sure all php oci modules are loaded and working.

Each propel project has its configurations in a build.properties file, including the connection to the database.
In case of oracle drivers, one must refer to the system OCI drivers, although we must generate Oracle like queries.

Please provide the following details, replacing {} according to your case:

propel.project = {proj name}

# The Propel driver to use for generating SQL, etc.
propel.database = oracle

propel.database.driver = oci

#tnsnames entry
#propel.database.url = oci:dbname={user}@{DBNAME}/{SID}

#Full qualified conn string (no need for TNSNAMES)
propel.database.url = oci:dbname=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST={db_server})(PORT={db_port})))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME={SID})))

propel.database.creole.url = ${propel.database.url}
propel.database.user = {user}
propel.database.password = {passwd}