root/branches/0.11/lib/Doctrine.php

Revision 4527, 31.7 KB (checked in by guilhermeblanco, 7 months ago)

Fixed #1140 referring to source documentation mistakes

  • Property svn:keywords set to Id Revision
Line 
1<?php
2/*
3 *  $Id$
4 *
5 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
6 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
7 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
8 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
9 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
10 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
11 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
12 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
13 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
14 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
15 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16 *
17 * This software consists of voluntary contributions made by many individuals
18 * and is licensed under the LGPL. For more information, see
19 * <http://www.phpdoctrine.org>.
20 */
21
22/**
23 * Doctrine
24 * the base class of Doctrine framework
25 *
26 * @package     Doctrine
27 * @author      Konsta Vesterinen <kvesteri@cc.hut.fi>
28 * @author      Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
29 * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
30 * @link        www.phpdoctrine.org
31 * @since       1.0
32 * @version     $Revision$
33 */
34final class Doctrine
35{
36    /**
37     * VERSION
38     */
39    const VERSION                   = '0.11.0';
40
41    /**
42     * ERROR CONSTANTS
43     */
44    const ERR                       = -1;
45    const ERR_SYNTAX                = -2;
46    const ERR_CONSTRAINT            = -3;
47    const ERR_NOT_FOUND             = -4;
48    const ERR_ALREADY_EXISTS        = -5;
49    const ERR_UNSUPPORTED           = -6;
50    const ERR_MISMATCH              = -7;
51    const ERR_INVALID               = -8;
52    const ERR_NOT_CAPABLE           = -9;
53    const ERR_TRUNCATED             = -10;
54    const ERR_INVALID_NUMBER        = -11;
55    const ERR_INVALID_DATE          = -12;
56    const ERR_DIVZERO               = -13;
57    const ERR_NODBSELECTED          = -14;
58    const ERR_CANNOT_CREATE         = -15;
59    const ERR_CANNOT_DELETE         = -16;
60    const ERR_CANNOT_DROP           = -17;
61    const ERR_NOSUCHTABLE           = -18;
62    const ERR_NOSUCHFIELD           = -19;
63    const ERR_NEED_MORE_DATA        = -20;
64    const ERR_NOT_LOCKED            = -21;
65    const ERR_VALUE_COUNT_ON_ROW    = -22;
66    const ERR_INVALID_DSN           = -23;
67    const ERR_CONNECT_FAILED        = -24;
68    const ERR_EXTENSION_NOT_FOUND   = -25;
69    const ERR_NOSUCHDB              = -26;
70    const ERR_ACCESS_VIOLATION      = -27;
71    const ERR_CANNOT_REPLACE        = -28;
72    const ERR_CONSTRAINT_NOT_NULL   = -29;
73    const ERR_DEADLOCK              = -30;
74    const ERR_CANNOT_ALTER          = -31;
75    const ERR_MANAGER               = -32;
76    const ERR_MANAGER_PARSE         = -33;
77    const ERR_LOADMODULE            = -34;
78    const ERR_INSUFFICIENT_DATA     = -35;
79    const ERR_CLASS_NAME            = -36;
80
81    /**
82     * PDO derived constants
83     */
84    const CASE_LOWER = 2;
85    const CASE_NATURAL = 0;
86    const CASE_UPPER = 1;
87    const CURSOR_FWDONLY = 0;
88    const CURSOR_SCROLL = 1;
89    const ERRMODE_EXCEPTION = 2;
90    const ERRMODE_SILENT = 0;
91    const ERRMODE_WARNING = 1;
92    const FETCH_ASSOC = 2;
93    const FETCH_BOTH = 4;
94    const FETCH_BOUND = 6;
95    const FETCH_CLASS = 8;
96    const FETCH_CLASSTYPE = 262144;
97    const FETCH_COLUMN = 7;
98    const FETCH_FUNC = 10;
99    const FETCH_GROUP = 65536;
100    const FETCH_INTO = 9;
101    const FETCH_LAZY = 1;
102    const FETCH_NAMED = 11;
103    const FETCH_NUM = 3;
104    const FETCH_OBJ = 5;
105    const FETCH_ORI_ABS = 4;
106    const FETCH_ORI_FIRST = 2;
107    const FETCH_ORI_LAST = 3;
108    const FETCH_ORI_NEXT = 0;
109    const FETCH_ORI_PRIOR = 1;
110    const FETCH_ORI_REL = 5;
111    const FETCH_SERIALIZE = 524288;
112    const FETCH_UNIQUE = 196608;
113    const NULL_EMPTY_STRING = 1;
114    const NULL_NATURAL = 0;
115    const NULL_TO_STRING         = NULL;
116    const PARAM_BOOL = 5;
117    const PARAM_INPUT_OUTPUT = -2147483648;
118    const PARAM_INT = 1;
119    const PARAM_LOB = 3;
120    const PARAM_NULL = 0;
121    const PARAM_STMT = 4;
122    const PARAM_STR = 2;
123
124    /**
125     * ATTRIBUTE CONSTANTS
126     */
127
128    /**
129     * PDO derived attributes
130     */
131    const ATTR_AUTOCOMMIT           = 0;
132    const ATTR_PREFETCH             = 1;
133    const ATTR_TIMEOUT              = 2;
134    const ATTR_ERRMODE              = 3;
135    const ATTR_SERVER_VERSION       = 4;
136    const ATTR_CLIENT_VERSION       = 5;
137    const ATTR_SERVER_INFO          = 6;
138    const ATTR_CONNECTION_STATUS    = 7;
139    const ATTR_CASE                 = 8;
140    const ATTR_CURSOR_NAME          = 9;
141    const ATTR_CURSOR               = 10;
142    const ATTR_ORACLE_NULLS         = 11;
143    const ATTR_PERSISTENT           = 12;
144    const ATTR_STATEMENT_CLASS      = 13;
145    const ATTR_FETCH_TABLE_NAMES    = 14;
146    const ATTR_FETCH_CATALOG_NAMES  = 15;
147    const ATTR_DRIVER_NAME          = 16;
148    const ATTR_STRINGIFY_FETCHES    = 17;
149    const ATTR_MAX_COLUMN_LEN       = 18;
150
151    /**
152     * Doctrine constants
153     */
154    const ATTR_LISTENER             = 100;
155    const ATTR_QUOTE_IDENTIFIER     = 101;
156    const ATTR_FIELD_CASE           = 102;
157    const ATTR_IDXNAME_FORMAT       = 103;
158    const ATTR_SEQNAME_FORMAT       = 104;
159    const ATTR_SEQCOL_NAME          = 105;
160    const ATTR_CMPNAME_FORMAT       = 118;
161    const ATTR_DBNAME_FORMAT        = 117;
162    const ATTR_TBLCLASS_FORMAT      = 119;
163    const ATTR_TBLNAME_FORMAT       = 120;
164    const ATTR_EXPORT               = 140;
165    const ATTR_DECIMAL_PLACES       = 141;
166
167    const ATTR_PORTABILITY          = 106;
168    const ATTR_VALIDATE             = 107;
169    const ATTR_COLL_KEY             = 108;
170    const ATTR_QUERY_LIMIT          = 109;
171    const ATTR_DEFAULT_TABLE_TYPE   = 112;
172    const ATTR_DEF_TEXT_LENGTH      = 113;
173    const ATTR_DEF_VARCHAR_LENGTH   = 114;
174    const ATTR_DEF_TABLESPACE       = 115;
175    const ATTR_EMULATE_DATABASE     = 116;
176    const ATTR_USE_NATIVE_ENUM      = 117;
177    const ATTR_DEFAULT_SEQUENCE     = 133;
178
179    const ATTR_FETCHMODE                = 118;
180    const ATTR_NAME_PREFIX              = 121;
181    const ATTR_CREATE_TABLES            = 122;
182    const ATTR_COLL_LIMIT               = 123;
183
184    const ATTR_CACHE                    = 150;
185    const ATTR_RESULT_CACHE             = 150;
186    const ATTR_CACHE_LIFESPAN           = 151;
187    const ATTR_RESULT_CACHE_LIFESPAN    = 151;
188    const ATTR_LOAD_REFERENCES          = 153;
189    const ATTR_RECORD_LISTENER          = 154;
190    const ATTR_THROW_EXCEPTIONS         = 155;
191    const ATTR_DEFAULT_PARAM_NAMESPACE  = 156;
192    const ATTR_QUERY_CACHE              = 157;
193    const ATTR_QUERY_CACHE_LIFESPAN     = 158;
194    const ATTR_AUTOLOAD_TABLE_CLASSES   = 160;
195    const ATTR_MODEL_LOADING            = 161;
196    const ATTR_RECURSIVE_MERGE_FIXTURES = 162;
197    const ATTR_SINGULARIZE_IMPORT       = 163;
198    const ATTR_USE_DQL_CALLBACKS        = 164;
199
200    /**
201     * LIMIT CONSTANTS
202     */
203
204    /**
205     * constant for row limiting
206     */
207    const LIMIT_ROWS       = 1;
208    const QUERY_LIMIT_ROWS = 1;
209
210    /**
211     * constant for record limiting
212     */
213    const LIMIT_RECORDS       = 2;
214    const QUERY_LIMIT_RECORDS = 2;
215
216    /**
217     * FETCHMODE CONSTANTS
218     */
219
220    /**
221     * IMMEDIATE FETCHING
222     * mode for immediate fetching
223     */
224    const FETCH_IMMEDIATE       = 0;
225
226    /**
227     * BATCH FETCHING
228     * mode for batch fetching
229     */
230    const FETCH_BATCH           = 1;
231
232    /**
233     * LAZY FETCHING
234     * mode for offset fetching
235     */
236    const FETCH_OFFSET          = 3;
237
238    /**
239     * LAZY OFFSET FETCHING
240     * mode for lazy offset fetching
241     */
242    const FETCH_LAZY_OFFSET     = 4;
243
244    /**
245     * FETCH CONSTANTS
246     */
247
248
249    /**
250     * FETCH VALUEHOLDER
251     */
252    const FETCH_VHOLDER         = 1;
253
254    /**
255     * FETCH RECORD
256     *
257     * Specifies that the fetch method shall return Doctrine_Record
258     * objects as the elements of the result set.
259     *
260     * This is the default fetchmode.
261     */
262    const FETCH_RECORD          = 2;
263
264    /**
265     * FETCH ARRAY
266     */
267    const FETCH_ARRAY           = 3;
268
269    /**
270     * PORTABILITY CONSTANTS
271     */
272
273    /**
274     * Portability: turn off all portability features.
275     * @see self::ATTR_PORTABILITY
276     */
277    const PORTABILITY_NONE          = 0;
278
279    /**
280     * Portability: convert names of tables and fields to case defined in the
281     * "field_case" option when using the query*(), fetch*() methods.
282     * @see self::ATTR_PORTABILITY
283     */
284    const PORTABILITY_FIX_CASE      = 1;
285
286    /**
287     * Portability: right trim the data output by query*() and fetch*().
288     * @see self::ATTR_PORTABILITY
289     */
290    const PORTABILITY_RTRIM         = 2;
291
292    /**
293     * Portability: force reporting the number of rows deleted.
294     * @see self::ATTR_PORTABILITY
295     */
296    const PORTABILITY_DELETE_COUNT  = 4;
297
298    /**
299     * Portability: convert empty values to null strings in data output by
300     * query*() and fetch*().
301     * @see self::ATTR_PORTABILITY
302     */
303    const PORTABILITY_EMPTY_TO_NULL = 8;
304
305    /**
306     * Portability: removes database/table qualifiers from associative indexes
307     * @see self::ATTR_PORTABILITY
308     */
309    const PORTABILITY_FIX_ASSOC_FIELD_NAMES = 16;
310
311    /**
312     * Portability: makes Doctrine_Expression throw exception for unportable RDBMS expressions
313     * @see self::ATTR_PORTABILITY
314     */
315    const PORTABILITY_EXPR          = 32;
316
317    /**
318     * Portability: turn on all portability features.
319     * @see self::ATTR_PORTABILITY
320     */
321    const PORTABILITY_ALL           = 63;
322
323    /**
324     * LOCKMODE CONSTANTS
325     */
326
327    /**
328     * mode for optimistic locking
329     */
330    const LOCK_OPTIMISTIC       = 0;
331
332    /**
333     * mode for pessimistic locking
334     */
335    const LOCK_PESSIMISTIC      = 1;
336
337    /**
338     * EXPORT CONSTANTS
339     */
340
341    /**
342     * EXPORT_NONE
343     */
344    const EXPORT_NONE               = 0;
345
346    /**
347     * EXPORT_TABLES
348     */
349    const EXPORT_TABLES             = 1;
350
351    /**
352     * EXPORT_CONSTRAINTS
353     */
354    const EXPORT_CONSTRAINTS        = 2;
355
356    /**
357     * EXPORT_PLUGINS
358     */
359    const EXPORT_PLUGINS            = 4;
360
361    /**
362     * EXPORT_ALL
363     */
364    const EXPORT_ALL                = 7;
365
366    /**
367     * HYDRATION CONSTANTS
368     */
369    const HYDRATE_RECORD            = 2;
370
371    /**
372     * HYDRATE_ARRAY
373     */
374    const HYDRATE_ARRAY             = 3;
375
376    /**
377     * HYDRATE_NONE
378     */
379    const HYDRATE_NONE              = 4;
380
381    /**
382     * VALIDATION CONSTANTS
383     */
384    const VALIDATE_NONE             = 0;
385
386    /**
387     * VALIDATE_LENGTHS
388     */
389    const VALIDATE_LENGTHS          = 1;
390
391    /**
392     * VALIDATE_TYPES
393     */
394    const VALIDATE_TYPES            = 2;
395
396    /**
397     * VALIDATE_CONSTRAINTS
398     */
399    const VALIDATE_CONSTRAINTS      = 4;
400
401    /**
402     * VALIDATE_ALL
403     */
404    const VALIDATE_ALL              = 7;
405
406    /**
407     * IDENTIFIER_AUTOINC
408     *
409     * constant for auto_increment identifier
410     */
411    const IDENTIFIER_AUTOINC        = 1;
412
413    /**
414     * IDENTIFIER_SEQUENCE
415     *
416     * constant for sequence identifier
417     */
418    const IDENTIFIER_SEQUENCE       = 2;
419
420    /**
421     * IDENTIFIER_NATURAL
422     *
423     * constant for normal identifier
424     */
425    const IDENTIFIER_NATURAL        = 3;
426
427    /**
428     * IDENTIFIER_COMPOSITE
429     *
430     * constant for composite identifier
431     */
432    const IDENTIFIER_COMPOSITE      = 4;
433
434    /**
435     * MODEL_LOADING_AGGRESSIVE
436     *
437     * Constant for agressive model loading
438     * Will require_once() all found model files
439     */
440    const MODEL_LOADING_AGGRESSIVE   = 1;
441
442    /**
443     * MODEL_LOADING_CONSERVATIVE
444     *
445     * Constant for conservative model loading
446     * Will not require_once() found model files inititally instead it will build an array
447     * and reference it in autoload() when a class is needed it will require_once() it
448     */
449    const MODEL_LOADING_CONSERVATIVE= 2;
450
451    /**
452     * Path to Doctrine root
453     *
454     * @var string $path            doctrine root directory
455     */
456    private static $_path;
457
458    /**
459     * Debug bool true/false option
460     *
461     * @var boolean $_debug
462     */
463    private static $_debug = false;
464
465    /**
466     * Array of all the loaded models and the path to each one for autoloading
467     *
468     * @var array
469     */
470    private static $_loadedModelFiles = array();
471
472    /**
473     * Array of all the loaded validators
474     *
475     * @var array
476     */
477    private static $_validators = array();
478
479    /**
480     * __construct
481     *
482     * @return void
483     * @throws Doctrine_Exception
484     */
485    public function __construct()
486    {
487        throw new Doctrine_Exception('Doctrine is static class. No instances can be created.');
488    }
489
490    /**
491     * Returns an array of all the loaded models and the path where each of them exists
492     *
493     * @return array
494     */
495    public static function getLoadedModelFiles()
496    {
497        return self::$_loadedModelFiles;
498    }
499
500    /**
501     * Turn on/off the debugging setting
502     *
503     * @param string $bool
504     * @return void
505     */
506    public static function debug($bool = null)
507    {
508        if ($bool !== null) {
509            self::$_debug = (bool) $bool;
510        }
511
512        return self::$_debug;
513    }
514
515    /**
516     * Get the root path to Doctrine
517     *
518     * @return string
519     */
520    public static function getPath()
521    {
522        if ( ! self::$_path) {
523            self::$_path = dirname(__FILE__);
524        }
525
526        return self::$_path;
527    }
528
529    /**
530     * Load an individual model name and path in to the model loading registry
531     *
532     * @return null
533     */
534    public static function loadModel($className, $path = null)
535    {
536        self::$_loadedModelFiles[$className] = $path;
537    }
538
539    /**
540     * Recursively load all models from a directory or array of directories
541     *
542     * @param  string   $directory      Path to directory of models or array of directory paths
543     * @param  integer  $modelLoading   Pass value of Doctrine::ATTR_MODEL_LOADING to force a certain style of model loading
544     *                                  Allowed Doctrine::MODEL_LOADING_AGGRESSIVE(default) or Doctrine::MODEL_LOADING_CONSERVATIVE
545     */
546    public static function loadModels($directory, $modelLoading = null)
547    {
548        $manager = Doctrine_Manager::getInstance();
549
550        $modelLoading = $modelLoading === null ? $manager->getAttribute(Doctrine::ATTR_MODEL_LOADING):$modelLoading;
551
552        $loadedModels = array();
553
554        if ($directory !== null) {
555            foreach ((array) $directory as $dir) {
556                if ( ! is_dir($dir)) {
557                    throw new Doctrine_Exception('You must pass a valid path to a directory containing Doctrine models');
558                }
559
560                $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir),
561                                                        RecursiveIteratorIterator::LEAVES_ONLY);
562                foreach ($it as $file) {
563                    $e = explode('.', $file->getFileName());
564                    if (end($e) === 'php' && strpos($file->getFileName(), '.inc') === false) {
565                        $className = $e[0];
566
567                        if ($modelLoading == Doctrine::MODEL_LOADING_CONSERVATIVE) {
568                            self::loadModel($className, $file->getPathName());
569
570                            $loadedModels[$className] = $className;
571                        } else {
572                            $declaredBefore = get_declared_classes();
573                            require_once($file->getPathName());
574
575                            $declaredAfter = get_declared_classes();
576                            // Using array_slice because array_diff is broken is some PHP versions
577                            $foundClasses = array_slice($declaredAfter, count($declaredBefore) - 1);
578                            if ($foundClasses) {
579                                foreach ($foundClasses as $className) {
580                                    if (self::isValidModelClass($className)) {
581                                        $loadedModels[$className] = $className;
582
583                                        self::loadModel($className, $file->getPathName());
584                                    }
585                                }
586                            }
587                        }
588                    }
589                }
590            }
591        }
592
593        return $loadedModels;
594    }
595
596    /**
597     * Get all the loaded models, you can provide an array of classes or it will use get_declared_classes()
598     *
599     * Will filter through an array of classes and return the Doctrine_Records out of them.
600     * If you do not specify $classes it will return all of the currently loaded Doctrine_Records
601     *
602     * @param classes  Array of classes to filter through, otherwise uses get_declared_classes()
603     * @return array   $loadedModels
604     */
605    public static function getLoadedModels($classes = null)
606    {
607        if ($classes === null) {
608            $classes = get_declared_classes();
609            $classes = array_merge($classes, array_keys(self::$_loadedModelFiles));
610        }
611
612        return self::filterInvalidModels($classes);
613    }
614
615    /**
616     * Initialize all models so everything is present and loaded in to memory
617     * This will also inheritently initialize any model behaviors and add
618     * the models generated by Doctrine generators and add them to the $models
619     * array
620     *
621     * @param string $models
622     * @return array $models
623     */
624    public static function initializeModels($models)
625    {
626        $models = self::filterInvalidModels($models);
627
628        foreach ($models as $model) {
629            $declaredBefore = get_declared_classes();
630            Doctrine::getTable($model);
631
632            $declaredAfter = get_declared_classes();
633            // Using array_slice because array_diff is broken is some PHP versions
634            $foundClasses = array_slice($declaredAfter, count($declaredBefore) - 1);
635            foreach ($foundClasses as $class) {
636                if (self::isValidModelClass($class)) {
637                    $models[] = $class;
638                }
639            }
640        }
641
642        $models = self::filterInvalidModels($models);
643
644        return $models;
645    }
646
647    /**
648     * Filter through an array of classes and return all the classes that are valid models.
649     * This will inflect the class, causing it to be loaded in to memory.
650     *
651     * @param classes  Array of classes to filter through, otherwise uses get_declared_classes()
652     * @return array   $loadedModels
653     */
654    public static function filterInvalidModels($classes)
655    {
656        $validModels = array();
657
658        foreach ((array) $classes as $name) {
659            if (self::isValidModelClass($name) && ! in_array($name, $validModels)) {
660                $validModels[] = $name;
661            }
662        }
663
664        return $validModels;
665    }
666
667    /**
668     * Checks if what is passed is a valid Doctrine_Record
669     * Will load class in to memory in order to inflect it and find out information about the class
670     *
671     * @param   mixed   $class Can be a string named after the class, an instance of the class, or an instance of the class reflected
672     * @return  boolean
673     */
674    public static function isValidModelClass($class)
675    {
676        if ($class instanceof Doctrine_Record) {
677            $class = get_class($class);
678        }
679
680        if (is_string($class) && class_exists($class)) {
681            $class = new ReflectionClass($class);
682        }
683
684        if ($class instanceof ReflectionClass) {
685            // Skip the following classes
686            // - abstract classes
687            // - not a subclass of Doctrine_Record
688            if ( ! $class->isAbstract() && $class->isSubClassOf('Doctrine_Record')) {
689
690                return true;
691            }
692        }
693
694        return false;
695    }
696
697    /**
698     * Get the connection object for a table by the actual table name
699     * FIXME: I think this method is flawed because a individual connections could have the same table name
700     *
701     * @param string $tableName
702     * @return Doctrine_Connection
703     */
704    public static function getConnectionByTableName($tableName)
705    {
706        $loadedModels = self::getLoadedModels();
707
708        foreach ($loadedModels as $name) {
709            $table = Doctrine::getTable($name);
710
711            if ($table->getTableName() == $tableName) {
712               return $table->getConnection();
713            }
714        }
715
716        return Doctrine_Manager::connection();
717    }
718
719    /**
720     * Method for importing existing schema to Doctrine_Record classes
721     *
722     * @param string $directory Directory to write your models to
723     * @param array $databases Array of databases to generate models for
724     * @param array $options Array of options
725     * @return boolean
726     * @throws Exception
727     */
728    public static function generateModelsFromDb($directory, array $databases = array(), array $options = array())
729    {
730        return Doctrine_Manager::connection()->import->importSchema($directory, $databases, $options);
731    }
732
733    /**
734     * Generates models from database to temporary location then uses those models to generate a yaml schema file.
735     * This should probably be fixed. We should write something to generate a yaml schema file directly from the database.
736     *
737     * @param string $yamlPath Path to write oyur yaml schema file to
738     * @param array  $options Array of options
739     * @return void
740     */
741    public static function generateYamlFromDb($yamlPath, array $databases = array(), array $options = array())
742    {
743        $directory = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'tmp_doctrine_models';
744
745        $options['generateBaseClasses'] = isset($options['generateBaseClasses']) ? $options['generateBaseClasses']:false;
746        $result = Doctrine::generateModelsFromDb($directory, $databases, $options);
747
748        if ( empty($result) && ! is_dir($directory)) {
749            throw new Doctrine_Exception('No models generated from your databases');
750        }
751
752        $export = new Doctrine_Export_Schema();
753
754        $result = $export->exportSchema($yamlPath, 'yml', $directory);
755
756        Doctrine_Lib::removeDirectories($directory);
757
758        return $result;
759    }
760
761    /**
762     * Generate a yaml schema file from an existing directory of models
763     *
764     * @param string $yamlPath Path to your yaml schema files
765     * @param string $directory Directory to generate your models in
766     * @param array  $options Array of options to pass to the schema importer
767     * @return void
768     */
769    public static function generateModelsFromYaml($yamlPath, $directory, $options = array())
770    {
771        $import = new Doctrine_Import_Schema();
772        $import->setOptions($options);
773
774        return $import->importSchema($yamlPath, 'yml', $directory);
775    }
776
777    /**
778     * Creates database tables for the models in the specified directory
779     *
780     * @param string $directory Directory containing your models
781     * @return void
782     */
783