Doctrine Object Relational Mapper

jwage - February 10, 2008 - 02:25

Module which bootstraps Doctrine in to Drupal so you can build new modules using Doctrine.

The module requires Doctrine libs to be present, however the Doctrine is under the LGPL license so it cannot be included in CVS. You will have to do a svn export/co of Doctrine after installing the module. Below is an outline of the steps you can take to get started with Doctrine in Drupal.

Getting Started

Download and install the Doctrine Drupal module. Once installed perform the following commands.

// Check out doctrine libs
$ cd drupal/modules/doctrine/lib
$ svn export http://svn.phpdoctrine.org/branches/0.9/lib doctrine

// Make doctrine shell script executable for the command line to work
$ cd ..
$ chmod 0755 doctrine
$ ./doctrine
Doctrine Command Line Interface

./doctrine build-all
./doctrine build-all-load
./doctrine build-all-reload
./doctrine compile
./doctrine create-db
./doctrine create-tables
./doctrine dql
./doctrine drop-db
./doctrine dump-data
./doctrine generate-migration
./doctrine generate-migrations-db
./doctrine generate-migrations-models
./doctrine generate-models-db
./doctrine generate-models-yaml
./doctrine generate-sql
./doctrine generate-yaml-db
./doctrine generate-yaml-models
./doctrine load-data
./doctrine load-dummy-data
./doctrine migrate
./doctrine rebuild-db

Writing Schema Files

Below is the schema for the users, users_roles, and roles table. It will provide you with the following methods and relationships.

- User hasMany Roles through UserRole
- User hasMany UserRole
- Role hasMany Users through UserRole
- Role hasMany UserRole
- UserRole hasOne User
- UserRole hasOne Role

Copy the yaml below in to drupal/modules/doctrine/schemas/user.yml

User:
  tableName: users
  columns:
    uid:
      unsigned: 1
      primary: true
      notnull: true
      type: integer(4)
    name:
      notnull: true
      type: string(60)
    pass:
      notnull: true
      type: string(32)
    mail:
      notnull: false
      type: string(64)
    mode:
      default: 0
      notnull: true
      type: integer(1)
    sort:
      default: 0
      notnull: false
      type: integer(1)
    threshold:
      default: 0
      notnull: false
      type: integer(1)
    theme:
      notnull: true
      type: string(255)
    signature:
      notnull: true
      type: string(255)
    created:
      default: 0
      notnull: true
      type: integer(4)
    access:
      default: 0
      notnull: true
      type: integer(4)
    login:
      default: 0
      notnull: true
      type: integer(4)
    status:
      default: 0
      notnull: true
      type: integer(1)
    timezone:
      notnull: false
      type: string(8)
    language:
      notnull: true
      type: string(12)
    picture:
      notnull: true
      type: string(255)
    init:
      notnull: false
      type: string(64)
    data:
      notnull: false
      type: clob
  relations:
    Roles:
      class: Role
      refClass: UserRole
      local: uid
      foreign: rid
      foreignAlias: Users

UserRole:
  tableName: users_roles
  columns:
    uid:
      unsigned: 1
      primary: true
      default: 0
      notnull: true
      type: integer(4)
    rid:
      unsigned: 1
      primary: true
      default: 0
      notnull: true
      type: integer(4)
  relations:
    User:
      local: uid
      foreign: uid
    Role:
      local: rid
      foreign: rid

Role:
  columns:
    rid:
      unsigned: 1
      primary: true
      notnull: true
      autoincrement: true
      type: integer(4)
    name:
      notnull: true
      type: string(64)

Now run the following command from the doctrine command line interface:

$ ./doctrine generate-models-yaml
generate-models-yaml - Generated models successfully from YAML schema

Now if you take a look in the models folders, you will some classes which extends from Doctrine_Record that were generated from the yaml schema files. If you have some users in your system run this at the command line to test a DQL query.

$ ./doctrine dql "FROM User u, u.Roles r"
dql - executing: "FROM User u, u.Roles r" ()
dql -   uid: 1
dql -   name: jwage
dql -   pass: ac5416aec3ad1840f3e02f8efee00a83
dql -   mail: jonwage@gmail.com
dql -   mode: 0
dql -   sort: 0
dql -   threshold: 0
dql -   theme:
dql -   signature:
dql -   created: 1202609752
dql -   access: 1202619641
dql -   login: 0
dql -   status: 1
dql -   timezone: 0
dql -   language:
dql -   picture:
dql -   init: jonwage@gmail.com
dql -   data: a:1:{s:7:"contact";i:0;}
dql -   Roles:
dql -     -
dql -       rid: 3
dql -       name: test

You can begin using Doctrine in your modules like the following

$user = new User();
$user->name = 'jwage';
$user->pass = 'changeme';

$role = Doctrine::getTable('Role')->findOneByName('test');
$user->Roles[] = $role

$user->save();

// This is slower than this
$user = Doctrine::getTable('User')->findOneByName('jwage');
$roles = $user->Roles; // Invokes additional query

// This
$query = new Doctrine_Query();
$query->from('User u, u.Roles u')->
              where('u.name = ?', 'jwage')->
              limit(1);

$user = $query->execute();
$roles = $user->getRoles(); // Does not invoke another query because the data was hydrated from the original Query data.

echo $user->name;

foreach ($roles as $rule)
{
  echo $role->name;
}

Data Fixtures

Data fixtures allow you to define data as yaml files and you can load the data from the command line.

---
User:
  jwage:
    uid: 2
    name: jonwage
    pass: changeme
    theme: theme
    language: en
    picture: picture
    signature: signature
    Roles: [Role1, Role2]

Role:
  Role1:
    name: Sample Role 3
  Role2:
    name: Sample Role 4

Now you can load the data from the command line.

$ ./doctrine load-data
load-data - Data was successfully loaded

Releases

Development snapshotsDateSizeLinksStatus
5.x-1.x-dev2008-Feb-1018.78 KBDevelopment snapshotDevelopment snapshots are automatically regenerated and their contents can frequently change, so they are not recommended for production use.
 
 

Drupal is a registered trademark of Dries Buytaert.