Skip to content
jsotuyod edited this page Jun 5, 2012 · 26 revisions

Most often, once you have decided on what your database schema should look like you end up writing lots of repetitive code. The models themselves, their builders, tables, CRUD controllers and such are all pretty repetitive, based on the database design.

To speed-up development, we have created zxa (ZendExt Automator), a small cli tool that allows you to autogenerate code in a simple and speedy way.

To achieve this, zxa delegates on Generator classes for each specific task, providing a general framework to enhance code reuse. These generators make extensive use of Zend's classes for code generation.

zxa is located under src/main/php/Tools/Tool.

Right now zxa has no interactive mode, though we are certainly considering it.

Running zxa will display the help.

zxa

Required arguments

  • generator(g): Which generator to use. zxa will automatically detect any generators located under ZendExt/Tool/Generator and list it as a valid option, so installing new and custom generators is really easy.
  • outputDir(o): The dir where to place the generated files. If not existing, it will be created recursively.

DB access arguments

zxa does not require generators to base their work on the database, though currently all of them do. However, it offers generators a simple and consistent way of requiring these arguments for ease of use. Such arguments are:

  • host(h): The database server host, defaults to localhost.
  • dbname(D): The name of the database to use.
  • username(u): Connect to the database as this user.
  • password(p): The password for the database user.
  • adapter(a): Which Zend_Db adapter to use. Will be loaded through Autoloading, make sure it's in the include_path.
  • table(t): The name of the table for which to apply the generator (all by default).

Generator-specific arguments

Other arguments, both required and optional are entirely up to the generator itself, though some are quite pervasive, such as info for javadocs on @author, @copyright and @link among others.

You can check out the complete list of arguments for any generator by executing:

zxa --help generator

It is important to know that the generator options are case sensitive, so it is necessary to type the keywords exacly as the example.

Example

Let's assume we have this table in the database 'testing':

CREATE TABLE user (
    id int not null primary key auto_increment,
    name varchar(255) collate utf8_bin null default null,
    email varchar(100) collate utf8_bin not null,
);

Let's autogenerate a model for this table under the TestProject/Model/ folder.

zxa -D testing -u dbuser -p dbpassword -a pdo_mysql -c Monits -l http://www.monits.com/ -e [email protected] -n TestProject_Model -o ~/workspace/project/src/main/php -g Model -t user

This will generate a TestProject_Model_User table in ~/workspace/project/src/main/php/TestProject/Model/User.php with a constructor working for both an array and a Zend_Db_Table_Row object, with getters for each property, all fully documented with javadoc, setting my email for the author, and setting Monits as the company responsible for this class and linking to it's website.

To generate the Zend_Db_Table object we simply do:

zxa -D testing -u dbuser -p dbpassword -a pdo_mysql -c Monits -l http://www.monits.com/ -e [email protected] -n TestProject_Table -o ~/workspace/project/src/main/php -g Table -t user

A TestProject_Table_User class will be created, extending Zend_Db_Table_Abstract, with the proper name for the table and primary key.

Next we can create a builder for our TestProject_Model_User class, that will perform all validations and set all defaults just as we defined on our database.

zxa -D testing -u dbuser -p dbpassword -a pdo_mysql -c Monits -l http://www.monits.com/ -e [email protected] -n Project_Model_Builder --modelnamespace Project_Model -o ~/workspace/project/src/main/php -g Model -t user

This time we need to tell the generator in which package do models live. It will assume models are using the same naming convention used by the model generator, using the table's name. Each value will have any default set on the database (whichever that may be), and apply any validations to make sure the data will be valid on the database (checking for not null, length, to be within a valid set of values, within a range or whatever seems fit). To do so this generator makes heavy use of ZendExt_Db_Schema, which in turn depends on ZendExt_Db_Schema_TypeMappingAdapter_Generic to map db types to sensible values in php and sets the minimum and maximum values for each numeric type. These defaults are good for most cases, and in special for MySQL, however they may not be complete nor proper for other RDBMs. Feel free to extend it for specific databases and send your pull requests to help us increase the scope of this tool.

Finally, we may auto-generate a CRUD controller just as easily.

zxa -D testing -u dbuser -p dbpassword -a pdo_mysql -c Monits -l http://www.monits.com/ -e [email protected] -n Project_Model_Builder --modelnamespace Project_Model -o ~/workspace/project/src/main/php -g CRUD -t user -j Project_Table_User

The CRUD controller makes use of the model as placeholder for all values and of the builder, delegating all validations on to it. It requires the table object to perform all operations on the database. The CRUD generator is also compatible with ZendExt_Db_Dao_Abstract.

Bare in mind the current incarnation of CRUD controller doesn't deal particularly gracefully with foreign keys (you will be required to enter the foreign value manually and no checks will be performed up until the insert / update / delete is attempted on the database / table object itself). We are analyzing a couple alternatives for this, but are currently too green and not on our immediate roadmap.

Conclusion

Having executed all these fours generators, we have a fully functional CRUD for our user's, with a model we can use through our application, a builder with extensive checks on the data's validity and the table required in just a couple minutes. Moreover, had we skipped the -t user argument on all four calls, we would have these classes for each table on the database, for free, in just a few minutes. The speed-up and ease of use are really evident.

Clone this wiki locally