Doctrine.php 16 KB
Newer Older
lsmith's avatar
lsmith committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
<?php
/*
 *  $Id$
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * This software consists of voluntary contributions made by many individuals
 * and is licensed under the LGPL. For more information, see
 * <http://www.phpdoctrine.com>.
 */

/**
 * Doctrine
 * the base class of Doctrine framework
 *
 * @package     Doctrine
 * @author      Konsta Vesterinen <kvesteri@cc.hut.fi>
 * @author      Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
 * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
 * @category    Object Relational Mapping
 * @link        www.phpdoctrine.com
 * @since       1.0
 * @version     $Revision$
 */
lsmith's avatar
lsmith committed
35 36 37
final class Doctrine
{
    /**
lsmith's avatar
lsmith committed
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
     * ERROR CONSTANTS
     */
    const ERR                       = -1;
    const ERR_SYNTAX                = -2;
    const ERR_CONSTRAINT            = -3;
    const ERR_NOT_FOUND             = -4;
    const ERR_ALREADY_EXISTS        = -5;
    const ERR_UNSUPPORTED           = -6;
    const ERR_MISMATCH              = -7;
    const ERR_INVALID               = -8;
    const ERR_NOT_CAPABLE           = -9;
    const ERR_TRUNCATED             = -10;
    const ERR_INVALID_NUMBER        = -11;
    const ERR_INVALID_DATE          = -12;
    const ERR_DIVZERO               = -13;
    const ERR_NODBSELECTED          = -14;
    const ERR_CANNOT_CREATE         = -15;
    const ERR_CANNOT_DELETE         = -16;
    const ERR_CANNOT_DROP           = -17;
    const ERR_NOSUCHTABLE           = -18;
    const ERR_NOSUCHFIELD           = -19;
    const ERR_NEED_MORE_DATA        = -20;
    const ERR_NOT_LOCKED            = -21;
    const ERR_VALUE_COUNT_ON_ROW    = -22;
    const ERR_INVALID_DSN           = -23;
    const ERR_CONNECT_FAILED        = -24;
    const ERR_EXTENSION_NOT_FOUND   = -25;
    const ERR_NOSUCHDB              = -26;
    const ERR_ACCESS_VIOLATION      = -27;
    const ERR_CANNOT_REPLACE        = -28;
    const ERR_CONSTRAINT_NOT_NULL   = -29;
    const ERR_DEADLOCK              = -30;
    const ERR_CANNOT_ALTER          = -31;
    const ERR_MANAGER               = -32;
    const ERR_MANAGER_PARSE         = -33;
    const ERR_LOADMODULE            = -34;
    const ERR_INSUFFICIENT_DATA     = -35;
    const ERR_CLASS_NAME            = -36;
76

77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
    /**
     * PDO derived constants
     */
    const CASE_LOWER = 2;
    const CASE_NATURAL = 0;
    const CASE_UPPER = 1;
    const CURSOR_FWDONLY = 0;
    const CURSOR_SCROLL = 1;
    const ERRMODE_EXCEPTION = 2;
    const ERRMODE_SILENT = 0;
    const ERRMODE_WARNING = 1;
    const FETCH_ASSOC = 2;
    const FETCH_BOTH = 4;
    const FETCH_BOUND = 6;
    const FETCH_CLASS = 8;
    const FETCH_CLASSTYPE = 262144;
    const FETCH_COLUMN = 7;
    const FETCH_FUNC = 10;
    const FETCH_GROUP = 65536;
    const FETCH_INTO = 9;
    const FETCH_LAZY = 1;
    const FETCH_NAMED = 11;
    const FETCH_NUM = 3;
    const FETCH_OBJ = 5;
    const FETCH_ORI_ABS = 4;
    const FETCH_ORI_FIRST = 2;
    const FETCH_ORI_LAST = 3;
    const FETCH_ORI_NEXT = 0;
    const FETCH_ORI_PRIOR = 1;
    const FETCH_ORI_REL = 5;
    const FETCH_SERIALIZE = 524288;
    const FETCH_UNIQUE = 196608;
    const NULL_EMPTY_STRING = 1;
    const NULL_NATURAL = 0;
111
    const NULL_TO_STRING         = NULL;
112 113 114 115 116 117 118
    const PARAM_BOOL = 5;
    const PARAM_INPUT_OUTPUT = -2147483648;
    const PARAM_INT = 1;
    const PARAM_LOB = 3;
    const PARAM_NULL = 0;
    const PARAM_STMT = 4;
    const PARAM_STR = 2;
lsmith's avatar
lsmith committed
119 120 121
    /**
     * ATTRIBUTE CONSTANTS
     */
122

123 124 125 126 127
    /**
     * PDO derived attributes
     */
    const ATTR_AUTOCOMMIT           = 0;
    const ATTR_PREFETCH             = 1;
128
    const ATTR_TIMEOUT              = 2;
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
    const ATTR_ERRMODE              = 3;
    const ATTR_SERVER_VERSION       = 4;
    const ATTR_CLIENT_VERSION       = 5;
    const ATTR_SERVER_INFO          = 6;
    const ATTR_CONNECTION_STATUS    = 7;
    const ATTR_CASE                 = 8;
    const ATTR_CURSOR_NAME          = 9;
    const ATTR_CURSOR               = 10;
    const ATTR_ORACLE_NULLS         = 11;
    const ATTR_PERSISTENT           = 12;
    const ATTR_STATEMENT_CLASS      = 13;
    const ATTR_FETCH_TABLE_NAMES    = 14;
    const ATTR_FETCH_CATALOG_NAMES  = 15;
    const ATTR_DRIVER_NAME          = 16;
    const ATTR_STRINGIFY_FETCHES    = 17;
    const ATTR_MAX_COLUMN_LEN       = 18;
zYne's avatar
zYne committed
145

146 147 148 149 150 151 152 153
    /**
     * Doctrine constants
     */
    const ATTR_LISTENER             = 100;
    const ATTR_QUOTE_IDENTIFIER     = 101;
    const ATTR_FIELD_CASE           = 102;
    const ATTR_IDXNAME_FORMAT       = 103;
    const ATTR_SEQNAME_FORMAT       = 104;
zYne's avatar
zYne committed
154
    const ATTR_SEQCOL_NAME          = 105;
155 156 157
    const ATTR_CMPNAME_FORMAT       = 118;
    const ATTR_DBNAME_FORMAT        = 117;
    const ATTR_TBLCLASS_FORMAT      = 119;
zYne's avatar
zYne committed
158
    const ATTR_EXPORT               = 140;
159
    const ATTR_DECIMAL_PLACES       = 141;
160

161
    const ATTR_PORTABILITY          = 106;
162
    const ATTR_VALIDATE             = 107;
163 164 165 166 167 168 169
    const ATTR_COLL_KEY             = 108;
    const ATTR_QUERY_LIMIT          = 109;
    const ATTR_DEFAULT_TABLE_TYPE   = 112;
    const ATTR_DEF_TEXT_LENGTH      = 113;
    const ATTR_DEF_VARCHAR_LENGTH   = 114;
    const ATTR_DEF_TABLESPACE       = 115;
    const ATTR_EMULATE_DATABASE     = 116;
170
    const ATTR_USE_NATIVE_ENUM      = 117;
zYne's avatar
zYne committed
171
    const ATTR_DEFAULT_SEQUENCE     = 133;
lsmith's avatar
lsmith committed
172

lsmith's avatar
lsmith committed
173 174
    /** TODO: REMOVE THE FOLLOWING CONSTANTS AND UPDATE THE DOCS ! */

175 176 177
    const ATTR_VLD                  = -1;
    const ATTR_AUTO_LENGTH_VLD      = -2;
    const ATTR_AUTO_TYPE_VLD        = -3;
178 179 180 181 182 183 184 185 186
    const ATTR_FETCHMODE            = 118;
    const ATTR_BATCH_SIZE           = 119;
    const ATTR_LOCKMODE             = 120;
    const ATTR_NAME_PREFIX          = 121;
    const ATTR_CREATE_TABLES        = 122;
    const ATTR_COLL_LIMIT           = 123;
    const ATTR_ACCESSORS            = 124;
    const ATTR_ACCESSOR_PREFIX_GET  = 125;
    const ATTR_ACCESSOR_PREFIX_SET  = 126;
lsmith's avatar
lsmith committed
187

188 189 190 191 192 193 194
    /**
     * NESTED SET CONSTANTS
     */
    const ATTR_NS_ROOT_COLUMN_NAME  = 130;
    const ATTR_NS_GAP_SIZE          = 131;
    const ATTR_NS_GAP_DECREASE_EXP  = 132;

zYne's avatar
zYne committed
195
    const ATTR_CACHE                = 150;
zYne's avatar
zYne committed
196
    const ATTR_CACHE_LIFESPAN       = 151;
zYne's avatar
zYne committed
197
    const ATTR_LOAD_REFERENCES      = 153;
198
    const ATTR_RECORD_LISTENER      = 154;
zYne's avatar
zYne committed
199 200
    const ATTR_THROW_EXCEPTIONS     = 155;

lsmith's avatar
lsmith committed
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251

    /**
     * LIMIT CONSTANTS
     */

    /**
     * constant for row limiting
     */
    const LIMIT_ROWS       = 1;
    /**
     * constant for record limiting
     */
    const LIMIT_RECORDS    = 2;

    /**
     * FETCHMODE CONSTANTS
     */

    /**
     * IMMEDIATE FETCHING
     * mode for immediate fetching
     */
    const FETCH_IMMEDIATE       = 0;
    /**
     * BATCH FETCHING
     * mode for batch fetching
     */
    const FETCH_BATCH           = 1;
    /**
     * LAZY FETCHING
     * mode for offset fetching
     */
    const FETCH_OFFSET          = 3;
    /**
     * LAZY OFFSET FETCHING
     * mode for lazy offset fetching
     */
    const FETCH_LAZY_OFFSET     = 4;

    /**
     * FETCH CONSTANTS
     */


    /**
     * FETCH VALUEHOLDER
     */
    const FETCH_VHOLDER         = 1;
    /**
     * FETCH RECORD
     *
lsmith's avatar
lsmith committed
252
     * Specifies that the fetch method shall return Doctrine_Record
lsmith's avatar
lsmith committed
253 254 255 256 257 258
     * objects as the elements of the result set.
     *
     * This is the default fetchmode.
     */
    const FETCH_RECORD          = 2;
    /**
lsmith's avatar
lsmith committed
259
     * FETCH ARRAY
lsmith's avatar
lsmith committed
260 261 262 263 264 265 266 267 268 269 270
     */

    const FETCH_ARRAY           = 3;
    /**
     * PORTABILITY CONSTANTS
     */

    /**
     * Portability: turn off all portability features.
     * @see Doctrine::ATTR_PORTABILITY
     */
zYne's avatar
zYne committed
271
    const PORTABILITY_NONE          = 0;
lsmith's avatar
lsmith committed
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299
    /**
     * Portability: convert names of tables and fields to case defined in the
     * "field_case" option when using the query*(), fetch*() methods.
     * @see Doctrine::ATTR_PORTABILITY
     */
    const PORTABILITY_FIX_CASE      = 1;

    /**
     * Portability: right trim the data output by query*() and fetch*().
     * @see Doctrine::ATTR_PORTABILITY
     */
    const PORTABILITY_RTRIM         = 2;
    /**
     * Portability: force reporting the number of rows deleted.
     * @see Doctrine::ATTR_PORTABILITY
     */
    const PORTABILITY_DELETE_COUNT  = 4;
    /**
     * Portability: convert empty values to null strings in data output by
     * query*() and fetch*().
     * @see Doctrine::ATTR_PORTABILITY
     */
    const PORTABILITY_EMPTY_TO_NULL = 8;
    /**
     * Portability: removes database/table qualifiers from associative indexes
     * @see Doctrine::ATTR_PORTABILITY
     */
    const PORTABILITY_FIX_ASSOC_FIELD_NAMES = 16;
zYne's avatar
zYne committed
300 301 302 303 304
    /**
     * Portability: makes Doctrine_Expression throw exception for unportable RDBMS expressions
     * @see Doctrine::ATTR_PORTABILITY
     */
    const PORTABILITY_EXPR          = 32;
lsmith's avatar
lsmith committed
305 306 307 308
    /**
     * Portability: turn on all portability features.
     * @see Doctrine::ATTR_PORTABILITY
     */
zYne's avatar
zYne committed
309
    const PORTABILITY_ALL           = 33;
lsmith's avatar
lsmith committed
310 311 312 313 314 315 316 317 318 319 320 321 322

    /**
     * LOCKMODE CONSTANTS
     */

    /**
     * mode for optimistic locking
     */
    const LOCK_OPTIMISTIC       = 0;
    /**
     * mode for pessimistic locking
     */
    const LOCK_PESSIMISTIC      = 1;
zYne's avatar
zYne committed
323 324 325
    /**
     * EXPORT CONSTANTS
     */
326

zYne's avatar
zYne committed
327 328 329 330 331
    /**
     * turns of exporting
     */
    const EXPORT_NONE               = 0;
    /**
zYne's avatar
zYne committed
332
     * export tables
zYne's avatar
zYne committed
333
     */
zYne's avatar
zYne committed
334
    const EXPORT_TABLES             = 1;
zYne's avatar
zYne committed
335
    /**
zYne's avatar
zYne committed
336
     * export constraints
zYne's avatar
zYne committed
337
     */
zYne's avatar
zYne committed
338
    const EXPORT_CONSTRAINTS        = 2;
zYne's avatar
zYne committed
339 340 341
    /**
     * export all
     */
342
    const EXPORT_ALL                = 3;
zYne's avatar
zYne committed
343
    
zYne's avatar
zYne committed
344

zYne's avatar
zYne committed
345 346 347 348 349 350 351 352 353 354 355 356
    /**
     * VALIDATION CONSTANTS
     */
    const VALIDATE_NONE             = 0;

    const VALIDATE_LENGTHS          = 1;
    
    const VALIDATE_TYPES            = 2;
    
    const VALIDATE_CONSTRAINTS      = 4;
    
    const VALIDATE_ALL              = 5;
zYne's avatar
zYne committed
357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373

    /**
     * constant for auto_increment identifier
     */
    const IDENTIFIER_AUTOINC        = 1;
    /**
     * constant for sequence identifier
     */
    const IDENTIFIER_SEQUENCE       = 2;
    /**
     * constant for normal identifier
     */
    const IDENTIFIER_NATURAL        = 3;
    /**
     * constant for composite identifier
     */
    const IDENTIFIER_COMPOSITE      = 4;
lsmith's avatar
lsmith committed
374 375 376
    /**
     * constructor
     */
lsmith's avatar
lsmith committed
377 378
    public function __construct()
    {
lsmith's avatar
lsmith committed
379 380 381 382 383 384
        throw new Doctrine_Exception('Doctrine is static class. No instances can be created.');
    }
    /**
     * @var string $path            doctrine root directory
     */
    private static $path;
zYne's avatar
zYne committed
385 386 387 388 389 390 391 392 393 394 395 396
    /**
     * @var boolean $_debug
     */
    private static $_debug = false;

    public static function debug($bool = null)
    {
        if ($bool !== null) {
            self::$_debug = (bool) $bool;
        }
        return self::$_debug;
    }
lsmith's avatar
lsmith committed
397 398 399 400 401 402
    /**
     * getPath
     * returns the doctrine root
     *
     * @return string
     */
lsmith's avatar
lsmith committed
403 404
    public static function getPath()
    {
zYne's avatar
zYne committed
405
        if ( ! self::$path) {
lsmith's avatar
lsmith committed
406 407 408 409 410 411 412 413 414 415
            self::$path = dirname(__FILE__);
        }
        return self::$path;
    }
    /**
     * loadAll
     * loads all runtime classes
     *
     * @return void
     */
lsmith's avatar
lsmith committed
416 417
    public static function loadAll()
    {
lsmith's avatar
lsmith committed
418 419 420 421 422 423 424
        $classes = Doctrine_Compiler::getRuntimeClasses();

        foreach ($classes as $class) {
            Doctrine::autoload($class);
        }
    }
    /**
425
     * importSchema
lsmith's avatar
lsmith committed
426 427 428
     * method for importing existing schema to Doctrine_Record classes
     *
     * @param string $directory
zYne's avatar
zYne committed
429 430
     * @param array $info
     * @return boolean
lsmith's avatar
lsmith committed
431
     */
432
    public static function importSchema($directory, array $databases = array())
lsmith's avatar
lsmith committed
433
    {
434
        return Doctrine_Manager::connection()->import->importSchema($directory, $databases);
lsmith's avatar
lsmith committed
435 436
    }
    /**
437
     * exportSchema
lsmith's avatar
lsmith committed
438 439 440 441
     * method for exporting Doctrine_Record classes to a schema
     *
     * @param string $directory
     */
442
    public static function exportSchema($directory = null)
lsmith's avatar
lsmith committed
443
    {
444
        return Doctrine_Manager::connection()->export->exportSchema($directory);
zYne's avatar
zYne committed
445 446 447 448 449 450 451
    }
    /**
     * exportSql
     * method for exporting Doctrine_Record classes to a schema
     *
     * @param string $directory
     */
zYne's avatar
zYne committed
452
    public static function exportSql($directory = null)
zYne's avatar
zYne committed
453 454
    {
        return Doctrine_Manager::connection()->export->exportSql($directory);
lsmith's avatar
lsmith committed
455 456 457 458 459 460 461
    }
    /**
     * compile
     * method for making a single file of most used doctrine runtime components
     * including the compiled file instead of multiple files (in worst
     * cases dozens of files) can improve performance by an order of magnitude
     *
462 463
     * @param string $target
     *
lsmith's avatar
lsmith committed
464 465 466
     * @throws Doctrine_Exception
     * @return void
     */
467
    public static function compile($target = null)
lsmith's avatar
lsmith committed
468
    {
469
        Doctrine_Compiler::compile($target);
lsmith's avatar
lsmith committed
470 471 472 473 474 475 476 477
    }
    /**
     * simple autoload function
     * returns true if the class was loaded, otherwise false
     *
     * @param string $classname
     * @return boolean
     */
lsmith's avatar
lsmith committed
478
    public static function autoload($classname)
479
    {
zYne's avatar
zYne committed
480
        if (class_exists($classname, false)) {
lsmith's avatar
lsmith committed
481 482
            return false;
        }
483
        if ( ! self::$path) {
lsmith's avatar
lsmith committed
484 485
            self::$path = dirname(__FILE__);
        }
zYne's avatar
zYne committed
486
        $class = self::$path . DIRECTORY_SEPARATOR . str_replace('_', DIRECTORY_SEPARATOR,$classname) . '.php';
lsmith's avatar
lsmith committed
487 488 489 490 491 492 493 494 495

        if ( ! file_exists($class)) {
            return false;
        }

        require_once($class);

        return true;
    }
zYne's avatar
zYne committed
496 497 498 499 500 501
    /**
     * dump
     *
     * dumps a given variable
     *
     * @param mixed $var        a variable of any type
502
     * @param boolean $output   whether to output the content
zYne's avatar
zYne committed
503 504
     * @return void|string
     */
505
    public static function dump($var, $output = true)
zYne's avatar
zYne committed
506
    {
507
        $ret = array();
zYne's avatar
zYne committed
508 509 510 511
        switch (gettype($var)) {
            case 'array':
                $ret[] = 'Array(';
                foreach ($var as $k => $v) {
zYne's avatar
zYne committed
512
                    $ret[] = $k . ' : ' . Doctrine::dump($v, false);
zYne's avatar
zYne committed
513
                }
zYne's avatar
zYne committed
514
                $ret[] = ")";
zYne's avatar
zYne committed
515
                break;
516
            case 'object':
zYne's avatar
zYne committed
517 518 519 520 521
                $ret[] = 'Object(' . get_class($var) . ')';
                break;
            default:
                $ret[] = var_export($var, true);
        }
522 523 524
        if ($output) {
            print implode("\n", $ret);
        }
zYne's avatar
zYne committed
525 526
        return implode("\n", $ret);
    }
lsmith's avatar
lsmith committed
527 528 529 530 531 532
    /**
     * returns table name from class name
     *
     * @param string $classname
     * @return string
     */
lsmith's avatar
lsmith committed
533 534
    public static function tableize($classname)
    {
lsmith's avatar
lsmith committed
535 536 537 538 539 540 541 542
         return strtolower(preg_replace('~(?<=\\w)([A-Z])~', '_$1', $classname));
    }
    /**
     * returns class name from table name
     *
     * @param string $tablename
     * @return string
     */
lsmith's avatar
lsmith committed
543 544
    public static function classify($tablename)
    {
lsmith's avatar
lsmith committed
545 546 547 548 549 550 551 552
        return preg_replace('~(_?)(_)([\w])~e', '"$1".strtoupper("$3")', ucfirst($tablename));
    }
    /**
     * checks for valid class name (uses camel case and underscores)
     *
     * @param string $classname
     * @return boolean
     */
lsmith's avatar
lsmith committed
553 554
    public static function isValidClassname($classname)
    {
zYne's avatar
zYne committed
555
        if (preg_match('~(^[a-z])|(_[a-z])|([\W])|(_{2})~', $classname)) {
lsmith's avatar
lsmith committed
556
            return false;
557
        }
lsmith's avatar
lsmith committed
558 559 560 561

        return true;
    }
}