DBTable.class.php

Go to the documentation of this file.
00001 <?php
00002 /***************************************************************************
00003  *   Copyright (C) 2006-2007 by Konstantin V. Arkhipov                     *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU Lesser General Public License as        *
00007  *   published by the Free Software Foundation; either version 3 of the    *
00008  *   License, or (at your option) any later version.                       *
00009  *                                                                         *
00010  ***************************************************************************/
00011 
00015     final class DBTable implements DialectString
00016     {
00017         private $name       = null;
00018         
00019         private $columns    = array();
00020         private $order      = array();
00021         
00022         private $uniques    = array();
00023         
00027         public static function create($name)
00028         {
00029             return new self($name);
00030         }
00031         
00032         public function __construct($name)
00033         {
00034             $this->name = $name;
00035         }
00036         
00037         public function getColumns()
00038         {
00039             return $this->columns;
00040         }
00041         
00045         public function addUniques(/* ... */)
00046         {
00047             Assert::isTrue(func_num_args() > 0);
00048             
00049             $uniques = array();
00050             
00051             foreach (func_get_args() as $name) {
00052                 // check existence
00053                 $this->getColumnByName($name);
00054                 
00055                 $uniques[] = $name;
00056             }
00057             
00058             $this->uniques[] = $uniques;
00059             
00060             return $this;
00061         }
00062         
00063         public function getUniques()
00064         {
00065             return $this->uniques;
00066         }
00067         
00072         public function addColumn(DBColumn $column)
00073         {
00074             $name = $column->getName();
00075             
00076             Assert::isFalse(
00077                 isset($this->columns[$name]),
00078                 "column '{$name}' already exist"
00079             );
00080             
00081             $this->order[] = $this->columns[$name] = $column;
00082             
00083             $column->setTable($this);
00084             
00085             return $this;
00086         }
00087         
00092         public function getColumnByName($name)
00093         {
00094             if (!isset($this->columns[$name]))
00095                 throw new MissingElementException(
00096                     "column '{$name}' does not exist"
00097                 );
00098             
00099             return $this->columns[$name];
00100         }
00101         
00105         public function dropColumnByName($name)
00106         {
00107             if (!isset($this->columns[$name]))
00108                 throw new MissingElementException(
00109                     "column '{$name}' does not exist"
00110                 );
00111             
00112             unset($this->columns[$name]);
00113             unset($this->order[array_search($name, $this->order)]);
00114             
00115             return $this;
00116         }
00117         
00121         public function setName($name)
00122         {
00123             $this->name = $name;
00124             
00125             return $this;
00126         }
00127         
00128         public function getName()
00129         {
00130             return $this->name;
00131         }
00132         
00133         public function getOrder()
00134         {
00135             return $this->order;
00136         }
00137         
00138         public function toDialectString(Dialect $dialect)
00139         {
00140             return OSQL::createTable($this)->toDialectString($dialect);
00141         }
00142         
00143         // TODO: consider port to AlterTable class (unimplemented yet)
00144         public static function findDifferences(
00145             Dialect $dialect,
00146             DBTable $source,
00147             DBTable $target
00148         )
00149         {
00150             $out = array();
00151             
00152             $head = 'ALTER TABLE '.$dialect->quoteTable($target->getName());
00153             
00154             $sourceColumns = $source->getColumns();
00155             $targetColumns = $target->getColumns();
00156             
00157             foreach ($sourceColumns as $name => $column) {
00158                 if (isset($targetColumns[$name])) {
00159                     if (
00160                         $column->getType()->getId()
00161                         != $targetColumns[$name]->getType()->getId()
00162                     ) {
00163                         $targetColumn = $targetColumns[$name];
00164                         
00165                         $out[] =
00166                             $head
00167                             .' ALTER COLUMN '.$dialect->quoteField($name)
00168                             .' TYPE '.$targetColumn->getType()->toString()
00169                             .(
00170                                 $targetColumn->getType()->hasSize()
00171                                     ?
00172                                         '('
00173                                         .$targetColumn->getType()->getSize()
00174                                         .(
00175                                             $targetColumn->getType()->hasPrecision()
00176                                                 ? ', '.$targetColumn->getType()->getPrecision()
00177                                                 : null
00178                                         )
00179                                         .')'
00180                                     : null
00181                             )
00182                             .';';
00183                     }
00184                     
00185                     if (
00186                         $column->getType()->isNull()
00187                         != $targetColumns[$name]->getType()->isNull()
00188                     ) {
00189                         $out[] =
00190                             $head
00191                             .' ALTER COLUMN '.$dialect->quoteField($name)
00192                             .' '
00193                             .(
00194                                 $targetColumns[$name]->getType()->isNull()
00195                                     ? 'DROP'
00196                                     : 'SET'
00197                             )
00198                             .' NOT NULL;';
00199                     }
00200                 } else {
00201                     $out[] =
00202                         $head
00203                         .' DROP COLUMN '.$dialect->quoteField($name).';';
00204                 }
00205             }
00206             
00207             foreach ($targetColumns as $name => $column) {
00208                 if (!isset($sourceColumns[$name])) {
00209                     $out[] =
00210                         $head
00211                         .' ADD COLUMN '
00212                         .$column->toDialectString($dialect).';';
00213                     
00214                     if ($column->hasReference()) {
00215                         $out[] =
00216                             'CREATE INDEX '.$dialect->quoteField($name.'_idx')
00217                             .' ON '.$dialect->quoteTable($target->getName()).
00218                             '('.$dialect->quoteField($name).');';
00219                     }
00220                 }
00221             }
00222             
00223             return $out;
00224         }
00225     }
00226 ?>