Procházet zdrojové kódy

* Add commit, and rollback to PDO
* Add stringColumn, stringIndex, and stringForeignKey to PDO and Transaction
* Formatting changes
* remove stringFilter and stringSet from Table and use the ones on PDO instead
* Simplify create table
* Implement alter table
* Add dropping columns

Nathaniel van Diepen před 7 roky
rodič
revize
51d56daf0b
4 změnil soubory, kde provedl 124 přidání a 47 odebrání
  1. 2 1
      PDO/migration.abstract.class.php
  2. 80 46
      PDO/table.class.php
  3. 9 0
      PDO/transaction.class.php
  4. 33 0
      pdo.class.php

+ 2 - 1
PDO/migration.abstract.class.php

@@ -47,7 +47,8 @@
 			}
 			$pdo = self::$pdo;
 			$table = $pdo->table(self::version_table());
-			$table->column('version', 'varchar(100)')
+			$table
+				->column('version', 'varchar(100)')
 				->primaryKey('version')
 				->commit();
 			switch($direction){

+ 80 - 46
PDO/table.class.php

@@ -8,6 +8,7 @@
 		private $name;
 		private $exists;
 		private $columns;
+		private $columns_removed;
 		private $primaryKey;
 		private $index;
 		private $foreignKey;
@@ -118,55 +119,27 @@
 				unset($columns);
 			}
 		}
-		public function stringFilter(...$args){
-			return $this->pdo->stringFilter(...$args);
-		}
-		public function stringSet(...$args){
-			return $this->pdo->stringSet(...$args);
-		}
 		public function commit(){
 			$pdo = $this->pdo;
 			if(!$this->exists){
 				$columns = '';
 				foreach($this->columns as $name => $column){
-					$default = '';
-					if(!is_null($column['default'])){
-						$default .= "DEFAULT {$pdo->quote($column['default'])}";
-					}
-					$null = $column['null'] ? 'NULL' : 'NOT NULL';
-					$ai = $column['increment'] ? 'AUTO_INCREMENT' : '';
-					$columns .= "{$name} {$column['type']} {$null} {$default} {$ai},";
+					$columns .= "{$pdo->stringColumn($name, $column)},";
 				}
 				if(count($columns) > 0){
 					$columns = rtrim($columns, ',');
 				}
 				$pk = $this->primaryKey();
 				if(count($pk)){
-					$pk = ", primary key (".implode(',',$pk).")";
+					$pk = ", primary key (".implode(',', $pk).")";
 				}
 				$index = '';
-				if(count($this->index) > 0){
-					foreach($this->index as $name => $idx){
-						if($idx['unique']){
-							$index .= ", constraint unique index {$name} (".implode(',', $idx['columns']).")";
-						}else{
-							$index .= ", index {$name} (".implode(',', $idx['columns']).")";
-						}
-					}
+				foreach($this->index as $name => $idx){
+					$index .=", {$pdo->stringIndex($name, $idx)}";
 				}
 				$fk = '';
-				if(count($this->foreignKeys) > 0){
-					foreach($this->foreignKeys as $name => $k){
-						$cols0 = '';
-						$cols1 = '';
-						foreach($k['columns'] as $row){
-							$cols0 .= "{$row[0]},";
-							$cols1 .= "{$row[1]},";
-						}
-						$cols0 = rtrim($cols0, ',');
-						$cols1 = rtrim($cols1, ',');
-						$fk .= ", constraint `{$name}` foreign key ({$cols0}) references `{$k['references']}` ({$cols1})";
-					}
+				foreach($this->foreignKeys as $name => $k){
+					$fk .= ", {$pdo->stringForeignKey($name, $k)}";
 				}
 				$count = $pdo->exec("create table `{$this->name}` ({$columns}{$pk}{$index}{$fk})");
 				if($count === false){
@@ -177,32 +150,93 @@
 				}
 				$this->exists();
 			}else{
-				// @todo alter table to add and remove columns
 				$columns = array_filter($this->columns, function($item){
 					return $item['dirty'];
 				});
+				if(count($columns) + count($this->columns_removed) > 0){
+					$sql = "alter table `{$this->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  = rtrim($sql , ',') . "),";
+					}
+					unset($columns);
+					$sql = rtrim($sql, ',');
+					if($pdo->exec($sql) === false){
+						throw new \Exception("Unable to update table {$this->name}\n{$this->pdo->getError()}");
+					}
+				}
+				$sql = "alter table `{$this->name}`";
+				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'];
+				}) as $name => $idx){
+					$sql .= " add {$this->stringIndex($name, $idx)},";
+				}
+				foreach(array_filter($this->foreignKeys, function($item){
+					return $item['dirty'];
+				}) as $name => $fk){
+					$sql .= " add {$this->stringForeignKey($name, $fk)},";
+				}
+				$sql = rtrim($sql, ',');
+				if($pdo->exec($sql) === false){
+					throw new \Exception("Unable to update table {$this->name}\n{$this->pdo->getError()}");
+				}
 			}
 			$this->describe();
 		}
 		public function rollback(){
+			$this->columns_removed = [];
 			$this->exists();
 			$this->describe();
 		}
-		public function drop(){
-			if($this->exists){
-				$this->pdo->exec("drop table `{$this->name}`");
+		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]);
+				}
+			}else{
+				if($this->exists){
+					$this->pdo->exec("drop table `{$this->name}`");
+				}
+				$this->rollback();
 			}
+			return $this;
 		}
 		public function column(string $name, string $type = null, string $default = null, bool $null = false, bool $increment = false){
 			if(!is_null($type)){
-				$this->columns[$name] = [
+				$new = [
 					'type'=> $type,
 					'default'=> $default,
 					'null'=> $null,
 					'increment'=> $increment,
-					'dirty'=> true
+					'dirty'=> false
 				];
-				$column['dirty'] = true;
+				if(isset($this->columns[$name])){
+					$old = $this->columns[$name];
+					foreach($new as $key => $val){
+						if($key != 'dirty' && $old[$key] !== $val){
+							$new['dirty'] = true;
+							break;
+						}
+					}
+				}else{
+					$new['dirty'] = true;
+				}
+				$this->columns[$name] = $new;
 				return $this;
 			}else{
 				return isset($this->columns[$name]) ? $this->columns[$name] : null;
@@ -271,17 +305,17 @@
 			}
 		}
 		public function insert(array $data){
-			return $this->exists ? $this->pdo->exec("insert into `{$this->name}` {$this->stringSet($data)}") : 0;
+			return $this->exists ? $this->pdo->exec("insert into `{$this->name}` {$this->pdo->stringSet($data)}") : 0;
 		}
 		public function update(array $data, array $filter = null){
-			return $this->exists ? $this->pdo->exec("update `{$this->name} {$this->stringSet($data)} {$this->stringFilter($filter)}`") : 0;
+			return $this->exists ? $this->pdo->exec("update `{$this->name} {$this->pdo->stringSet($data)} {$this->pdo->stringFilter($filter)}`") : 0;
 		}
 		public function delete(array $filter = null){
-			return $this->exists ? $this->pdo->exec("delete from `{$this->name}` {$this->stringFilter($filter)}") : 0;
+			return $this->exists ? $this->pdo->exec("delete from `{$this->name}` {$this->pdo->stringFilter($filter)}") : 0;
 		}
 		public function fetch(array $filter = null){
 			if($this->exists){
-				$query = $this->pdo->query("select * from `{$this->name}` {$this->stringFilter($filter)}");
+				$query = $this->pdo->query("select * from `{$this->name}` {$this->pdo->stringFilter($filter)}");
 				$results = $query->fetchAll();
 				$query->closeCursor();
 			}else{
@@ -290,7 +324,7 @@
 			return $results;
 		}
 		public function count(array $filter = null){
-			return $this->exists ? $this->pdo->exec("select 1 from `{$this->name}` {$this->stringFilter($filter)}") : 0;
+			return $this->exists ? $this->pdo->exec("select 1 from `{$this->name}` {$this->pdo->stringFilter($filter)}") : 0;
 		}
 	}
 ?>

+ 9 - 0
PDO/transaction.class.php

@@ -84,5 +84,14 @@
 		public function stringSet(...$args){
 			return $this->pdo->stringSet(...$args);
 		}
+		public function stringColumn(...$args){
+			return $this->pdo->stringColumn(...$args);
+		}
+		public function stringIndex(...$args){
+			return $this->pdo->stringIndex(...$args);
+		}
+		public function stringForeignKey(...$args){
+			return $this->pdo->stringForeignKey(...$args);
+		}
 	}
 ?>

+ 33 - 0
pdo.class.php

@@ -117,6 +117,12 @@
 		public function beginTransaction(...$args){
 			return $this->pdo->beginTransaction(...$args);
 		}
+		public function commit(...$args){
+			return $this->pdo->commit(...$args);
+		}
+		public function rollback(...$args){
+			return $this->pdo->rollback(...$args);
+		}
 		public function setAttribute(...$args){
 			return $this->pdo->setAttribute(...$args);
 		}
@@ -151,5 +157,32 @@
 			}
 			return $sets;
 		}
+		public function stringColumn(string $name, array $column){
+			$default = '';
+			if(!is_null($column['default'])){
+				$default .= " DEFAULT {$this->quote($column['default'])}";
+			}
+			$null = $column['null'] ? ' NULL' : ' NOT NULL';
+			$ai = $column['increment'] ? ' AUTO_INCREMENT' : '';
+			return "{$name} {$column['type']}{$null}{$default}{$ai}";
+		}
+		public function stringIndex(string $name, array $idx){
+			if($idx['unique']){
+				return "constraint unique index {$name} (".implode(',', $idx['columns']).")";
+			}else{
+				return "index {$name} (".implode(',', $idx['columns']).")";
+			}
+		}
+		public function stringForeignKey(string $name, array $foreignKey){
+			$cols0 = '';
+			$cols1 = '';
+			foreach($foreignKey['columns'] as $row){
+				$cols0 .= "{$row[0]},";
+				$cols1 .= "{$row[1]},";
+			}
+			$cols0 = rtrim($cols0, ',');
+			$cols1 = rtrim($cols1, ',');
+			return "constraint `{$name}` foreign key ({$cols0}) references `{$foreignKey['references']}` ({$cols1})";
+		}
 	}
 ?>