Metastorage troubleshooting guide
Author: Manuel Lemos (mlemos-at-acm.org)
Version control: @(#) $Id: troubleshooting.documentation,v 1.10 2007/11/19 03:47:22 mlemos Exp $
This guide is meant to help users understanding and solving problems that they may find when they try to use Metastorage.
If you are having a problem using Metastorage that is not addressed in this document, please post your problem in the MetaL development mailing list. To access this mailing list via the Web you need to have a free Yahoo account.
If you do not want to create an Yahoo account, you can have access by e-mail only subscribing to the mailing list by sending a message to firstname.lastname@example.org. You will receive a message with instructions to confirm the subscription before you can post to the mailing list.
If you are a Portuguese speaker, you may also obtain support in the Metastorage support mailing list for Portuguese speakers. You may also subscribe by e-mail sending a message to email@example.com.
If the metastorage command exits with an error message like could not find class file metal_compiler.php in directory /some/path/metal, this means that the standard MetaL distribution is not installed in the parent directory of the Metastorage installation path.
Please check the section of Metastorage tutorial about its installation to learn how to correctly install the MetaL distribution for use with Metastorage.
Metastorage needs to be executed by PHP in normal mode. Safe mode prevents PHP scripts to run for longer than the default time limit. It also disallows the creation a files, preventing Metastorage to generate the projects files.
To disable PHP safe mode, just edit its php.ini configuration file and make sure the safe mode option line is set like this:
safe_mode = Off
If for some reason you are not able to locate your system php.ini file or you are not able to change it, when you run PHP from the command line you can use a new php.ini file with the safe mode and other settings. You can make PHP use the new php.ini file instead of the default using the -c switch like this:
/path/to/php -c /my/php.ini -q -C /path/to/metastorage my.component
To run the metastorage command when it is executed from a directory different than Metastorage installation directory, you need to specify the -C switch to the PHP command to tell it to not change the current directory to metastorage command path.
/path/to/php -q -C /path/to/metastorage my.component
The default memory limit used on each invocation of a PHP script is of 8MB. Usually this is insufficient to run Metastorage compiler. 32MB is often enough to compile most components. However, if you use PHP optimizer extensions like Zend Optimizer, you may need to increase to 256MB or disable these extensions when you run Metastorage.
To increase the PHP memory limit, just edit its php.ini configuration file and make sure the memory limit option is set to an higher value like this:
memory_limit = 32M
Some PHP debugging extensions like Xdebug are capable of watching the running scripts and prevent that they enter in infinite function call recursion loops. This is done by stopping the current script when it exceeds a given limit of recursive function calls.
The MetaL compiler engine often calls functions that end up calling themselves to process nested language structures. Although this is the normal behavior of the MetaL engine, it may exceed the function call nesting level limit and abort Metastorage execution.
To avoid this problem, the allowed nesting level limit needs to be increased. If you are using the Xdebug PHP extension, you can increase the nesting level limit by setting the respective configuration option in the php.ini like this:
xdebug.max_nesting_level = 1000
Retrieving objects of an external component must be done using the factory class or the data classes of that component.
Retrieving an object pointed by a reference variable of an external component class can be done using first a getreference function defined with the oid parameter to tell it to return the external object identifier.
<class> <name>article</name> <variable> <name>author</name> <class>user</class> <component>accounts</component> </variable> <function> <name>getauthoroid</name> <type>getreference</type> <parameters> <variable>author</variable> <oid /> </parameters> </function> </class>
Then use the a getobject type function of the external component factory class to retrieve object using its OID.
<component> <name>accounts</name> ... <factory> <function> <name>getuserbyoid</name> <type>getobject</type> <parameters> <class>user</class> <id> <argument>user_oid</argument> </id> </parameters> </function> </factory> </component>
Metastorage does not yet support cloning objects with variables of type largedata.
Large data variable values maybe copied or not, depending on the purpose of the applications that need to clone objects.
For now, if you need to clone an object of a class with large data variables, it is recommended that you create a new object of that class and assign each of the new object variables individually.
If you need to also copy the large data variables, you need to explicitly retrieve the large data values from the original object into a string variable or to a file, and then store the data in the new object.
Report queries can only return scalar values. Therefore report queries cannot return object instances.
If you need to retrieve an object or an object reference variable, you must specify that you want to retrieve the object identifier using the oid tag in the report query column expression, like this:
<column> <name>column_name</name> <value><variable> <object>object_name</object> <name>reference_variable_name</name> <oid /> </variable></value> </column>
When a setreference type function is called, it stores the OID of the reference object passed as argument to the function if it is not a null object reference. However, the if the reference object was just created and was not yet saved, its OID is not yet determined and so the setreference type function fails with the error above.
When this happens, it means that the calling application must be fixed to invoke the persist type function of the reference object before calling the setreference type function.
By default, all class variables are required and so they have to be initialized. Otherwise, the class persist type function fails with the above error message.
If the class variable was not really meant to always be required, it must be defined as optional. If the variable is always required it must be initialized before calling the class persist type function.
Certain database types, like MySQL, can only implement transactions with table types that support them.
The MySQL Metabase driver used by the Metastorage generated code, assumes that the default table type is MYISAM. However, MYISAM tables do not support transactions.
Transaction support can be enabled using another table type like INNODB. You also need to configure the MySQL Metabase to explicitly support transactions. That can be done using a connection string like these:
If you have not used a connection string that determines the use of transactional tables when the database schema was created, you can change the type of a MySQL table, for instance to INNODB, executing an SQL query like this:
ALTER TABLE name_of_the_table TYPE=INNODB