Finally we have found some time to start documenting the different Emilda API functions present to lower the threshold for You to take part in the Emilda development process.
The Emilda FAQ contains frequently asked questions about Emilda, the installation and related issues.
The manual for setting up a working and optimized Emilda 1.2.x environment either from scratch, or alternatively upgrading from an existsing setup.
Emilda was built to work with the requirements above. There is however no good reason why it should not work on another platform with other backend applications, although this might require some changes to the Emilda source. Alternative setups (such as Microsoft Windows) have been attempted, but they require hard work and both administrative and coding skills. The biggest problems you will experience when attempting a Windows install is getting the correct MySQL client version and getting the Zebra Perl module installed.
* The official, and supported database version of MySQL is 4.1.x. As such, we cannot debug or give support for errors related to usage of an earlier database version. As of 1.2-alpha, however, Emilda has been tested to work with both 3.23.x and 4.0.x, so even though we encourage you to upgrade your MySQL server it is not required.
Instructions for setting up a fresh, Emilda 1.2.x environment
The below instructions at least gave me a working environment on my Debian/Unstable workstation, but should also serve as directives how to get Emilda working on your computer.
- INSTALL A BASE SYSTEM. Debian/Unstable comes with MySQL 4.0, so if you find yourself satisfied with this, you can install this as a .deb package, otherwise we recommend installing a precompiled binary release from the MySQL site. Using a precompiled version will - at least to our knowledge - supply you with a more stable environment than if you compile it from source, but this is entirely individual.
- INSTALL YAZ. (http://www.indexdata.dk/yaz/) Emilda 1.2 (and earlier) has only been tested using Yaz => 2.0.2, but should at least work with other Yaz 2.x-versions. Feel free to use Yaz 1.x-vesions at own risk. At least on Debian, using Apt is a good idea, just follow the instructions on the Indexdata site how to change your /etc/sources.list to comply with Indexdata downloads.
- INSTALL ZEBRA. (http://www.indexdata.dk/zebra/) Emilda 1.2 (and earlier) has only been tested using Zebra => 1.3.10, but should work using also other versions (except 1.3.14, see note below). We however recommend using 1.3.15+. Zebra should, stressing the word "should", be built from source. Special attributes to use when compiling Zebra is '--with-perl' since the Perl-API of Zebra is required by Emilda to manage Zebra from within the system. After making Zebra, go to the perl/ subfolder in the Zebra src-folder and install the perl library located there. Before making the source there, make sure that you edit the Makefile and search for "MakeMaker const_loadlibs section". A few lines under that string you should add in EXTRALIBS and LDLOADLIBS the -lexpat parameter before the -lxml2 parameter. Should look something like this: ... -L/usr/lib -lexpat -lxml2 ...
IMPORTANT NOTE
During QA it was noticed that version 1.3.14 of Zebra contains a bug that will break Emilda MARC management functions and should Not be used with Emilda under any circumstances. In versions of Zebra prior to 1.3.14 the problem doesn't exist, and in version 1.3.15 this issue has been corrected. As such we encourage Emilda users to install version 1.3.15 or later of the Zebra server.- INSTALL MYSQL. (http://www.mysql.com) As of 1.2-alpha it is possible to use versions 3.23 and above of MySQL, but we strongly recommend using version 4.1.2+ for any version of Emilda. When installing precompiled files, remember to install development headers so that PHP can include the correct "libmysqlclient"-headers.
- INSTALL GDThe old layout of Emilda uses GD to generate images, and as such it is a good idea to install GD support in PHP. For this, you need to install GD on your system, which on Debian works like a charm using Apt.
- INSTALL PHP. (http://www.php.net) It is wise not to try to use Emilda 1.2.x with older PHP versions than 4.3.x as problems might arise, especially with the Object model. In addition to the configure parameters you choose to use, be sure to have the following:
--with-mysql
--with-zlib
--with-yaz
--with-gd
--with-gettext
--with-ldap (optional; needed for LDAP authentication)If you choose to omit --with-apxs or your architecture does not support apxs, be sure to configure your Apache server to utilize PHP.
These packages kan either be installed using the CPAN-shell in perl (perl -MCPAN -e shell) or by downloading separate source-files and compiling them individually. Dependencies might already be met, so use consideration from case to case.
Use the install command in the CPAN-shell.
- Net::Z3950 (http://search.cpan.org/author/MIRK/Net-Z3950-0.35/)
Prerequisites:
- Event (http://search.cpan.org/author/JPRIT/Event-0.87/)
- MARC::Record (http://search.cpan.org/author/PETDANCE/MARC-Record-1.29/)
- GD::Barcode (http://search.cpan.org/author/KWITKNR/GD-Barcode-1.14/)
- DBD::mysql (http://search.cpan.org/~rudy/DBD-mysql-2.9003/lib/DBD/mysql.pm)
The following steps need to be performed in the exact order they are given here, to prevent unwanted actions. If you are not totally sure about what you are doing, consider contacting someone who does, since doing something wrong might damage data in your database.
- LOG INTO MYSQL Log into mysql using the "mysql"-tool. You have to have root access to the MySQL database.
COMMAND:
mysql --user=root --password='rootpass'
- CREATE DATABASE The next thing to do is create the Emilda database.
COMMAND:
create database emilda;
The name of the database can be anything, but if You change it from 'emilda' remember to change it in the configuration.
- GRANT PRIVILEGES After creating the database we want to grant privileges to the new database to some user, since we do not want Emilda to run with the root user.
COMMAND:
grant all privileges on emilda.* to emilda@localhost identified by 'password';
If You specified another database name than 'emilda' You need to alter the syntax here; change 'emilda' in 'emilda.*' to Your database name. Further, if You want another username than 'emilda' change the 'emilda' in emilda@localhost to Your alternative. Finally replace 'password' with the password You choose. Remember to update the configuration.
- EXIT MYSQL Leave the MySQL server.
COMMAND:
exit;
It is imperative to have all folders in place for the system to work. To assure that you have all folders in their correct places, follow the below instructions.
COPY THE SOURCE FOLDER You will want to have the Emilda-source, src/ folder in your document-root. (e.g. /var/www/ or /var/www/html/) If you have dedicated the server entirely to Emilda and no other projects will be run on the computer, you can copy the files directly into the document-root. Otherwise it is wise to copy them into a subfolder. (e.g. /var/www/emilda)
- ZEBRA FOLDER You need to have a Zebra root-folder somewhere on the server. This folder contains all Zebra configuration files and specifications. The location of this folder is uninteresting, since it can be configured in the "Zebra configuration"-section. Inside the zebra root-folder you need to have a subfolder containing MARC-records. Also the name of this folder is configurable. What however is important is that both the "zebrasrv"-process and the Apache web server (typically username 'www-data' or 'apache') have write access to the records folder.
New in Emilda 1.2 is the usage of shadow registers to allow fast and secure updates of the database. As such, depending on your database size, the zebra folder might consume considerably large space, and there is no check that there is enough space available. Please make sure that you assign the zebra folder enough space to operate.
After completing all the sections above it is time for fine-tuning.
- CONFIGURE APACHE Emilda requires some configuration directives to be present in Apache to work correctly. You can configure it either as a virtual host or customizing the .htaccess file supplied with Emilda 1.2. See in the Sample Configurations-section for an example on a virtualhost configuration. Remember to restart Apache after modifying your configuration file.
- SETUP EMILDA Run the setup.php script supplied with Emilda to ensure that your system is sane, and properly configured. You do this by pointing your favourite browser to the Emilda "location", and accessing setup.php (e.g. http://localhost/emilda/setup.php) and following the on-screen instructions. When installing a fresh installation the emilda.sql file is needed by setup.php. You should copy the sql directory from the Emilda tarball to your Emilda www-root so that setup can use it. After a successful installation, the sql directory can be removed. It is adviceable to disallow setup.php from web users after running it.
- SETUP LANGUAGES To get languages working correctly, upgrade your locale linkage folders in the ./locale folder. You do this by going into the Emilda source folder and executing the following command:
sh bin/locales.shIn addition you need to compile the languages to support these. This is done by going into the source folder and executing the following command:
sh bin/compile_languages.sh- CONFIGURE EMILDA Last but not least you need to configure Emilda to suit your system. This you do by using the Emilda configuration section, which of version 1.2-alpha is within the Emilda system. The Configuration Panel can be found under the Management icon in Emilda. To log in, use the administrator account information provided when you ran setup.php.
One account has been created automatically for the system administrator. Use it to create users and configure Emilda further, just remember to change the password! The login information for the admin account was provided when setup.php was run.
Below are some directives how to configure Zebra to comply with Emilda in an acceptable manner.
The first thing to be done is to decide where the Zebra folder is to be located. We recommend that you put it as a subfolder (zebra/) of the Emilda source folder. One reason not to have it there is when the Zebra database is bigger than the disk that the Emilda source folder is located on. In such cases, it might be a good idea to put it on a separate drive.
There are two ways to configure Zebra to comply with Emilda; either configuring it from the example files supplied with the Zebra source, or using the pre-configured setup supplied with Emilda.
When configuring from the examples supplied with Zebra, you need to put the USMARC example files into your zebra-root. They are normally located in test/ under the idzebra source folder. Additionally you need to put the tab/ folder from the idzebra source folder into your zebra-root. You can of course use a custom setup if you feel familiar with Zebra configuration.
Now we have a working environment where the "zebrasrv"-process can live and work, but this is not enough for Emilda as it uses attributes that are not defined in the default configuration supplied with Zebra. That is why we have supplied a tarball containing all the files that need to be replaced in your Zebra root folder and it can be downloaded from the same location you downloaded Emilda itself, named "emilda-zebra-folder-VERSION.tar.gz". Unpack the tarball in some arbitraty location, and copy the files to their appropriate locations (see below).
If you want to use our pre-configured zebra environment, download the tarball and extract into the location where you want your zebra-root to exist. This tarball contains all necessary files for Zebra to work with Emilda, so no configuration should be needed.
Before starting Zebra, we need to create a folder where the MARC-records are to be stored. In our examples it is called records/ and it is located in the Zebra root folder (/path/to/emilda/zebra/records/). What is important with this folder is that both the Zebra process and Apache need to have write access to it. This can be achieved e.g. by running the "zebrasrv"-process as the Apache user and only giving the Apache user write access to records/, or by giving write access to records/ to both Apache and the user running the "zebrasrv"-process. There is no favourable way to do this, both work just as well.
After deciding on which method to use, we are ready to prepare Zebra for running; Zebra needs to init and index the records/ folder before we start the process. If you have any records that you wish to import into Emilda, you need to copy these into the records/ folder before running these commands. (If you afterwards want to import MARC-recods, you copy them into the recods/ folder and run these commands.) However, remember that the Items that the records in the records/ folder represent need to be added into the SQL database before Emilda can use them.
This should give you a working environment with Emilda and Zebra.
NOTE!
If the records/ folder is empty, there will be an error of the type
Unsupported Use attribute: 7
which should not show up after the first record has been added. If it persists there is something odd going on - try to check if you have done everything according to the above instructions, or send a note to the Emilda mailing list.
This section explains how to upgrade an existing Emilda setup to 1.2.x. Below you'll find instructions on how to upgrade between different versions. If you upgrade from an older version, you should follow each step in the progress, i.e. upgrading from 1 -> 3 you would do 1 -> 2, 2 -> 3. Make sure you read the right sections and do the right steps to achieve a fully working Emilda environment.
Emilda 1.2.x releases are stable bug fix releases. As such, they only fixes a few minor code issues. Upgrading to 1.2.x can be done by simply overwriting the contents of the existing src folder with the contents of the new src folder (make sure you don't have anything else than source files in that folder).
The easiest way, however, is to use the supplied 1.2.x patch. Download the patch, save it in your current emilda src folder (the one with all the .php files) and issue the following command (in the src folder):
gunzip emilda-1.2.x.patch.gz patch -p2 < emilda-1.2.x.patch
If there is an emilda-1.2.x-lang.patch.gz file available, the language files have changed too. Download this patch, save it in your emilda lang folder and issue the following command (in the lang folder):
gunzip emilda-1.2.x-lang.patch.gz patch -p2 < emilda-1.2.x-lang.patch
After this the new language files need to be compiled as usual.
Watch out for any errors or warnings. After this run setup.php to make sure your system is up-to-date. If everything was successful, you should have a working Emilda 1.2.x environment.
This is only required for Emilda 1.2.1.
The zebra folder has changed in 1.2.1. Turn off your zebra server. Make sure you don't loose your records folder and replace your existing zebra folder with the new one (the tab/bib1.att file has changed). After the upgrade issue the following commands in the zebra root folder:
zebraidx init zebraidx -g emilda update records zebraidx commit
If everything went smoothly, restart zebra.
Always make a backup of your database before upgrading!
The easiest way to upgrade the Emilda source is probably to move the old directory to a backup location, install the new source from the tarball and copy over required files from the old installation. Here's an example:
mv emilda emilda-1.1 tar -zxf emilda-1.2.tar.gz mv emilda-1.2/src emilda cp emilda-1.1/config emilda/conf/ cp emilda-1.1/MARC_config emilda/ cp emilda-1.1/MARC_defs emilda/ cp emilda-1.1/MARCsyn_config emilda/ cp -a emilda-1.1/perl/barcodes/* emilda/perl/barcodes/Also copy/move over any other files/directories you may have in the old emilda dir that didn't come with the original tarball. If you have the Zebra database in the emilda-1.1 directory, move it to the new emilda directory. The MARC* files you copied over are only needed for the Upgrade part (setup.php) and can be safely removed after the upgrade.
Now point your Internet browser to http://your-old-emilda-address/setup.php and follow the on-screen instructions. After a successful setup your Emilda database will have been converted to the right version. Now you should edit config in the Emilda directory and remove everything except the MySQL section, as the rest is in the database now. Remember to disallow access to setup.php after completing the installation!
Note: MARC configuration has been moved to the database also but setup.php won't convert any changes you might have made to the old MARC_config file. After a successful upgrade you should log in to Emilda and modify MARC settings from the configuration panel if you made any changes to the old file.
To get languages working correctly, upgrade your locale linkage folders in the ./locale folder. You do this by going into the Emilda source folder and executing the following command:
sh bin/locales.shIn addition you need to compile the languages to support these. This is done by going into the source folder and executing the following command:
sh bin/compile_languages.sh
Upgrading Zebra is almost identical to when installing a new Emilda environment. To ensure that all files that have been updated are present on your system, we encourage you to download this tarball, and operate as follows.
- Move your existing zebra folder to another location, but be sure not to delete it yet as this would result in you loosing all your records.
- Extract the tarball to the same location where you had the old one, with the same name and same permissions.
- Copy your records folder (typically records/) from your old zebra folder. If you have made any custom changes to your Emilda instance, you probably are so familiar with Zebra that you will figure out which files you need to restore from your old folder to be able to use those changes. Just make sure that also the "new" issues released will be taken into consideration. Now you can theoretically delete your old zebra folder, but it might be a good idea to hold on to it until you are certain that everything works.
- Initialize and update your new Zebra instance by issuing the following set of commands:
- Go into the Zebra root folder: "cd /path/to/emilda/zebra/
- Init Zebra: "zebraidx init"
- Index the records/ folder: "zebraidx -g emilda update records"
- Commit results into shadow: "zebraidx commit"
- Start the zebrasrv-process: "zebrasrv -l /path/to/log @:9999"
As you might notice the syntax has slightly changed, so if you have any scripts or similar that run Zebra at startup it might be a good idea to make these compatible with the new system.
Always make a backup of your database before upgrading!
The easiest way to upgrade the Emilda source is probably to move the old directory to a backup location, install the new source from the tarball and copy over required files from the old installation. Here's an example:
mv emilda emilda-1.1 tar -zxf emilda-1.2-alpha.tar.gz mv emilda-1.2-alpha/src emilda cp emilda-1.1/config emilda/ cp -a emilda-1.1/perl/barcodes/* emilda/perl/barcodes/Also copy/move over any other files/directories you may have in the old emilda dir that didn't come with the original tarball. If you have the Zebra database in the emilda-1.1 directory, move it to the new emilda directory.
Now point your Internet browser to http://your-old-emilda-address/setup.php and follow the on-screen instructions. After a successful setup your Emilda database will have been converted to the right version. Now you should edit config in the Emilda directory and remove everything except the MySQL section, as the rest is in the database now. Remember to disallow access to setup.php after completing the installation!
Note: MARC configuration has been moved to the database also but setup.php won't convert any changes you might have made to the old MARC_config file. After a successful upgrade you should log in to Emilda and modify MARC settings from the configuration panel if you made any changes to the old file.
Upgrading Zebra is almost identical to when installing a new Emilda environment. To ensure that all files that have been updated are present on your system, we encourage you to download this tarball, and operate as follows.
- Move your existing zebra folder to another location, but be sure not to delete it yet as this would result in you loosing all your records.
- Extract the tarball to the same location where you had the old one, with the same name and same permissions.
- Copy your records folder (typically records/) from your old zebra folder. If you have made any custom changes to your Emilda instance, you probably are so familiar with Zebra that you will figure out which files you need to restore from your old folder to be able to use those changes. Just make sure that also the "new" issues released will be taken into consideration. Now you can theoretically delete your old zebra folder, but it might be a good idea to hold on to it until you are certain that everything works.
- Initialize and update your new Zebra instance by issuing the following set of commands:
- Go into the Zebra root folder: "cd /path/to/emilda/zebra/
- Init Zebra: "zebraidx init"
- Index the records/ folder: "zebraidx -g emilda update records"
- Commit results into shadow: "zebraidx commit"
- Start the zebrasrv-process: "zebrasrv -l /path/to/log @:9999"
As you might notice the syntax has slightly changed, so if you have any scripts or similar that run Zebra at startup it might be a good idea to make these compatible with the new system.
Always make a backup of your database before upgrading!
The easiest way to upgrade the Emilda source is probably to move the old directory to a backup location, install the new source from the tarball and copy over required files from the old installation. Here's an example:
mv emilda emilda-1.2-alpha tar -zxf emilda-1.2-beta.tar.gz mv emilda-1.2-alpha/src emilda cp emilda-1.2-alpha/config emilda/ cp -a emilda-1.2-alpha/perl/barcodes/* emilda/perl/barcodes/Also copy/move over any other files/directories you may have in the old emilda dir that didn't come with the original tarball. If you have the Zebra database in the emilda-1.1 directory, move it to the new emilda directory.
Now point your Internet browser to http://your-old-emilda-address/setup.php and follow the on-screen instructions. After a successful setup your Emilda database will have been converted to the right version. You may want to disallow access to setup.php after completing the installation, although, nothing harmful can be done with it after a successfull installation.
Always make a backup of your database before upgrading!
The easiest way to upgrade the Emilda source is probably to move the old directory to a backup location, install the new source from the tarball and copy over required files from the old installation. Here's an example:
mv emilda emilda-1.2-beta tar -zxf emilda-1.2-rc1.tar.gz mv emilda-1.2-rc1/src emilda cp emilda-1.2-beta/config emilda/ cp -a emilda-1.2-beta/perl/barcodes/* emilda/perl/barcodes/Also copy/move over any other files/directories you may have in the old emilda dir that didn't come with the original tarball. If you have the Zebra database in the emilda-1.1 directory, move it to the new emilda directory.
Move the config file to the conf directory (mv config conf/). Now point your Internet browser to http://your-old-emilda-address/setup.php and follow the on-screen instructions. After a successful setup your Emilda database will have been converted to the right version. You may want to disallow access to setup.php after completing the installation, although, nothing harmful can be done with it after a successfull installation.
To get languages working correctly, upgrade your locale linkage folders in the ./locale folder. You do this by going into the Emilda source folder and executing the following command:
sh bin/locales.shIn addition you need to compile the languages to support these. This is done by going into the source folder and executing the following command:
sh bin/compile_languages.sh
The Emilda 1.1 Administrators Guide is the Emilda manual for site administrators who wish to install and maintain an Emilda 1.1.x environment.
Emilda was built to work with the requirements above. There is however no good reason why it should not work on another platform with other backend applications, although this might require some changes to the Emilda source. Alternative set-ups have not been tested, but if You do succeed to set up Emilda on an other system, please let us know what Your system looks like and a few steps to reproduce.
Following these installation directives will give You a working Emilda environment on at least a Mandrake 9.1 machine, on which this file was written. These directives should, however, give ideas of what is compulsory for a successfull environment and as such give You an idea what to do also on other platforms.
- INSTALL A BASE SYSTEM. Mandrake 9.1 comes with Apache 2 and MySQL 4.0. If using an other platform, install Apache 1 or 2, favourably 2, but skip MySQL for now.
- INSTALL YAZ. (http://www.indexdata.dk/yaz/) Emilda 1.0 has only been tested using Yaz => 2.0.2, but should at least work with other Yaz 2.x-versions. Feel free to use Yaz 1.x-vesions at own risk. Build fron source if the favourable type to install, but if Your architecture has precompiled versions feel free to use these.
- INSTALL ZEBRA. (http://www.indexdata.dk/zebra/) Emilda 1.0 has only been tested using Zebra => 1.3.10, but should work using also other versions (except 1.3.14, see note below). Zebra should, stressing the word "should", be built from source. Special attributes to use when compiling Zebra is '--with-perl' since the Perl-API of Zebra is required by Emilda to manage Zebra from within the system. After making Zebra, go to the perl/ subfolder in the Zebra src-folder and install the perl library located there. Before making the source there, make sure that you edit the Makefile and search for "MakeMaker const_loadlibs section". A few lines under that string you should add in EXTRALIBS and LDLOADLIBS the -lexpat parameter before the -lxml2 parameter. Should look something like this: ... -L/usr/lib -lexpat -lxml2 ...
IMPORTANT NOTE!!
During QA it was noticed that version 1.3.14 of Zebra contains a bug that will break Emilda MARC management functions and should NOT be used with Emilda under any circumstances. In versions of Zebra prior to 1.3.14 the problem doesn't exist, and in version 1.3.15 this issue has been corrected. As such we encourage Emilda users to upgrade to version 1.3.15 or later of the Zebra server.- INSTALL SABLOTRON. (http://www.gingerall.com/charlie/ga/xml/p_sab.xml) Sablotron in itself has dependencies, which need to be satisfied, but of these only Expat (http://www.libexpat.org/) is required. The JavaScript extension is optional, since it is not required by Emilda 1.0.
- INSTALL MYSQL. (http://www.mysql.com) !! Emilda 1.0 requires MySQL => 4.1 !! If installing precompiled packages (e.g. rpm), be sure to install development & header files, so that PHP might include the appropriate header files.
- INSTALL GD The Emilda default layout generates its submenu inages with GD, and as such GD is needed in PHP. Each platform should have GD as a bundled package, but if You for some strange reason cannot find it, try building it from source.
- INSTALL PHP. (http://www.php.net) Emilda 1.0 has only been tested using PHP => 4.3.1 and is most certainly only going to work on 4.x-versions of PHP. As it, however many times has been proven, nothing is impossible; if You are of masochistic nature and find tweaking Your favourite waste of time, You might get it working using older versions of PHP. Additional to the configure parameters You choose to use, be sure to have the following:
--with-mysql
--enable-xslt
--with-xslt-sablot
--with-zlib
--with-yaz
--with-gdIf You choose to omit --with-apxs or Your architecture does not support apxs, be sure to configure Your Apache to utilize PHP.
These packages kan either be installed using the CPAN-shell in perl (perl -MCPAN -e shell) or by downloading separate source-files and compiling them individually. Dependencies of the following libraries are only valid on a "clean" Mandrake 9.1 install, and may vary greatly from case to case.
- Net::Z3950 (http://search.cpan.org/author/MIRK/Net-Z3950-0.35/)
Prerequisites:
- Event (http://search.cpan.org/author/JPRIT/Event-0.87/)
- MARC::Record (http://search.cpan.org/author/PETDANCE/MARC-Record-1.29/)
HTML::HTMLDoc (http://search.cpan.org/author/MFRANKL/HTML-HTMLDoc-0.06/)
Prerequisites:
- HTMLDOC (http://www.easysw.com/htmldoc) This is a program, not a perl library as it will become clear. This is a prerequisity to the perl htmldoc-API HTML::HTMLDoc, which is required by Emilda 1.0.
- GD::Barcode (http://search.cpan.org/author/KWITKNR/GD-Barcode-1.14/)
- DBD::MySQL (http://search.cpan.org/~rudy/DBD-mysql-2.9003/lib/DBD/mysql.pm)
The following steps need to be performed in the exact order they are given here, to prevent unwanted actions. (nothing disastrous can happen) If You are not totally sure about what You are doing, consider contacting someone who does, since doing something wrong might damage data in Your database.
- LOG INTO MYSQL Log into mysql using the "mysql"-tool. You have to have root access to the MySQL database.
COMMAND:
mysql --user=root --password='rootpass'
- CREATE DATABASE The next thing to do is create the Emilda database.
COMMAND:
create database emilda;
The name of the database can be anything, but if You change it from 'emilda' remember to change it in the configuration.
- GRANT PRIVILEGES After creating the database we want to grant privileges to the new database to some user, since we do not want Emilda to run with the root user.
COMMAND:
grant all privileges on emilda.* to emilda@localhost identified by 'password';
If You specified another database name than 'emilda' You need to alter the syntax here; change 'emilda' in 'emilda.*' to Your database name. Further, if You want another username than 'emilda' change the 'emilda' in emilda@localhost to Your alternative. Finally replace 'password' with the password You choose. Remember to update the configuration.
- EXIT MYSQL Leave the MySQL server.
COMMAND:
exit;
- CREATE TABLE-STRUCTURE What we want to do next is to fill the empty database with tables. To do this, You need to enter the sql/ directory in the Emilda root-folder. After this proceed followingly:
COMMAND:
mysql emilda --user=emilda --password='password' < emilda.sql
where the first argument after 'mysql' is the name of the database, the second the user, the third the password of the user.
It is imperative to have all folders correctly for the system to work. To assure that You have all folders in their correct places, follow the below instructions.
COPY THE SOURCE FOLDER You will want to have the Emilda-source, src/ folder in Your document-root. (e.g. /var/www/ or /var/www/html/) If You have dedicated the server entirely to Emilda and no other projects are to be run on the computer, You can copy the files directly into the document-root, otherwise it is wise to copy them into a subfolder. (e.g. /var/www/Emilda)
- ZEBRA FOLDER You need to have a Zebra root-folder somewhere on the server. This folder contains all Zebra configuration files and specifications. The location of this folder is uninteresting, since it can be configured in the "Zebra configuration"-section. Inside the zebra root-folder You need to have a subfolder containing MARC-records. Also the name of this folder is configurable. What however is important is that both the "zebrasrv"-process and apache have write access to the records folder.
After completing all the sections above it is time for fine-tuning.
- GENERATE MARC RULES We need to generate some MARC-rules so that Emilda knows e.g. what indicators are allowed in which subfields. For this we use the MARC-rules supplied with MARC::Lint. As these rules are updated with every release of MARC::Lint we do not supply these rules, but insted a script that will copy the rules from MARC::Lint to Emilda understandable. The is done followingly:
1. Go into the perl/ folder in the source folder (cd /path/to/source/perl/)
2. Run read_Lint.pl with the argument '../MARC_defs' (./read_Lint ../MARC_defs)
- CONFIGURE APACHE Emilda requires some configuration directives to be present in Apache to work correctly. You can configure it either as a virtual host or as a directory. See in the Sample Configurations-section for an example on a virtualhost/directory configuration. Restart Apache after modifying your configuration file.
- CONFIGURE EMILDA Last but not least You need to configure Emilda to suit Your system. This You can do by running './configure' in the Emilda source folder. Go through all sections to see if there is anything that is to be changed.
One account has been created automatically for the system administrator. Use it to create users and configure Emilda further, just remember to change the password! The login information for the admin account is:
username: admin
password: test
Hope this helps you on the way to get a working Emilda environment. If you experience difficulties, you can always ask via the Mailing lists.
This is a sample Directory for Apache. Do not use directly, but alter with the help of the description below.
<Directory /var/www/emilda> AddHandler cgi-script .cgi .pl php_value include_path .:lib AllowOverride All Options ExecCGI FollowSymLinks Order allow,deny Allow from all <Files "*.inc"> Order allow,deny Deny from all </Files> </Directory>
This is a sample VirtualHost for Apache. Do not use directly, but alter with the help of the description below.
<VirtualHost *> ServerName emilda.example.com ServerAdmin webmaster@example.com DocumentRoot /var/www/emilda AddHandler cgi-script .cgi .pl php_value include_path .:lib <Files "*.inc"> Order allow,deny Deny from all </Files> <Location "/"> AllowOverride All Options ExecCGI FollowSymLinks Order allow,deny Allow from all </Location> CustomLog logs/Emilda.log combined </VirtualHost>
<VirtualHost *>
Declares the beginning of the VirtualHost. Replace * with the IP of your server if you want Apache to specify this VirtualHost to only a specific IP. (Can be useful if your server is accessible via multiple IPs)
ServerName emilda.example.com
Declares the name of the VirtualHost, i.e. the domain name that Emilda will be accessed with. This domain must exist!
ServerAdmin webmaster@example.com
The email address of the person responsible for this VirtualHost. Will be visible if server fails.
DocumentRoot /var/www/emilda
The full path to the Emilda source folder
AddHandler cgi-script .cgi .pl
Allows execution of Perl/CGI scripts outside the cgi-bin-directory
php_value include_path .:lib
Declares a PHP-value defining the location of Emilda includes
<Files "*.inc">
Order allow,deny
Deny from all
</Files>
Deny access to all .inc filed via Apache for security reasons
<Location "/">
AllowOverride All
Options ExecCGI FollowSymLinks
Order allow,deny
Allow from all
</Location>
Allow the execution of Perl/CGI scripts in the Emilda source folder and sub-folders and deny listing of files.
CustomLog logs/Emilda.log combined
Specify Apache to separate the access log of this VirtualHost from the others. The path can be which ever, but be sure that apache has write access there
</VirtualHost>
End VirtualHost declaration
Below are some directives how to configure Zebra to comply with Emilda in an acceptable manner.
The first thing to be done is to decide where the Zebra folder is to be located. If you do not have any particularly good reason why not to put this folder as a subfolder of the Emilda source folder, we recommend that you put it as a subfolder of the Emilda source folder named zebra/.
What you need to put into this folder, is the sample USMARC configuration supplied with the Zebra source. If you feel familiar with the Zebra configuration you can of course customize this process. For more information on where to locate the USMARC configuration samples, please consult the README supplied with the Zebra source.
Now we have a working environment where the "zebrasrv"-process can live and work, but this is not enough for Emilda as Emilda uses attributes that are not defined in the default configuration supplied with Zebra. That is why we have supplied a tarball containing all the files that need to be replaced in Your Zebra root folder and it can be downloaded here. Unpack the tarball in some arbitraty location, and copy the files to their appropriate locations (see below).
Before starting Zebra, we need to create a folder where the MARC-records are to be stored. In our examples it is named records/ and it is located in the Zebra root folder (/path/to/emilda/zebra/records/). What is important with this folder is that both the Zebra process and Apache need to have write access to this folder. This can be achieved e.g. by running the "zebrasrv"-process as the Apache user and only giving the Apache user write access to records/, or then give write access to records/ to both Apache and the user running the "zebrasrv"-process. There is no favourable way to do this; both work just as well.
After deciding on which method to use, we are ready to prepare zebra for running; zebra needs to init and index the records/ folder before we start the process. If you have any records that you wish to import into Emilda, you need to copy these into the records/ folder before running these commands. (If you afterwards want to import MARC-recods, you copy them into the recods/ folder and run these commands.)
This should give you a working environment where there are no anomalies regarding Zebra and Emilda interaction at least.
NOTE!
If the records/ folder is empty, there will be an error of the type
Unsupported Use attribute: 7
which should not show up after the first record has been added. If it persists, there is something odd going on; try to check if you have done everything according to the above instructions, or send a note to the Emilda mailing list.
Here we will document the most basic API functions implemented in Emilda for You to use and modify. For all functions, You should best consult the source of Emilda.
The purpose of this book is to give insight into how the search API of Emilda works, and how it can help You design custom pages or help us make Emilda even better.
require_once "search.inc";
require_once "mgmnt.inc";
$search = new Search;
$search->init("localhost:9999/Default", "emilda", "abc123");
$ccl = $search->generate_ccl(array("100" => "Jansson",
"245" => "Mumin"));
$rpn = $search->ccl2rpn($rpn, generate_ccl_conf("localhost:9999/Default"));
$search->perform($rpn, "1=1004 ai");
if($this->hits()) {
while($record = $search->next(10)) {
... record manipulation ...
}
} else {
die "No hits";
}
The search class is the core of the search and retrieval process of records (thus data) in Emilda. The reason for making it in object form, is the ease of storing information related to the search or retrieval process at stake.
The class iself contains all vital information allowing the user to only use the object itself when performing the search without having to remember to pass connection id:s or similar.
This new class system also contains the call to the record class, so that the user using the search class does not have to instantiate the record object to be able to access the data; this is done by the search class and is such one step less to remember for the user before the data is available.
In contrast to the engine used in Emilda 1.1 and earlier, this new search class system supports simultaneous search statements within one connection; what this in practice implies is that the connection is instatiated at script start, and terminated at script end and unlimited search statements can be performed inbetween.
$search = new Search; $search->init() ... preform searches ... $search->terminate();
In addition, the record retrieval function itself verifies that the number of records desired is available, so that the user requesting the records does not have to separately verify the availability of records. This is one step colser to making the process of search and retrieval in Emilda both less error prone and optimized.
Below is an example of how an user can request records from the search class. In this case, the user wants 10 records, and will retrieve 10 if there are that many, otherwise the number of available records.
... instantiate and search ...
while($record = $search->next(10)) {
... use or manipulate record ...
}
... clean up ...
As we see, there is no real need to verify that there are any hits. This can however be useful when wanting to trap custom errors.
For more detailed description on the different methods, please see the Methods section
The logics itself has undergone an conciderable amount of testing and rethinking before reaching its current state. We think that this class system is a working entirety which is mature for real life implementation but at the same time open for suggestions and improvements.
The component that needs most attention in upcoming releases is the error handling. Currently the class contains an intrnal function called __raise_error() which is called every time there is a possibility of an error. This function will, at least by default not halt the search process, only inform the user that an error has occurred. This can in some cases result in the code to break, as the code might be designed so that it assumes that records are retrieved.
Below is an example how one can trap an error using the search class.
... instantiate ...
$search->perform($rpn);
if($search->errno()) {
die writeLog("Search error\n");
} else{
... process more ...
}
... terminate ...
As the above example illustrates, the __raise_error() function which is internally called within the search class informs the user of possible errors, and as such there is no need to generate custom errors, unless explicitly desired.
What needs to be done, is to make the search request "die" cleanly upon an error, so that even the calling code understands and exits with a clean error. Suggestions are more than welcome, as we have numerous alternatives of which none seems to fit our needs completely.
This section contains a more deatiled description on all the different methods contained within the search class.
mixed additional (string syntax)
Gives the user the possibility to retrieve the record in an additional format than the Emilda Record Model, e.g. Raw MARC, GRS array etc. This is particulary suitable for cases where the user wants to pass the raw MARC to some script or similar.
The argument passed is the format desired. To see which formats are present, please turn to the PHP/YAZ documentation.
Example of first extracting the Emilda Record and then the raw MARC data.
... Initialize and search ...
while($record = $search->next()) {
$raw = $search->additional("raw");
... process ...
}
string ccl2rpn (string query, array config)
This function will generate a RPN query of Your passed CCL query based on the config that You supply. The config can automatically be generated using the function generate_ccl_conf([string url]) or then alternatively be passed manually. To avoid errors and corrupt queries, we recommend using the generate_ccl_conf()-function.
The result of this function can directly be passed as the query argument to the perform() function. See examples below.
Example of generating an RPN-query of a passed CCL query.
... Initialize ...
$rpn = $search->ccl2rpn("title=mumin and author=jansson", generate_ccl_conf());
... End and clean ...
Will result in the following RPN query (example definitions, may vary from system to system).
@and @attr 5=3 @attr 1=1004 "mumin" @attr 5=3 @attr 1=4 "jansson"
Additionally and example of using the function to feed the perform() function.
... Initialize ...
$search->perform($search->ccl2rpn("title=mumin", generate_ccl_conf()), "1=4 ai")
if(!$search->errno()) {
... process ...
}
... End anc clean ...
int errno (void)
Returns the error code of the last error, and Null if no error is accessible.
Example of how to trap an error. It might be a good idea to use errno() to "see" if there is an error present.
... initialize and perform ...
if ($search->errno()) {
writeLog($search->error());
}
... terminate ...
string error (void)
Returns a formatted error string for either printing or storing to a log. This error is different depending if debugging has been turned on on the system. If debuging is on, the error is more descriptive with the exact explanation from YAZ accompanied with an error code, whereas it when debuging is turned off is only an error notice with the error code.
Example of how to trap an error
... initialize and perform ...
if ($search->errno()) {
custom_error_processor($search->error());
}
... end ...
There is no function called custom_error_processor(); it only represents some arbitrary function that can accept an error and process it meaningfully.
string generate_ccl (array array)
Generates a valid CCL query from the passed array. The idea of this function is to centralize the way Emilda processes CCL queries, so that it is easy to alter this logics.
generate_ccl() accepts an arbitrary key-value pair array, where it only processes the key-value pairs where the key is a valid MARC field. By valid we mean a field defined in the MARC-configuration section, not that it is according to some MARC standard. If there is more than one valid key-value pair, these are appended to each other with the logical "AND"-operator.
As such, if You have a form with fields which You want to search from, You only have to give $_REQUEST as the argument to generate valid and working CCL, assuming that the fields are named e.g. 020 for ISBN, or 100 for author.
Example of an array that will generate the example query.
Array (
"100" => "Jansson",
"245" => "Mumin",
)
Will generate the following query (with the example CCL-names from emilda)
author=Jansson and title=Mumin
int hits (void)
Returns the number of hits that the last search query returned, 0 if no search has been performed or there were no hits.
Example of checking using hits() before proceeding with processing.
... Initialize and perform ...
if($search->hits()) {
... process ...
}
... End ...
int id init (string host [, string user, string password])
Initialize the connection to the given host with the given parameters.
This method has to be called prior to any other method as it populates the object with the required information, and at the same time prepares PHP/YAZ for the upcoming search statements.
Simple example of initializing a connection to the local database without user information. As it can be seen, the default host is the local zebra server, so no server needs to be specified.
$search = new Search; $search->init(); ... perform searches ....
Example of initializing a connection to the Library of Congress, which needs no login information.
$search = new Search;
$search->init("z3950.loc.gov:7090/voyager");
... perform searches ...
Last an example of a connection to an arbitrary server with login information supplied.
$search = new Search;
$search->init("some.host.com", "username", "abc123");
... perform searches ...
Record next ([int count])
Wrapper method for retrieving the Record objects containing the data. The advantage of this function is that the user does not need to keep track of the records; next() will return records as long as there are records or alternatively until count records have been retrieved. For security issues, a hard-coded value of 10000 will be assigned to count unless a value is given.
Example of retrieving the first 10 records.
... initialize and search ...
while ($record = $search->next(10)) {
... process records ...
}
... clean up and end ...
Omitting the argument passed to next() will only return the first 10000 records, so if You suspect that there might be more hits (this is probably not very realistic) You have to pass the number of hits as an argument. The below example illustrates this.
... intilialize and search ...
while ($record = $search->next($search->hits())) {
... process records ...
}
... clean up and exit ...
int perform (string rpn [, string sort, int from, int how_many])
A function that will do all the numerous PHP/YAZ calls so that the next thing to do is only to retrieve the records.
Of the arguments only the rpn query is required, the others have predefined defaults. The rpn query can either be user specified or alternatively generated (e.g. using the ccl2rpn() method) but there is no check that the rpn query is valid, so an invalid query will result in failure.
The sort criteria can be used where desired, and if not specified, the result set will be sorted according to the system default, which varies. For more information on the syntax of the sort query, please consult more appropriate documentation sources, or the examples below.
Of the from and how_many arguments only from is the interesting one, as how_many can be overrid in the next() method. The from method is mainly interesting when wanting to start the retrieval from a certain position, e.g. when using a page index where only 10 hits are visible per page.
Example of an rpn-query; this query selects all items which have an author that contains "jansson"
@attr 1=1004 'jansson'
The first example is an sorting query that will sort according to title, ascending and case insensitive, and the second will first sort according to author then title, both ascending and case insensitive.
1=4 ai
1=1004 ai 1=4 ai
Example of a search request when we want to search for authors containing "jansson", sort the results according to author and title, and start from the 30th record.
... initialize ...
$search->perform("@attr 1=1004 jansson", "1=1004 ai 1=4 ai", 30);
while ($record = $search->next(10)) {
... manipulate ...
}
... end ...
void restart (void)
Restarts the record retrieval process. After calling restart() the next() functio will operate as were the records never retrieved.
An example of retrieving the first 10 records twice.
... initialize and search ...
while($record = $search->next(10)) {
... process ...
}
$search->restart();
while($record = $search->next(10)) {
... process more ...
}
... end and clean ...
int search_by_cn (string cn)
This is a wrapper function for the above functions enabling the searching for a control number using just one function. This function performs all tasks so that nothing else than the next() need to be called to be able to start the retreval of records. See examples below.
It is possible that similar wrapper functions will be written, but as control number is the most common search term (70% of cases excluding user instantiated searches) this was the most logical to implement.
Example of using the function
... Initialize ...
$search->search_by_cn("1234");
while($record = $search->next()) {
... process ...
}
... End ...
bool terminate (void)
Terminates the class and the connection before script end. If this is forgotten, no harm is done as PHP will clean up after script completion. If You however want to destroy the class, this is the method to use.
Example of how to destroy the class.
... instantiate and use class ... $search->terminate();
void __raise_error (void)
Internal function within the search class which handles all errors in the class.
If You want to change the way the search errors appear to the user, or want to customize these, this is the function to change, not error() or errno()
This method is not intended to be used externally from the calling code. For this purpose, see the methods error() and errno()
N/A
Example of an search using the control number as criteria. This is possibly the most useful example as searching for by the control number of an item is one of the most common searches in the Emilda code.
require_once "mgmnt.inc";
require_once "search.inc";
$search = new Search;
$search->search_by_cn("1234");
if (!$search->errno()) {
while($record = $search->next(10)) {
print $record->ffield("020", "This book has the ISBN number '%a'\n");
}
} else {
die "Failed!";
}
$search->terminate();
More complicated search using more details in the API
require_once "mgmnt.inc";
require_once "search.inc";
$search = new Search;
$ccl = $search->generate_ccl(array("100" => "Jansson"));
$rpn = $search->ccl2rpn($ccl, generate_ccl_conf());
$search->perform($rpn, "1=4 ai");
if (!$search->errno()) {
while($record = $search->next(10)) {
print $record->ffield("020", "This book has the ISBN number '%a'\n");
printf("Raw MARC: %s\n", $search->additional("raw"));
}
} else {
die "Failed!";
}
$search->terminate();
The Emilda Search API was first introduced in Emilda 1.2-alpha and is thus rather new and fresh. What this implies is that cosmetic changes and additions to the functionality is are very likely, whereas the main functionality and logics prbably will remain unchanged.
Due to the fact that the API has not been largely tested, it would be great if some of testers interested in customizing and maybe coding would take a standpoint in how well the API works and if something need to be changed, then what.
Christoffer Landtman ( emilda.org account )
Copyright © 2003-2004 Oy Realnode Ab
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
The Emilda FAQ contains frequently asked questions about Emilda, the installation and related issues.
To ensure the base for understanding the importing and thus handling of MARC records within Emilda, some basic concepts have to be clarified.
1. MARC information resides within the Zebra server in Emilda. This directly implies that no bibliographic data exists in MySQL.
2. For administrative purposes, administrative data of items is stored in MySQL. Such administrative data is e.g. the Item Type of this particular item, the Control Number that links the item to the MARC record in Zebra etc.
Importing data, i.e. not using the Z39.50 searching or manual adding within Emilda, can be split up into subsections as follows.
1. What MARC fields are required for Emilda to be able to import records?
The only compulsory field that Emilda requires is the field 001 - Control field, (see q2). It is of course rather useless to add Items that do not contain any data, as they are virtually imposible to access.
Just as in importing records from an Z39.50-server, You can supply "any" information within the MARC record to Emilda, and it will use the information that it has been configured to do (the MARC configuration section). So if You only have field 100 configured within Emilda, You might only supply that field in the generated Titles, but if You maybe later would like to change the setup of fields, it is a good idea so add all information present into the records so that when needed the information can be accessed.
2. Are there any MARC fields or field values (for instance, "001") that I should avoid converting so that there will not be any conflicts with existing Emilda records?
Emilda uses an incrementing number as the control number - 001 to link the "Items" in the MySQL database together with the MARC records. There is no direct need to give the imported fields a control number according to the Emilda-type of control numbers, but it would be safer in case the Records at a later stage will be edited within Emilda.
In the table "control" within the Emilda MySQL database, there is a row called, "last_control_number" which represents the last added control number. This You can use when generating the records to get the last record. The control number is of the type 0000000001, where the total length is "CONTROL_NUMBER_LENGTH" (from the control panel), and the "1" is a actual id, and the zeros are just padded to achieve the length. The zeros are compulsory for indexing purposes.
3. How must I put these Titles into the Zebra records directory? Should they be one file per title? All 400 titles in one file? What should I name the file(s) so that there is no conflict with the existing Emilda Zebra records?
The file naming has to be done according to the control number. What this implies that each record has to be a single file, with the file name identical to the control number of that record. When You list the files in the Zebra records folder, You will see files named of the type 0000000001. When creating these records, remember to give the correct file permissions to avoid errors, i.e. the apache user has to have write access to these files.
4. How must I set up the corresponding data in MySQL?
Each Record has at least one Item attached to it, for the system to be sane. This means that You can have "Records" in Zebra, but without a linkage to this record in the MySQL database the records is worthless. The table structure of the books table is as follows:
+---------------------+----------------------+------+-----+------------+----------------+ | Field | Type | Null | Key | Default | Extra | +---------------------+----------------------+------+-----+------------+----------------+ | book_id | int(10) unsigned | | PRI | NULL | auto_increment | | book_control_number | varchar(255) | | MUL | | | | book_date_added | date | | | 0000-00-00 | | | book_date_deleted | date | | | 0000-00-00 | | | book_borrowed | tinyint(1) | | MUL | 0 | | | book_reserved | tinyint(1) | | | 0 | | | book_deleted | tinyint(1) | | MUL | 0 | | | book_borrow_count | smallint(5) unsigned | | | 0 | | | book_location | tinyint(3) unsigned | | | 0 | | | book_item_type | varchar(255) | | | | | +---------------------+----------------------+------+-----+------------+----------------+
where the important fields are:
book_control_number: The control number of the record that this particular item is linked to
book_location: the location of the item, i.e. in which library instance it exists
book_item_type: the type of item it is. (check item_types table for reference)
This set of information should be enough to get any system up and running.
We have noticed that compiling Zebra so that the Perl libraries get compiled correctly is quite tricky business. However, David experimented on this and found an order in which things should be done to achieve a sane system. Below is the findings of this mail. In case You are experiencing problems compiling Zebra correctly, it is adviseable to follow these steps.
First, I needed these package on my Debian system before it would build properly: automake1.4, tcl8.3-dev, libncurses5-dev, libexpat1-dev, libyaz-dev (>= 2.0.2), libssl-dev, libbz2-dev, autoconf2.13, libperl-dev Also, I found it is very important to do things in order: 1. ./configure
2. make
3. cd perl
4. perl Makefile.PL
5. make
6. cd ..
7. make install
8. cd perl
9. make install
The login (index) page for Emilda 1.2 looks for a file called .setup in the Emilda directory. If that file is not writeable by the web server user (usually apache or www-data) Emilda setup cannot update it, therefore prompting to run setup everytime the login page is loaded. To fix this run the following commands in the Emilda directory:
touch .setup chmod 666 .setup
The next time you enter setup, the file should be updated correctly.