Coverage for Doctrine

Back to coverage report

1 <?php
2 /*
3  *  $Id: Doctrine.php 2963 2007-10-21 06:23:59Z Jonathan.Wage $
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.com>.
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.com
31  * @since       1.0
32  * @version     $Revision: 2963 $
33  */
34 final class Doctrine
35 {
36     /**
37      * ERROR CONSTANTS
38      */
39     const ERR                       = -1;
40     const ERR_SYNTAX                = -2;
41     const ERR_CONSTRAINT            = -3;
42     const ERR_NOT_FOUND             = -4;
43     const ERR_ALREADY_EXISTS        = -5;
44     const ERR_UNSUPPORTED           = -6;
45     const ERR_MISMATCH              = -7;
46     const ERR_INVALID               = -8;
47     const ERR_NOT_CAPABLE           = -9;
48     const ERR_TRUNCATED             = -10;
49     const ERR_INVALID_NUMBER        = -11;
50     const ERR_INVALID_DATE          = -12;
51     const ERR_DIVZERO               = -13;
52     const ERR_NODBSELECTED          = -14;
53     const ERR_CANNOT_CREATE         = -15;
54     const ERR_CANNOT_DELETE         = -16;
55     const ERR_CANNOT_DROP           = -17;
56     const ERR_NOSUCHTABLE           = -18;
57     const ERR_NOSUCHFIELD           = -19;
58     const ERR_NEED_MORE_DATA        = -20;
59     const ERR_NOT_LOCKED            = -21;
60     const ERR_VALUE_COUNT_ON_ROW    = -22;
61     const ERR_INVALID_DSN           = -23;
62     const ERR_CONNECT_FAILED        = -24;
63     const ERR_EXTENSION_NOT_FOUND   = -25;
64     const ERR_NOSUCHDB              = -26;
65     const ERR_ACCESS_VIOLATION      = -27;
66     const ERR_CANNOT_REPLACE        = -28;
67     const ERR_CONSTRAINT_NOT_NULL   = -29;
68     const ERR_DEADLOCK              = -30;
69     const ERR_CANNOT_ALTER          = -31;
70     const ERR_MANAGER               = -32;
71     const ERR_MANAGER_PARSE         = -33;
72     const ERR_LOADMODULE            = -34;
73     const ERR_INSUFFICIENT_DATA     = -35;
74     const ERR_CLASS_NAME            = -36;
75
76     /**
77      * PDO derived constants
78      */
79     const CASE_LOWER = 2;
80     const CASE_NATURAL = 0;
81     const CASE_UPPER = 1;
82     const CURSOR_FWDONLY = 0;
83     const CURSOR_SCROLL = 1;
84     const ERRMODE_EXCEPTION = 2;
85     const ERRMODE_SILENT = 0;
86     const ERRMODE_WARNING = 1;
87     const FETCH_ASSOC = 2;
88     const FETCH_BOTH = 4;
89     const FETCH_BOUND = 6;
90     const FETCH_CLASS = 8;
91     const FETCH_CLASSTYPE = 262144;
92     const FETCH_COLUMN = 7;
93     const FETCH_FUNC = 10;
94     const FETCH_GROUP = 65536;
95     const FETCH_INTO = 9;
96     const FETCH_LAZY = 1;
97     const FETCH_NAMED = 11;
98     const FETCH_NUM = 3;
99     const FETCH_OBJ = 5;
100     const FETCH_ORI_ABS = 4;
101     const FETCH_ORI_FIRST = 2;
102     const FETCH_ORI_LAST = 3;
103     const FETCH_ORI_NEXT = 0;
104     const FETCH_ORI_PRIOR = 1;
105     const FETCH_ORI_REL = 5;
106     const FETCH_SERIALIZE = 524288;
107     const FETCH_UNIQUE = 196608;
108     const NULL_EMPTY_STRING = 1;
109     const NULL_NATURAL = 0;
110     const NULL_TO_STRING         = NULL;
111     const PARAM_BOOL = 5;
112     const PARAM_INPUT_OUTPUT = -2147483648;
113     const PARAM_INT = 1;
114     const PARAM_LOB = 3;
115     const PARAM_NULL = 0;
116     const PARAM_STMT = 4;
117     const PARAM_STR = 2;
118
119     /**
120      * ATTRIBUTE CONSTANTS
121      */
122
123     /**
124      * PDO derived attributes
125      */
126     const ATTR_AUTOCOMMIT           = 0;
127     const ATTR_PREFETCH             = 1;
128     const ATTR_TIMEOUT              = 2;
129     const ATTR_ERRMODE              = 3;
130     const ATTR_SERVER_VERSION       = 4;
131     const ATTR_CLIENT_VERSION       = 5;
132     const ATTR_SERVER_INFO          = 6;
133     const ATTR_CONNECTION_STATUS    = 7;
134     const ATTR_CASE                 = 8;
135     const ATTR_CURSOR_NAME          = 9;
136     const ATTR_CURSOR               = 10;
137     const ATTR_ORACLE_NULLS         = 11;
138     const ATTR_PERSISTENT           = 12;
139     const ATTR_STATEMENT_CLASS      = 13;
140     const ATTR_FETCH_TABLE_NAMES    = 14;
141     const ATTR_FETCH_CATALOG_NAMES  = 15;
142     const ATTR_DRIVER_NAME          = 16;
143     const ATTR_STRINGIFY_FETCHES    = 17;
144     const ATTR_MAX_COLUMN_LEN       = 18;
145
146     /**
147      * Doctrine constants
148      */
149     const ATTR_LISTENER             = 100;
150     const ATTR_QUOTE_IDENTIFIER     = 101;
151     const ATTR_FIELD_CASE           = 102;
152     const ATTR_IDXNAME_FORMAT       = 103;
153     const ATTR_SEQNAME_FORMAT       = 104;
154     const ATTR_SEQCOL_NAME          = 105;
155     const ATTR_CMPNAME_FORMAT       = 118;
156     const ATTR_DBNAME_FORMAT        = 117;
157     const ATTR_TBLCLASS_FORMAT      = 119;
158     const ATTR_EXPORT               = 140;
159     const ATTR_DECIMAL_PLACES       = 141;
160
161     const ATTR_PORTABILITY          = 106;
162     const ATTR_VALIDATE             = 107;
163     const ATTR_COLL_KEY             = 108;
164     const ATTR_QUERY_LIMIT          = 109;
165     const ATTR_DEFAULT_TABLE_TYPE   = 112;
166     const ATTR_DEF_TEXT_LENGTH      = 113;
167     const ATTR_DEF_VARCHAR_LENGTH   = 114;
168     const ATTR_DEF_TABLESPACE       = 115;
169     const ATTR_EMULATE_DATABASE     = 116;
170     const ATTR_USE_NATIVE_ENUM      = 117;
171     const ATTR_DEFAULT_SEQUENCE     = 133;
172
173     const ATTR_FETCHMODE            = 118;
174     const ATTR_NAME_PREFIX          = 121;
175     const ATTR_CREATE_TABLES        = 122;
176     const ATTR_COLL_LIMIT           = 123;
177
178     const ATTR_CACHE                = 150;
179     const ATTR_CACHE_LIFESPAN       = 151;
180     const ATTR_LOAD_REFERENCES      = 153;
181     const ATTR_RECORD_LISTENER      = 154;
182     const ATTR_THROW_EXCEPTIONS     = 155;
183
184     /**
185      * LIMIT CONSTANTS
186      */
187
188     /**
189      * constant for row limiting
190      */
191     const LIMIT_ROWS       = 1;
192
193     /**
194      * constant for record limiting
195      */
196     const LIMIT_RECORDS    = 2;
197
198     /**
199      * FETCHMODE CONSTANTS
200      */
201
202     /**
203      * IMMEDIATE FETCHING
204      * mode for immediate fetching
205      */
206     const FETCH_IMMEDIATE       = 0;
207
208     /**
209      * BATCH FETCHING
210      * mode for batch fetching
211      */
212     const FETCH_BATCH           = 1;
213
214     /**
215      * LAZY FETCHING
216      * mode for offset fetching
217      */
218     const FETCH_OFFSET          = 3;
219
220     /**
221      * LAZY OFFSET FETCHING
222      * mode for lazy offset fetching
223      */
224     const FETCH_LAZY_OFFSET     = 4;
225
226     /**
227      * FETCH CONSTANTS
228      */
229
230
231     /**
232      * FETCH VALUEHOLDER
233      */
234     const FETCH_VHOLDER         = 1;
235
236     /**
237      * FETCH RECORD
238      *
239      * Specifies that the fetch method shall return Doctrine_Record
240      * objects as the elements of the result set.
241      *
242      * This is the default fetchmode.
243      */
244     const FETCH_RECORD          = 2;
245
246     /**
247      * FETCH ARRAY
248      */
249     const FETCH_ARRAY           = 3;
250
251     /**
252      * PORTABILITY CONSTANTS
253      */
254
255     /**
256      * Portability: turn off all portability features.
257      * @see self::ATTR_PORTABILITY
258      */
259     const PORTABILITY_NONE          = 0;
260
261     /**
262      * Portability: convert names of tables and fields to case defined in the
263      * "field_case" option when using the query*(), fetch*() methods.
264      * @see self::ATTR_PORTABILITY
265      */
266     const PORTABILITY_FIX_CASE      = 1;
267
268     /**
269      * Portability: right trim the data output by query*() and fetch*().
270      * @see self::ATTR_PORTABILITY
271      */
272     const PORTABILITY_RTRIM         = 2;
273
274     /**
275      * Portability: force reporting the number of rows deleted.
276      * @see self::ATTR_PORTABILITY
277      */
278     const PORTABILITY_DELETE_COUNT  = 4;
279
280     /**
281      * Portability: convert empty values to null strings in data output by
282      * query*() and fetch*().
283      * @see self::ATTR_PORTABILITY
284      */
285     const PORTABILITY_EMPTY_TO_NULL = 8;
286
287     /**
288      * Portability: removes database/table qualifiers from associative indexes
289      * @see self::ATTR_PORTABILITY
290      */
291     const PORTABILITY_FIX_ASSOC_FIELD_NAMES = 16;
292
293     /**
294      * Portability: makes Doctrine_Expression throw exception for unportable RDBMS expressions
295      * @see self::ATTR_PORTABILITY
296      */
297     const PORTABILITY_EXPR          = 32;
298
299     /**
300      * Portability: turn on all portability features.
301      * @see self::ATTR_PORTABILITY
302      */
303     const PORTABILITY_ALL           = 63;
304
305     /**
306      * LOCKMODE CONSTANTS
307      */
308
309     /**
310      * mode for optimistic locking
311      */
312     const LOCK_OPTIMISTIC       = 0;
313
314     /**
315      * mode for pessimistic locking
316      */
317     const LOCK_PESSIMISTIC      = 1;
318
319     /**
320      * EXPORT CONSTANTS
321      */
322
323     /**
324      * EXPORT_NONE
325      */
326     const EXPORT_NONE               = 0;
327
328     /**
329      * EXPORT_TABLES
330      */
331     const EXPORT_TABLES             = 1;
332
333     /**
334      * EXPORT_CONSTRAINTS
335      */
336     const EXPORT_CONSTRAINTS        = 2;
337
338     /**
339      * EXPORT_PLUGINS
340      */
341     const EXPORT_PLUGINS            = 4;
342
343     /**
344      * EXPORT_ALL
345      */
346     const EXPORT_ALL                = 7;
347
348     /**
349      * HYDRATION CONSTANTS
350      */
351     const HYDRATE_RECORD            = 2;
352
353     /**
354      * HYDRATE_ARRAY
355      */
356     const HYDRATE_ARRAY             = 3;
357
358     /**
359      * VALIDATION CONSTANTS
360      */
361     const VALIDATE_NONE             = 0;
362
363     /**
364      * VALIDATE_LENGTHS
365      */
366     const VALIDATE_LENGTHS          = 1;
367
368     /**
369      * VALIDATE_TYPES
370      */
371     const VALIDATE_TYPES            = 2;
372
373     /**
374      * VALIDATE_CONSTRAINTS
375      */
376     const VALIDATE_CONSTRAINTS      = 4;
377
378     /**
379      * VALIDATE_ALL
380      */
381     const VALIDATE_ALL              = 7;
382
383     /**
384      * IDENTIFIER_AUTOINC
385      *
386      * constant for auto_increment identifier
387      */
388     const IDENTIFIER_AUTOINC        = 1;
389
390     /**
391      * IDENTIFIER_SEQUENCE
392      *
393      * constant for sequence identifier
394      */
395     const IDENTIFIER_SEQUENCE       = 2;
396
397     /**
398      * IDENTIFIER_NATURAL
399      *
400      * constant for normal identifier
401      */
402     const IDENTIFIER_NATURAL        = 3;
403
404     /**
405      * IDENTIFIER_COMPOSITE
406      *
407      * constant for composite identifier
408      */
409     const IDENTIFIER_COMPOSITE      = 4;
410
411     /**
412      * Path
413      *
414      * @var string $path            doctrine root directory
415      */
416     private static $_path;
417
418     /**
419      * Debug
420      *
421      * Bool true/false
422      *
423      * @var boolean $_debug
424      */
425     private static $_debug = false;
426
427     /**
428      * __construct
429      *
430      * @return void
431      * @throws Doctrine_Exception
432      */
433     public function __construct()
434     {
435         throw new Doctrine_Exception('Doctrine is static class. No instances can be created.');
436     }
437
438     /**
439      * debug
440      *
441      * @param string $bool 
442      * @return void
443      */
444     public static function debug($bool = null)
445     {
446         if ($bool !== null) {
447             self::$_debug = (bool) $bool;
448         }
449         
450         return self::$_debug;
451     }
452
453     /**
454      * getPath
455      * returns the doctrine root
456      *
457      * @return string
458      */
459     public static function getPath()
460     {
461         if ( ! self::$_path) {
462             self::$_path = dirname(__FILE__);
463         }
464         
465         return self::$_path;
466     }
467
468     /**
469      * loadAll
470      * loads all runtime classes
471      *
472      * @return void
473      */
474     public static function loadAll()
475     {
476         return self::loadAllRuntimeClasses();
477     }
478
479     /**
480      * importSchema
481      * method for importing existing schema to Doctrine_Record classes
482      *
483      * @param string $directory Directory to write your models to
484      * @param array $databases Array of databases to generate models for
485      * @return boolean
486      */
487     public static function importSchema($directory, array $databases = array())
488     {
489         return self::generateModelsFromDb($directory, $databases);
490     }
491
492     /**
493      * exportSchema
494      * method for exporting Doctrine_Record classes to a schema
495      *
496      * @param string $directory Directory containing your models
497      * @return void
498      */
499     public static function exportSchema($directory = null)
500     {
501         return self::createTablesFromModels($directory);
502     }
503
504     /**
505      * exportSql
506      * method for exporting Doctrine_Record classes to a schema
507      *
508      * @param string $directory
509      */
510     public static function exportSql($directory = null)
511     {
512         return self::generateSqlFromModels($directory);
513     }
514
515     /**
516      * loadAllRuntimeClasses
517      *
518      * loads all runtime classes
519      *
520      * @return void
521      */
522     public static function loadAllRuntimeClasses()
523     {
524         $classes = Doctrine_Compiler::getRuntimeClasses();
525
526         foreach ($classes as $class) {
527             self::autoload($class);
528         }
529     }
530
531     /**
532      * loadModels
533      *
534      * Recursively load all models from a directory or array of directories
535      * 
536      * @param string $directory Path to directory of models or array of directory paths
537      * @return array $loadedModels
538      */
539     public static function loadModels($directory)
540     {
541         $declared = get_declared_classes();
542         
543         if ($directory !== null) {
544             foreach ((array) $directory as $dir) {
545                 $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir),
546                                                         RecursiveIteratorIterator::LEAVES_ONLY);
547
548                 foreach ($it as $file) {
549                     $e = explode('.', $file->getFileName());
550                     if (end($e) === 'php' && strpos($file->getFileName(), '.inc') === false) {
551                         require_once $file->getPathName();
552                     }
553                 }
554             }
555             
556             $declared = array_diff(get_declared_classes(), $declared);
557         }
558         
559         return self::getLoadedModels($declared);
560     }
561
562     /**
563      * getLoadedModels
564      *
565      * Get all the loaded models, you can provide an array of classes or it will use get_declared_classes()
566      * 
567      * Will filter through an array of classes and return the Doctrine_Records out of them.
568      * If you do not specify $classes it will return all of the currently loaded Doctrine_Records
569      *
570      * @param $classes Array of classes to filter through, otherwise uses get_declared_classes()
571      * @return array $loadedModels
572      */
573     public static function getLoadedModels($classes = null)
574     {
575         if ($classes === null) {
576             $classes = get_declared_classes();
577         }
578         
579         $parent = new ReflectionClass('Doctrine_Record');
580         
581         $loadedModels = array();
582         
583         foreach ((array) $classes as $name) {
584             $class = new ReflectionClass($name);
585             
586             // Skip the following classes
587             // - abstract classes
588             // - not a subclass of Doctrine_Record 
589             // - don't have a setTableDefinition method
590             if ($class->isAbstract() || 
591                 !$class->isSubClassOf($parent) || 
592                 !$class->hasMethod('setTableDefinition')) {
593                 continue;
594             }
595             
596             $loadedModels[] = $name;
597         }
598         
599         return $loadedModels;
600     }
601
602     /**
603      * getConnectionByTableName
604      *
605      * Get the connection object for a table by the actual table name
606      * 
607      * @param string $tableName 
608      * @return object Doctrine_Connection
609      */
610     public static function getConnectionByTableName($tableName)
611     {
612         $loadedModels = self::getLoadedModels();
613         
614         foreach ($loadedModels as $name) {
615             $model = new $name();
616             $table = $model->getTable();
617             
618             if ($table->getTableName() == $tableName) {
619                return $table->getConnection(); 
620             }
621         }
622         
623         return Doctrine_Manager::connection();
624     }
625
626     /**
627      * generateModelsFromDb
628      *
629      * method for importing existing schema to Doctrine_Record classes
630      *
631      * @param string $directory Directory to write your models to
632      * @param array $databases Array of databases to generate models for
633      * @return boolean
634      * @throws Exception
635      */
636     public static function generateModelsFromDb($directory, array $databases = array())
637     {
638         return Doctrine_Manager::connection()->import->importSchema($directory, $databases);
639     }
640
641     /**
642      * generateYamlFromDb
643      *
644      * Generates models from database to temporary location then uses those models to generate a yaml schema file.
645      * This should probably be fixed. We should write something to generate a yaml schema file directly from the database.
646      *
647      * @param string $yamlPath Path to write oyur yaml schema file to
648      * @return void
649      */
650     public static function generateYamlFromDb($yamlPath)
651     {
652         $directory = '/tmp/tmp_doctrine_models';
653
654         Doctrine::generateModelsFromDb($directory);
655
656         $export = new Doctrine_Export_Schema();
657         
658         $result = $export->exportSchema($yamlPath, 'yml', $directory);
659         
660         exec('rm -rf ' . $directory);
661         
662         return $result;
663     }
664
665     /**
666      * generateModelsFromYaml
667      *
668      * Generate a yaml schema file from an existing directory of models
669      *
670      * @param string $yamlPath Path to your yaml schema files
671      * @param string $directory Directory to generate your models in
672      * @return void
673      */
674     public static function generateModelsFromYaml($yamlPath, $directory)
675     {
676         $import = new Doctrine_Import_Schema();
677         $import->generateBaseClasses(true);
678         
679         return $import->importSchema($yamlPath, 'yml', $directory);
680     }
681
682     /**
683      * createTablesFromModels
684      *
685      * Creates database tables for the models in the specified directory
686      *
687      * @param string $directory Directory containing your models
688      * @return void
689      */
690     public static function createTablesFromModels($directory = null)
691     {
692         return Doctrine_Manager::connection()->export->exportSchema($directory);
693     }
694
695     /**
696      * generateSqlFromModels
697      *
698      * @param string $directory 
699      * @return string $build  String of sql queries. One query per line
700      */
701     public static function generateSqlFromModels($directory = null)
702     {
703         $sql = Doctrine_Manager::connection()->export->exportSql($directory);
704         
705         $build = '';
706         foreach ($sql as $query) {
707             $build .= $query.";\n";
708         }
709         
710         return $build;
711     }
712
713     /**
714      * generateYamlFromModels
715      *
716      * Generate yaml schema file for the models in the specified directory
717      *
718      * @param string $yamlPath Path to your yaml schema files
719      * @param string $directory Directory to generate your models in
720      * @return void
721      */
722     public static function generateYamlFromModels($yamlPath, $directory)
723     {
724         $export = new Doctrine_Export_Schema();
725         
726         return $export->exportSchema($yamlPath, 'yml', $directory);
727     }
728
729     /**
730      * createDatabases
731      *
732      * Creates databases for connections
733      *
734      * @param string $specifiedConnections Array of connections you wish to create the database for
735      * @return void
736      */
737     public static function createDatabases($specifiedConnections = array())
738     {
739         if ( ! is_array($specifiedConnections)) {
740             $specifiedConnections = (array) $specifiedConnections;
741         }
742         
743         $manager = Doctrine_Manager::getInstance();
744         $connections = $manager->getConnections();
745         
746         foreach ($connections as $name => $connection) {
747             if ( ! empty($specifiedConnections) && !in_array($name, $specifiedConnections)) {
748                 continue;
749             }
750             
751             $info = $manager->parsePdoDsn($connection->getOption('dsn'));
752             $username = $connection->getOption('username');
753             $password = $connection->getOption('password');
754             
755             // Make connection without database specified so we can create it
756             $connect = $manager->openConnection(new PDO($info['scheme'] . ':host=' . $info['host'], $username, $password), 'tmp_connection', false);
757             
758             try {
759                 // Create database
760                 $connect->export->createDatabase($name);
761                 
762                 // Close the tmp connection with no database
763                 $manager->closeConnection($connect);
764                 
765                 // Close original connection
766                 $manager->closeConnection($connection);
767                 
768                 // Reopen original connection with newly created database
769                 $manager->openConnection(new PDO($info['dsn'], $username, $password), $name, true);
770             } catch (Exception $e) {
771                 
772             }
773         }
774     }
775
776     /**
777      * dropDatabases
778      *
779      * Drops databases for connections
780      *
781      * @param string $specifiedConnections Array of connections you wish to drop the database for
782      * @return void
783      */
784     public static function dropDatabases($specifiedConnections = array())
785     {
786         if ( ! is_array($specifiedConnections)) {
787             $specifiedConnections = (array) $specifiedConnections;
788         }
789         
790         $manager = Doctrine_Manager::getInstance();
791         
792         $connections = $manager->getConnections();
793         
794         foreach ($connections as $name => $connection) {
795             if ( ! empty($specifiedConnections) && !in_array($name, $specifiedConnections)) {
796                 continue;
797             }
798             
799             try {
800                 $connection->export->dropDatabase($name);
801             } catch (Exception $e) {
802                 
803             }
804         }
805     }
806
807     /**
808      * dumpData
809      *
810      * Dump data to a yaml fixtures file
811      *
812      * @param string $yamlPath Path to write the yaml data fixtures to
813      * @param string $individualFiles Whether or not to dump data to individual fixtures files
814      * @return void
815      */
816     public static function dumpData($yamlPath, $individualFiles = false)
817     {
818         $data = new Doctrine_Data();
819         
820         return $data->exportData($yamlPath, 'yml', array(), $individualFiles);
821     }
822
823     /**
824      * loadData
825      *
826      * Load data from a yaml fixtures file.
827      * The output of dumpData can be fed to loadData
828      *
829      * @param string $yamlPath Path to your yaml data fixtures
830      * @param string $append Whether or not to append the data
831      * @return void
832      */
833     public static function loadData($yamlPath, $append = false)
834     {
835         $data = new Doctrine_Data();
836         
837         if ( ! $append) {
838             $data->purge();
839         }
840         
841         return $data->importData($yamlPath, 'yml');
842     }
843
844     /**
845      * loadDummyData
846      *
847      * Populdate your models with dummy data
848      *
849      * @param string $append Whether or not to append the data
850      * @param string $num Number of records to populate
851      * @return void
852      */
853     public static function loadDummyData($append, $num = 5)
854     {
855         $data = new Doctrine_Data();
856
857         if ( ! $append) {
858           $data->purge();
859         }
860         
861         return $data->importDummyData($num);
862     }
863
864     /**
865      * migrate
866      * 
867      * Migrate database to specified $to version. Migrates from current to latest if you do not specify.
868      *
869      * @param string $migrationsPath Path to migrations directory which contains your migration classes
870      * @param string $to Version you wish to migrate to.
871      * @return bool true
872      * @throws new Doctrine_Migration_Exception
873      */
874     public static function migrate($migrationsPath, $to = null)
875     {
876         $migration = new Doctrine_Migration($migrationsPath);
877         
878         return $migration->migrate($to);
879     }
880
881     /**
882      * generateMigrationClass
883      *
884      * Generate new migration class skeleton
885      *
886      * @param string $className Name of the Migration class to generate
887      * @param string $migrationsPath Path to directory which contains your migration classes
888      */
889     public static function generateMigrationClass($className, $migrationsPath)
890     {
891         $builder = new Doctrine_Migration_Builder($migrationsPath);
892         
893         return $builder->generateMigrationClass($className);
894     }
895
896     /**
897      * generateMigrationsFromDb
898      *
899      * @param string $migrationsPath 
900      * @return void
901      * @throws new Doctrine_Migration_Exception
902      */
903     public static function generateMigrationsFromDb($migrationsPath)
904     {
905         $builder = new Doctrine_Migration_Builder($migrationsPath);
906         
907         return $builder->generateMigrationsFromDb();
908     }
909
910     /**
911      * generateMigrationsFromModels
912      *
913      * @param string $migrationsPath 
914      * @param string $modelsPath 
915      * @return void
916      */
917     public static function generateMigrationsFromModels($migrationsPath, $modelsPath = null)
918     {
919         $builder = new Doctrine_Migration_Builder($migrationsPath);
920         
921         return $builder->generateMigrationsFromModels($modelsPath);
922     }
923
924     /**
925      * getTable
926      *
927      * @param string $tableName 
928      * @return void
929      */
930     public static function getTable($tableName)
931     {
932         return Doctrine_Manager::table($tableName);
933     }
934
935     /**
936      * connection
937      *
938      * @param string $adapter 
939      * @param string $name 
940      * @return void
941      */
942     public static function connection($adapter, $name = null)
943     {
944         return Doctrine_Manager::connection($adapter, $name);
945     }
946
947     /**
948      * fileFinder
949      *
950      * @param string $type 
951      * @return void
952      */
953     public static function fileFinder($type)
954     {
955         return Doctrine_FileFinder::type($type);
956     }
957
958     /**
959      * compile
960      * method for making a single file of most used doctrine runtime components
961      * including the compiled file instead of multiple files (in worst
962      * cases dozens of files) can improve performance by an order of magnitude
963      *
964      * @param string $target
965      *
966      * @throws Doctrine_Exception
967      * @return void
968      */
969     public static function compile($target = null, $includedDrivers = array())
970     {
971         return Doctrine_Compiler::compile($target, $includedDrivers);
972     }
973
974     /**
975      * simple autoload function
976      * returns true if the class was loaded, otherwise false
977      *
978      * @param string $classname
979      * @return boolean
980      */
981     public static function autoload($classname)
982     {
983         if (class_exists($classname, false)) {
984             return false;
985         }
986         
987         if ( ! self::$_path) {
988             self::$_path = dirname(__FILE__);
989         }
990         
991         $class = self::$_path . DIRECTORY_SEPARATOR . str_replace('_', DIRECTORY_SEPARATOR, $classname) . '.php';
992
993         if ( ! file_exists($class)) {
994             return false;
995         }
996
997         require_once($class);
998
999         return true;
1000     }
1001
1002     /**
1003      * dump
1004      *
1005      * dumps a given variable
1006      *
1007      * @param mixed $var        a variable of any type
1008      * @param boolean $output   whether to output the content
1009      * @return void|string
1010      */
1011     public static function dump($var, $output = true)
1012     {
1013         $ret = array();
1014         switch (gettype($var)) {
1015             case 'array':
1016                 $ret[] = 'Array(';
1017                 foreach ($var as $k => $v) {
1018                     $ret[] = $k . ' : ' . self::dump($v, false);
1019                 }
1020                 $ret[] = ")";
1021                 break;
1022             case 'object':
1023                 $ret[] = 'Object(' . get_class($var) . ')';
1024                 break;
1025             default:
1026                 $ret[] = var_export($var, true);
1027         }
1028         if ($output) {
1029             print implode("\n", $ret);
1030         }
1031         return implode("\n", $ret);
1032     }
1033
1034     /**
1035      * returns table name from class name
1036      *
1037      * @param string $classname
1038      * @return string
1039      */
1040     public static function tableize($classname)
1041     {
1042          return strtolower(preg_replace('~(?<=\\w)([A-Z])~', '_$1', $classname));
1043     }
1044
1045     /**
1046      * returns class name from table name
1047      *
1048      * @param string $tablename
1049      * @return string
1050      */
1051     public static function classify($tablename)
1052     {
1053         return preg_replace_callback('~(_?)(_)([\w])~', array("Doctrine", "classifyCallback"), ucfirst($tablename));
1054     }
1055
1056     /**
1057      * Callback function to classify a classname propperly. 
1058      *
1059      * @param array $matches An array of matches from a pcre_replace call
1060      * @return string A string with matches 1 and mathces 3 in upper case. 
1061      */
1062     public static function classifyCallback($matches)
1063     {
1064         return $matches[1] . strtoupper($matches[3]);
1065     }
1066
1067     /**
1068      * checks for valid class name (uses camel case and underscores)
1069      *
1070      * @param string $classname
1071      * @return boolean
1072      */
1073     public static function isValidClassname($classname)
1074     {
1075         if (preg_match('~(^[a-z])|(_[a-z])|([\W])|(_{2})~', $classname)) {
1076             return false;
1077         }
1078
1079         return true;
1080     }
1081 }