|
@@ -4,14 +4,19 @@
|
|
|
use Juju\{PDO, PDO\Transaction};
|
|
|
|
|
|
class Table {
|
|
|
+ const COLUMN = 'column';
|
|
|
+ const INDEX = 'index';
|
|
|
+ const FOREIGN_KEY = 'foreignkey';
|
|
|
private $pdo;
|
|
|
private $name;
|
|
|
private $exists;
|
|
|
- private $columns;
|
|
|
- private $columns_removed;
|
|
|
private $primaryKey;
|
|
|
+ private $columns;
|
|
|
private $index;
|
|
|
private $foreignKey;
|
|
|
+ private $columns_removed;
|
|
|
+ private $index_removed;
|
|
|
+ private $foreignKey_removed;
|
|
|
|
|
|
public function __construct($pdo, string $name){
|
|
|
if($pdo instanceof PDO || $pdo instanceof Transaction){
|
|
@@ -46,6 +51,9 @@
|
|
|
$this->primaryKey = [];
|
|
|
$this->index = [];
|
|
|
$this->foreignKeys = [];
|
|
|
+ $this->columns_removed = [];
|
|
|
+ $this->index_removed = [];
|
|
|
+ $this->foreignKey_removed = [];
|
|
|
if($this->exists){
|
|
|
$pdo = $this->pdo;
|
|
|
|
|
@@ -92,7 +100,8 @@
|
|
|
}
|
|
|
$foreignKeys[$item[1]] = [
|
|
|
'references'=> $item[3],
|
|
|
- 'columns'=> $columns
|
|
|
+ 'columns'=> $columns,
|
|
|
+ 'dirty'=> false
|
|
|
];
|
|
|
return $foreignKeys;
|
|
|
});
|
|
@@ -151,17 +160,25 @@
|
|
|
$this->exists();
|
|
|
}else{
|
|
|
$columns = array_filter($this->columns, function($item){
|
|
|
- return $item['dirty'];
|
|
|
+ return (bool)$item['dirty'];
|
|
|
});
|
|
|
if(count($columns) + count($this->columns_removed) > 0){
|
|
|
$sql = "alter table `{$this->name}`";
|
|
|
+ foreach($this->index_removed as $name){
|
|
|
+ if($pdo->exec("show index from `{$this->name}` where KEY_name = ".$pdo->quote($name)) > 0){
|
|
|
+ $sql .= " drop index {$name},";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ foreach($this->foreignKey_removed as $name){
|
|
|
+ $sql .= " drop foreign key {$name},";
|
|
|
+ }
|
|
|
foreach($this->columns_removed as $name){
|
|
|
$sql .= " drop column {$name},";
|
|
|
}
|
|
|
if(count($columns) > 0){
|
|
|
$sql .= " add (";
|
|
|
foreach($columns as $name => $column){
|
|
|
- $sql .= "{$this->stringColumn($name, $column)},";
|
|
|
+ $sql .= "{$pdo->stringColumn($name, $column)},";
|
|
|
}
|
|
|
$sql = rtrim($sql , ',') . "),";
|
|
|
}
|
|
@@ -171,42 +188,74 @@
|
|
|
throw new \Exception("Unable to update table {$this->name}\n{$this->pdo->getError()}");
|
|
|
}
|
|
|
}
|
|
|
- $sql = "alter table `{$this->name}`";
|
|
|
+ $sql = '';
|
|
|
+ if($pdo->exec("show index from `{$this->name}` where KEY_name = 'PRIMARY'") > 0){
|
|
|
+ $sql .= " drop primary key,";
|
|
|
+ }
|
|
|
if(count($this->primaryKey) > 0){
|
|
|
- if($pdo->exec("show index from `{$this->name}` where KEY_name = 'PRIMARY'") > 0){
|
|
|
- $sql .= " drop primary key,";
|
|
|
- }
|
|
|
$sql .= " add primary key (".implode(',', $this->primaryKey)."),";
|
|
|
}
|
|
|
foreach(array_filter($this->index, function($item){
|
|
|
- return $item['dirty'];
|
|
|
+ return (bool)$item['dirty'];
|
|
|
}) as $name => $idx){
|
|
|
- $sql .= " add {$this->stringIndex($name, $idx)},";
|
|
|
+ $sql .= " add {$pdo->stringIndex($name, $idx)},";
|
|
|
}
|
|
|
- foreach(array_filter($this->foreignKeys, function($item){
|
|
|
- return $item['dirty'];
|
|
|
- }) as $name => $fk){
|
|
|
- $sql .= " add {$this->stringForeignKey($name, $fk)},";
|
|
|
+ if(count($sql) > 0){
|
|
|
+ $sql = "alter table `{$this->name}`".rtrim($sql, ',');
|
|
|
+ if($pdo->exec($sql) === false){
|
|
|
+ throw new \Exception("Unable to update table {$this->name}\n{$this->pdo->getError()}");
|
|
|
+ }
|
|
|
}
|
|
|
- $sql = rtrim($sql, ',');
|
|
|
- if($pdo->exec($sql) === false){
|
|
|
- throw new \Exception("Unable to update table {$this->name}\n{$this->pdo->getError()}");
|
|
|
+ $foreignKeys =array_filter($this->foreignKeys, function($item){
|
|
|
+ return (bool)$item['dirty'];
|
|
|
+ });
|
|
|
+ if(count($foreignKeys) > 0){
|
|
|
+ $sql = "alter table `{$this->name}`";
|
|
|
+ foreach($foreignKeys as $name => $fk){
|
|
|
+ $sql .= " add {$pdo->stringForeignKey($name, $fk)},";
|
|
|
+ }
|
|
|
+ $sql = rtrim($sql, ',');
|
|
|
+ if($pdo->exec($sql) === false){
|
|
|
+ throw new \Exception("Unable to update table {$this->name}\n{$this->pdo->getError()}");
|
|
|
+ }
|
|
|
}
|
|
|
+ unset($foreignKeys);
|
|
|
}
|
|
|
$this->describe();
|
|
|
}
|
|
|
public function rollback(){
|
|
|
- $this->columns_removed = [];
|
|
|
$this->exists();
|
|
|
$this->describe();
|
|
|
}
|
|
|
- public function drop(string $column = null){
|
|
|
- if(!is_null($column)){
|
|
|
- if(isset($this->columns[$column])){
|
|
|
- if($this->exists){
|
|
|
- $this->columns_removed = array_merge($this->columns_removed, [$column]);
|
|
|
- }
|
|
|
- unset($this->columns[$column]);
|
|
|
+ public function drop(string $type = null, string $name = null){
|
|
|
+ if(!is_null($type)){
|
|
|
+ switch($type){
|
|
|
+ case self::COLUMN:
|
|
|
+ if(isset($this->columns[$name])){
|
|
|
+ if($this->exists){
|
|
|
+ $this->columns_removed = array_merge($this->columns_removed, [$name]);
|
|
|
+ }
|
|
|
+ unset($this->columns[$name]);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case self::INDEX:
|
|
|
+ if(isset($this->index[$name])){
|
|
|
+ if($this->exists){
|
|
|
+ $this->index_removed = array_merge($this->index_removed, [$name]);
|
|
|
+ }
|
|
|
+ unset($this->index[$name]);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case self::FOREIGN_KEY:
|
|
|
+ if(isset($this->foreignKey[$name])){
|
|
|
+ if($this->exists){
|
|
|
+ $this->foreignKey_removed = array_merge($this->foreignKey_removed, [$name]);
|
|
|
+ }
|
|
|
+ unset($this->foreignKey[$name]);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ throw new \Exception("Cannot drop {$name}. Unknown type {$type}");
|
|
|
}
|
|
|
}else{
|
|
|
if($this->exists){
|
|
@@ -284,7 +333,8 @@
|
|
|
}
|
|
|
$this->foreignKeys[$name] = [
|
|
|
'references'=> $references,
|
|
|
- 'columns'=> $columns
|
|
|
+ 'columns'=> $columns,
|
|
|
+ 'dirty'=> true
|
|
|
];
|
|
|
return $this;
|
|
|
}else{
|