Coverage for Doctrine

Back to coverage report

1 <?php
2 /*
3  *  $Id: Doctrine.php 2814 2007-10-11 04:24:01Z 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: 2814 $
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      * ATTRIBUTE CONSTANTS
120      */
121
122     /**
123      * PDO derived attributes
124      */
125     const ATTR_AUTOCOMMIT           = 0;
126     const ATTR_PREFETCH             = 1;
127     const ATTR_TIMEOUT              = 2;
128     const ATTR_ERRMODE              = 3;
129     const ATTR_SERVER_VERSION       = 4;
130     const ATTR_CLIENT_VERSION       = 5;
131     const ATTR_SERVER_INFO          = 6;
132     const ATTR_CONNECTION_STATUS    = 7;
133     const ATTR_CASE                 = 8;
134     const ATTR_CURSOR_NAME          = 9;
135     const ATTR_CURSOR               = 10;
136     const ATTR_ORACLE_NULLS         = 11;
137     const ATTR_PERSISTENT           = 12;
138     const ATTR_STATEMENT_CLASS      = 13;
139     const ATTR_FETCH_TABLE_NAMES    = 14;
140     const ATTR_FETCH_CATALOG_NAMES  = 15;
141     const ATTR_DRIVER_NAME          = 16;
142     const ATTR_STRINGIFY_FETCHES    = 17;
143     const ATTR_MAX_COLUMN_LEN       = 18;
144
145     /**
146      * Doctrine constants
147      */
148     const ATTR_LISTENER             = 100;
149     const ATTR_QUOTE_IDENTIFIER     = 101;
150     const ATTR_FIELD_CASE           = 102;
151     const ATTR_IDXNAME_FORMAT       = 103;
152     const ATTR_SEQNAME_FORMAT       = 104;
153     const ATTR_SEQCOL_NAME          = 105;
154     const ATTR_CMPNAME_FORMAT       = 118;
155     const ATTR_DBNAME_FORMAT        = 117;
156     const ATTR_TBLCLASS_FORMAT      = 119;
157     const ATTR_EXPORT               = 140;
158     const ATTR_DECIMAL_PLACES       = 141;
159
160     const ATTR_PORTABILITY          = 106;
161     const ATTR_VALIDATE             = 107;
162     const ATTR_COLL_KEY             = 108;
163     const ATTR_QUERY_LIMIT          = 109;
164     const ATTR_DEFAULT_TABLE_TYPE   = 112;
165     const ATTR_DEF_TEXT_LENGTH      = 113;
166     const ATTR_DEF_VARCHAR_LENGTH   = 114;
167     const ATTR_DEF_TABLESPACE       = 115;
168     const ATTR_EMULATE_DATABASE     = 116;
169     const ATTR_USE_NATIVE_ENUM      = 117;
170     const ATTR_DEFAULT_SEQUENCE     = 133;
171
172     const ATTR_FETCHMODE            = 118;
173     const ATTR_NAME_PREFIX          = 121;
174     const ATTR_CREATE_TABLES        = 122;
175     const ATTR_COLL_LIMIT           = 123;
176
177     const ATTR_CACHE                = 150;
178     const ATTR_CACHE_LIFESPAN       = 151;
179     const ATTR_LOAD_REFERENCES      = 153;
180     const ATTR_RECORD_LISTENER      = 154;
181     const ATTR_THROW_EXCEPTIONS     = 155;
182
183
184     /**
185      * LIMIT CONSTANTS
186      */
187
188     /**
189      * constant for row limiting
190      */
191     const LIMIT_ROWS       = 1;
192     /**
193      * constant for record limiting
194      */
195     const LIMIT_RECORDS    = 2;
196
197     /**
198      * FETCHMODE CONSTANTS
199      */
200
201     /**
202      * IMMEDIATE FETCHING
203      * mode for immediate fetching
204      */
205     const FETCH_IMMEDIATE       = 0;
206     /**
207      * BATCH FETCHING
208      * mode for batch fetching
209      */
210     const FETCH_BATCH           = 1;
211     /**
212      * LAZY FETCHING
213      * mode for offset fetching
214      */
215     const FETCH_OFFSET          = 3;
216     /**
217      * LAZY OFFSET FETCHING
218      * mode for lazy offset fetching
219      */
220     const FETCH_LAZY_OFFSET     = 4;
221
222     /**
223      * FETCH CONSTANTS
224      */
225
226
227     /**
228      * FETCH VALUEHOLDER
229      */
230     const FETCH_VHOLDER         = 1;
231     /**
232      * FETCH RECORD
233      *
234      * Specifies that the fetch method shall return Doctrine_Record
235      * objects as the elements of the result set.
236      *
237      * This is the default fetchmode.
238      */
239     const FETCH_RECORD          = 2;
240     /**
241      * FETCH ARRAY
242      */
243
244     const FETCH_ARRAY           = 3;
245     /**
246      * PORTABILITY CONSTANTS
247      */
248
249     /**
250      * Portability: turn off all portability features.
251      * @see Doctrine::ATTR_PORTABILITY
252      */
253     const PORTABILITY_NONE          = 0;
254     /**
255      * Portability: convert names of tables and fields to case defined in the
256      * "field_case" option when using the query*(), fetch*() methods.
257      * @see Doctrine::ATTR_PORTABILITY
258      */
259     const PORTABILITY_FIX_CASE      = 1;
260
261     /**
262      * Portability: right trim the data output by query*() and fetch*().
263      * @see Doctrine::ATTR_PORTABILITY
264      */
265     const PORTABILITY_RTRIM         = 2;
266     /**
267      * Portability: force reporting the number of rows deleted.
268      * @see Doctrine::ATTR_PORTABILITY
269      */
270     const PORTABILITY_DELETE_COUNT  = 4;
271     /**
272      * Portability: convert empty values to null strings in data output by
273      * query*() and fetch*().
274      * @see Doctrine::ATTR_PORTABILITY
275      */
276     const PORTABILITY_EMPTY_TO_NULL = 8;
277     /**
278      * Portability: removes database/table qualifiers from associative indexes
279      * @see Doctrine::ATTR_PORTABILITY
280      */
281     const PORTABILITY_FIX_ASSOC_FIELD_NAMES = 16;
282     /**
283      * Portability: makes Doctrine_Expression throw exception for unportable RDBMS expressions
284      * @see Doctrine::ATTR_PORTABILITY
285      */
286     const PORTABILITY_EXPR          = 32;
287     /**
288      * Portability: turn on all portability features.
289      * @see Doctrine::ATTR_PORTABILITY
290      */
291     const PORTABILITY_ALL           = 63;
292
293     /**
294      * LOCKMODE CONSTANTS
295      */
296
297     /**
298      * mode for optimistic locking
299      */
300     const LOCK_OPTIMISTIC       = 0;
301     /**
302      * mode for pessimistic locking
303      */
304     const LOCK_PESSIMISTIC      = 1;
305     /**
306      * EXPORT CONSTANTS
307      */
308
309     /**
310      * turns of exporting
311      */
312     const EXPORT_NONE               = 0;
313     /**
314      * export tables
315      */
316     const EXPORT_TABLES             = 1;
317     /**
318      * export constraints
319      */
320     const EXPORT_CONSTRAINTS        = 2;
321     /**
322      * export plugins
323      */
324     const EXPORT_PLUGINS            = 4;
325     /**
326      * export all
327      */
328     const EXPORT_ALL                = 7;
329     
330     /**
331      * HYDRATION CONSTANTS
332      */
333     const HYDRATE_RECORD            = 2;
334     
335     const HYDRATE_ARRAY             = 3;
336
337     /**
338      * VALIDATION CONSTANTS
339      */
340     const VALIDATE_NONE             = 0;
341
342     const VALIDATE_LENGTHS          = 1;
343     
344     const VALIDATE_TYPES            = 2;
345     
346     const VALIDATE_CONSTRAINTS      = 4;
347     
348     const VALIDATE_ALL              = 5;
349
350     /**
351      * constant for auto_increment identifier
352      */
353     const IDENTIFIER_AUTOINC        = 1;
354     /**
355      * constant for sequence identifier
356      */
357     const IDENTIFIER_SEQUENCE       = 2;
358     /**
359      * constant for normal identifier
360      */
361     const IDENTIFIER_NATURAL        = 3;
362     /**
363      * constant for composite identifier
364      */
365     const IDENTIFIER_COMPOSITE      = 4;
366     /**
367      * constructor
368      */
369     public function __construct()
370     {
371         throw new Doctrine_Exception('Doctrine is static class. No instances can be created.');
372     }
373     /**
374      * @var string $path            doctrine root directory
375      */
376     private static $_path;
377     /**
378      * @var boolean $_debug
379      */
380     private static $_debug = false;
381
382     public static function debug($bool = null)
383     {
384         if ($bool !== null) {
385             self::$_debug = (bool) $bool;
386         }
387         return self::$_debug;
388     }
389     /**
390      * getPath
391      * returns the doctrine root
392      *
393      * @return string
394      */
395     public static function getPath()
396     {
397         if ( ! self::$_path) {
398             self::$_path = dirname(__FILE__);
399         }
400         return self::$_path;
401     }
402     /**
403      * loadAll
404      * loads all runtime classes
405      *
406      * @return void
407      */
408     public static function loadAll()
409     {
410         $classes = Doctrine_Compiler::getRuntimeClasses();
411
412         foreach ($classes as $class) {
413             Doctrine::autoload($class);
414         }
415     }
416     /**
417      * loadModels
418      *
419      * Recursively load all models from a directory or array of directories
420      * 
421      * @param string $directory Path to directory of models or array of directory paths
422      * @return void
423      */
424     public static function loadModels($directory)
425     {
426         $declared = get_declared_classes();
427         
428         if ($directory !== null) {
429             foreach ((array) $directory as $dir) {
430                 $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir),
431                                                         RecursiveIteratorIterator::LEAVES_ONLY);
432
433                 foreach ($it as $file) {
434                     $e = explode('.', $file->getFileName());
435                     if (end($e) === 'php' && strpos($file->getFileName(), '.inc') === false) {
436                         require_once $file->getPathName();
437                     }
438                 }
439             }
440             
441             $declared = array_diff(get_declared_classes(), $declared);
442         }
443         
444         return self::getLoadedModels($declared);
445     }
446     /**
447      * getLoadedModels
448      *
449      * Get all the loaded models, you can provide an array of classes or it will use get_declared_classes()
450      * 
451      * @param $classes Array of classes to filter through, otherwise uses get_declared_classes()
452      * @return void
453      */
454     public static function getLoadedModels($classes = null)
455     {
456         if ($classes === null) {
457             $classes = get_declared_classes();
458         }
459         
460         $parent = new ReflectionClass('Doctrine_Record');
461         
462         $loadedModels = array();
463         
464         // we iterate trhough the diff of previously declared classes
465         // and currently declared classes
466         foreach ($classes as $name) {
467             $class = new ReflectionClass($name);
468             
469             // Skip the following classes
470             // - abstract classes
471             // - not a subclass of Doctrine_Record 
472             // - don't have a setTableDefinition method
473             if ($class->isAbstract() || 
474                 !$class->isSubClassOf($parent) || 
475                 !$class->hasMethod('setTableDefinition')) {
476                 continue;
477             }
478             
479             $loadedModels[] = $name;
480         }
481         
482         return $loadedModels;
483     }
484     /**
485      * getConnectionByTableName
486      *
487      * Get the connection object for a table by the actual table name
488      * 
489      * @param string $tableName 
490      * @return void
491      */
492     public static function getConnectionByTableName($tableName)
493     {
494         $loadedModels = self::getLoadedModels();
495         
496         foreach ($loadedModels as $name) {
497             $model = new $name();
498             $table = $model->getTable();
499             
500             if ($table->getTableName() == $tableName) {
501                return $table->getConnection(); 
502             }
503         }
504     }
505     /**
506      * importSchema
507      * method for importing existing schema to Doctrine_Record classes
508      *
509      * @param string $directory Directory to write your models to
510      * @param array $databases Array of databases to generate models for
511      * @return boolean
512      */
513     public static function importSchema($directory, array $databases = array())
514     {
515         return Doctrine_Manager::connection()->import->importSchema($directory, $databases);
516     }
517     /**
518      * generateModelsFromDb
519      *
520      * Generate your model definitions from an existing database
521      *
522      * @param string $directory Directory to write your models to
523      * @param string $databases Array of databases to generate models for
524      * @return void
525      */
526     public static function generateModelsFromDb($directory, array $databases = array())
527     {
528         return self::importSchema($directory, $databases);
529     }
530     /**
531      * generateYamlFromDb
532      *
533      * Generates models from database to temporary location then uses those models to generate a yaml schema file.
534      * This should probably be fixed. We should write something to generate a yaml schema file directly from the database.
535      *
536      * @param string $yamlPath Path to write oyur yaml schema file to
537      * @return void
538      */
539     public static function generateYamlFromDb($yamlPath)
540     {
541         $directory = '/tmp/tmp_doctrine_models';
542
543         Doctrine::generateModelsFromDb($directory);
544
545         $export = new Doctrine_Export_Schema();
546         
547         return $export->exportSchema($yamlPath, 'yml', $directory);
548     }
549     /**
550      * generateModelsFromYaml
551      *
552      * Generate a yaml schema file from an existing directory of models
553      *
554      * @param string $yamlPath Path to your yaml schema files
555      * @param string $directory Directory to generate your models in
556      * @return void
557      */
558     public static function generateModelsFromYaml($yamlPath, $directory)
559     {
560         $import = new Doctrine_Import_Schema();
561         
562         return $import->importSchema($yamlPath, 'yml', $directory);
563     }
564     /**
565      * exportSchema
566      * method for exporting Doctrine_Record classes to a schema
567      *
568      * @param string $directory Directory containing your models
569      * @return void
570      */
571     public static function exportSchema($directory = null)
572     {
573         return Doctrine_Manager::connection()->export->exportSchema($directory);
574     }
575     /**
576      * createTablesFromModels
577      *
578      * Creates database tables for the models in the specified directory
579      *
580      * @param string $directory Directory containing your models
581      * @return void
582      */
583     public static function createTablesFromModels($directory = null)
584     {
585         return self::exportSchema($directory);
586     }
587     /**
588      * generateYamlFromModels
589      *
590      * Generate yaml schema file for the models in the specified directory
591      *
592      * @param string $yamlPath Path to your yaml schema files
593      * @param string $directory Directory to generate your models in
594      * @return void
595      */
596     public static function generateYamlFromModels($yamlPath, $directory)
597     {
598         $export = new Doctrine_Export_Schema();
599         
600         return $export->exportSchema($yamlPath, 'yml', $directory);
601     }
602     /**
603      * createDatabases
604      *
605      * Creates databases for connections
606      *
607      * @param string $specifiedConnections Array of connections you wish to create the database for
608      * @return void
609      */
610     public static function createDatabases($specifiedConnections)
611     {
612         if (!is_array($specifiedConnections)) {
613             $specifiedConnections = (array) $specifiedConnections;
614         }
615         
616         $connections = Doctrine_Manager::getInstance()->getConnections();
617         
618         foreach ($connections as $name => $connection) {
619             if (!empty($specifiedConnections) && !in_array($name, $specifiedConnections)) {
620                 continue;
621             }
622             
623             $connection->export->createDatabase($name);
624         }
625     }
626     /**
627      * dropDatabases
628      *
629      * Drops databases for connections
630      *
631      * @param string $specifiedConnections Array of connections you wish to drop the database for
632      * @return void
633      */
634     public static function dropDatabases($specifiedConnections = array())
635     {
636         if (!is_array($specifiedConnections)) {
637             $specifiedConnections = (array) $specifiedConnections;
638         }
639         
640         $connections = Doctrine_Manager::getInstance()->getConnections();
641         
642         foreach ($connections as $name => $connection) {
643             if (!empty($specifiedConnections) && !in_array($name, $specifiedConnections)) {
644                 continue;
645             }
646             
647             $connection->export->dropDatabase($name);
648         }
649     }
650     /**
651      * dumpData
652      *
653      * Dump data to a yaml fixtures file
654      *
655      * @param string $yamlPath Path to write the yaml data fixtures to
656      * @param string $individualFiles Whether or not to dump data to individual fixtures files
657      * @return void
658      */
659     public static function dumpData($yamlPath, $individualFiles = false)
660     {
661         $data = new Doctrine_Data();
662         
663         return $data->exportData($yamlPath, 'yml', array(), $individualFiles);
664     }
665     /**
666      * loadData
667      *
668      * Load data from a yaml fixtures file.
669      * The output of dumpData can be fed to loadData
670      *
671      * @param string $yamlPath Path to your yaml data fixtures
672      * @param string $append Whether or not to append the data
673      * @return void
674      */
675     public static function loadData($yamlPath, $append = false)
676     {
677         $delete = isset($append) ? ($append ? false : true) : true;
678
679         if ($delete)
680         {
681           $models = Doctrine::getLoadedModels();
682
683           foreach ($models as $model)
684           {
685             $model = new $model();
686
687             $model->getTable()->createQuery()->delete($model)->execute();
688           }
689         }
690
691         $data = new Doctrine_Data();
692         
693         return $data->importData($yamlPath, 'yml');
694     }
695     /**
696      * loadDummyData
697      *
698      * Populdate your models with dummy data
699      *
700      * @param string $append Whether or not to append the data
701      * @param string $num Number of records to populate
702      * @return void
703      */
704     public static function loadDummyData($append, $num = 5)
705     {
706         $delete = isset($append) ? ($append ? false : true) : true;
707
708         if ($delete)
709         {
710           $models = Doctrine::getLoadedModels();
711
712           foreach ($models as $model)
713           {
714             $model = new $model();
715
716             $model->getTable()->createQuery()->delete($model)->execute();
717           }
718         }
719         
720         $data = new Doctrine_Data();
721         
722         return $data->importDummyData($num);
723     }
724     /**
725      * migrate
726      * 
727      * Migrate database to specified $to version. Migrates from current to latest if you do not specify.
728      *
729      * @param string $directory Directory which contains your migration classes
730      * @param string $to Version you wish to migrate to.
731      * @return void
732      */
733     public static function migrate($directory, $to = null)
734     {
735         $migration = new Doctrine_Migration($directory);
736         
737         return $migration->migrate($to);
738     }
739     /**
740      * generateMigrationClass
741      *
742      * Generate new migration class skeleton
743      *
744      * @param string $className Name of the Migration class to generate
745      * @param string $directory Directory which contains your migration classes
746      * @package default
747      */
748     public static function generateMigrationClass($className, $directory)
749     {
750         $migration = new Doctrine_Migration($directory);
751         $next = (string) $migration->getNextVersion();
752         
753         $fileName = str_repeat('0', (3 - strlen($next))) . $next . '_' . Doctrine::tableize($className) . '.class.php';
754         $path = $directory . DIRECTORY_SEPARATOR . $fileName;
755         
756         $code  = '<?php' . PHP_EOL;
757         $code .= "// Automatically generated by Doctrine\n";
758         $code .= "class " . $className . " extends Doctrine_Migration\n";
759         $code .= "{\n";
760         $code .= "\tpublic function up()\n\t{ }\n\n";
761         $code .= "\tpublic function down()\n\t{ }\n";
762         $code .= "}";
763         
764         file_put_contents($path, $code);
765     }
766     /**
767      * exportSql
768      * method for exporting Doctrine_Record classes to a schema
769      *
770      * @param string $directory
771      */
772     public static function exportSql($directory = null)
773     {
774         return Doctrine_Manager::connection()->export->exportSql($directory);
775     }
776     /**
777      * generateSqlFromModels
778      *
779      * Generate sql for directory of models
780      *
781      * @param string $directory Directory where your models exist
782      * @return void
783      */
784     public static function generateSqlFromModels($directory)
785     {
786         return self::exportSql($directory);
787     }
788     /**
789      * compile
790      * method for making a single file of most used doctrine runtime components
791      * including the compiled file instead of multiple files (in worst
792      * cases dozens of files) can improve performance by an order of magnitude
793      *
794      * @param string $target
795      *
796      * @throws Doctrine_Exception
797      * @return void
798      */
799     public static function compile($target = null)
800     {
801         Doctrine_Compiler::compile($target);
802     }
803     /**
804      * simple autoload function
805      * returns true if the class was loaded, otherwise false
806      *
807      * @param string $classname
808      * @return boolean
809      */
810     public static function autoload($classname)
811     {
812         if (class_exists($classname, false)) {
813             return false;
814         }
815         if ( ! self::$_path) {
816             self::$_path = dirname(__FILE__);
817         }
818         $class = self::$_path . DIRECTORY_SEPARATOR . str_replace('_', DIRECTORY_SEPARATOR,$classname) . '.php';
819
820         if ( ! file_exists($class)) {
821             return false;
822         }
823
824         require_once($class);
825
826         return true;
827     }
828     /**
829      * dump
830      *
831      * dumps a given variable
832      *
833      * @param mixed $var        a variable of any type
834      * @param boolean $output   whether to output the content
835      * @return void|string
836      */
837     public static function dump($var, $output = true)
838     {
839         $ret = array();
840         switch (gettype($var)) {
841             case 'array':
842                 $ret[] = 'Array(';
843                 foreach ($var as $k => $v) {
844                     $ret[] = $k . ' : ' . Doctrine::dump($v, false);
845                 }
846                 $ret[] = ")";
847                 break;
848             case 'object':
849                 $ret[] = 'Object(' . get_class($var) . ')';
850                 break;
851             default:
852                 $ret[] = var_export($var, true);
853         }
854         if ($output) {
855             print implode("\n", $ret);
856         }
857         return implode("\n", $ret);
858     }
859     /**
860      * returns table name from class name
861      *
862      * @param string $classname
863      * @return string
864      */
865     public static function tableize($classname)
866     {
867          return strtolower(preg_replace('~(?<=\\w)([A-Z])~', '_$1', $classname));
868     }
869     /**
870      * returns class name from table name
871      *
872      * @param string $tablename
873      * @return string
874      */
875     public static function classify($tablename)
876     {
877         return preg_replace_callback('~(_?)(_)([\w])~', array("Doctrine", "classifyCallback"), ucfirst($tablename));
878     }
879
880     /**
881      * Callback function to classify a classname propperly. 
882      *
883      * @param array $matches An array of matches from a pcre_replace call
884      * @return string A string with matches 1 and mathces 3 in upper case. 
885      */
886     public static function classifyCallback($matches)
887     {
888         return $matches[1] . strtoupper($matches[3]);
889     }
890     /**
891      * checks for valid class name (uses camel case and underscores)
892      *
893      * @param string $classname
894      * @return boolean
895      */
896     public static function isValidClassname($classname)
897     {
898         if (preg_match('~(^[a-z])|(_[a-z])|([\W])|(_{2})~', $classname)) {
899             return false;
900         }
901
902         return true;
903     }
904 }