00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00016 final class DBTable implements DialectString
00017 {
00018 private $name = null;
00019
00020 private $columns = array();
00021 private $order = array();
00022
00023 private $uniques = array();
00024
00028 public static function create($name)
00029 {
00030 return new self($name);
00031 }
00032
00033 public function __construct($name)
00034 {
00035 $this->name = $name;
00036 }
00037
00038 public function getColumns()
00039 {
00040 return $this->columns;
00041 }
00042
00046 public function addUniques()
00047 {
00048 Assert::isTrue(func_num_args() > 0);
00049
00050 $uniques = array();
00051
00052 foreach (func_get_args() as $name) {
00053
00054 $this->getColumnByName($name);
00055
00056 $uniques[] = $name;
00057 }
00058
00059 $this->uniques[] = $uniques;
00060
00061 return $this;
00062 }
00063
00064 public function getUniques()
00065 {
00066 return $this->uniques;
00067 }
00068
00073 public function addColumn(DBColumn $column)
00074 {
00075 $name = $column->getName();
00076
00077 Assert::isFalse(
00078 isset($this->columns[$name]),
00079 "column '{$name}' already exist"
00080 );
00081
00082 $this->order[] = $this->columns[$name] = $column;
00083
00084 $column->setTable($this);
00085
00086 return $this;
00087 }
00088
00093 public function getColumnByName($name)
00094 {
00095 if (!isset($this->columns[$name]))
00096 throw new MissingElementException(
00097 "column '{$name}' does not exist"
00098 );
00099
00100 return $this->columns[$name];
00101 }
00102
00106 public function dropColumnByName($name)
00107 {
00108 if (!isset($this->columns[$name]))
00109 throw new MissingElementException(
00110 "column '{$name}' does not exist"
00111 );
00112
00113 unset($this->columns[$name]);
00114 unset($this->order[array_search($name, $this->order)]);
00115
00116 return $this;
00117 }
00118
00119 public function getName()
00120 {
00121 return $this->name;
00122 }
00123
00124 public function getOrder()
00125 {
00126 return $this->order;
00127 }
00128
00129 public function toDialectString(Dialect $dialect)
00130 {
00131 return OSQL::createTable($this)->toDialectString($dialect);
00132 }
00133
00134
00135 public static function findDifferences(
00136 Dialect $dialect,
00137 DBTable $source,
00138 DBTable $target
00139 )
00140 {
00141 $out = array();
00142
00143 $head = 'ALTER TABLE '.$dialect->quoteTable($target->getName());
00144
00145 $sourceColumns = $source->getColumns();
00146 $targetColumns = $target->getColumns();
00147
00148 foreach ($sourceColumns as $name => $column) {
00149 if (isset($targetColumns[$name])) {
00150 if (
00151 $column->getType()->getId()
00152 != $targetColumns[$name]->getType()->getId()
00153 ) {
00154 $targetColumn = $targetColumns[$name];
00155
00156 $out[] =
00157 $head
00158 .' ALTER COLUMN '.$dialect->quoteField($name)
00159 .' TYPE '.$targetColumn->getType()->toString()
00160 .(
00161 $targetColumn->getType()->hasSize()
00162 ?
00163 '('
00164 .$targetColumn->getType()->getSize()
00165 .(
00166 $targetColumn->getType()->hasPrecision()
00167 ? ', '.$targetColumn->getType()->getPrecision()
00168 : null
00169 )
00170 .')'
00171 : null
00172 )
00173 .';';
00174 }
00175
00176 if (
00177 $column->getType()->isNull()
00178 != $targetColumns[$name]->getType()->isNull()
00179 ) {
00180 $out[] =
00181 $head
00182 .' ALTER COLUMN '.$dialect->quoteField($name)
00183 .' '
00184 .(
00185 $targetColumns[$name]->getType()->isNull()
00186 ? 'DROP'
00187 : 'SET'
00188 )
00189 .' NOT NULL;';
00190 }
00191 } else {
00192 $out[] =
00193 $head
00194 .' DROP COLUMN '.$dialect->quoteField($name).';';
00195 }
00196 }
00197
00198 foreach ($targetColumns as $name => $column) {
00199 if (!isset($sourceColumns[$name])) {
00200 $out[] =
00201 $head
00202 .' ADD COLUMN '
00203 .$column->toDialectString($dialect).';';
00204
00205 if ($column->hasReference()) {
00206 $out[] =
00207 'CREATE INDEX '.$dialect->quoteField($name.'_idx')
00208 .' ON '.$dialect->quoteTable($target->getName()).
00209 '('.$dialect->quoteField($name).');';
00210 }
00211 }
00212 }
00213
00214 return $out;
00215 }
00216 }
00217 ?>