141 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			PHP
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			141 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			PHP
		
	
	
		
			Executable File
		
	
	
	
	
<?php namespace MapGuesser\Database\Query;
 | 
						|
 | 
						|
use MapGuesser\Interfaces\Database\IConnection;
 | 
						|
use MapGuesser\Database\Utils;
 | 
						|
 | 
						|
class Modify
 | 
						|
{
 | 
						|
    private IConnection $connection;
 | 
						|
 | 
						|
    private string $table;
 | 
						|
 | 
						|
    private string $idName = 'id';
 | 
						|
 | 
						|
    private array $attributes = [];
 | 
						|
 | 
						|
    private ?string $externalId = null;
 | 
						|
 | 
						|
    private bool $autoIncrement = true;
 | 
						|
 | 
						|
    public function __construct(IConnection $connection, string $table)
 | 
						|
    {
 | 
						|
        $this->connection = $connection;
 | 
						|
        $this->table = $table;
 | 
						|
    }
 | 
						|
 | 
						|
    public function setIdName(string $idName): Modify
 | 
						|
    {
 | 
						|
        $this->idName = $idName;
 | 
						|
 | 
						|
        return $this;
 | 
						|
    }
 | 
						|
 | 
						|
    public function setExternalId($id): Modify
 | 
						|
    {
 | 
						|
        $this->externalId = $id;
 | 
						|
 | 
						|
        return $this;
 | 
						|
    }
 | 
						|
 | 
						|
    public function setAutoIncrement(bool $autoIncrement = true): Modify
 | 
						|
    {
 | 
						|
        $this->autoIncrement = $autoIncrement;
 | 
						|
 | 
						|
        return $this;
 | 
						|
    }
 | 
						|
 | 
						|
    public function fill(array $attributes): Modify
 | 
						|
    {
 | 
						|
        $this->attributes = array_merge($this->attributes, $attributes);
 | 
						|
 | 
						|
        return $this;
 | 
						|
    }
 | 
						|
 | 
						|
    public function set(string $name, $value): Modify
 | 
						|
    {
 | 
						|
        $this->attributes[$name] = $value;
 | 
						|
 | 
						|
        return $this;
 | 
						|
    }
 | 
						|
 | 
						|
    public function setId($id): Modify
 | 
						|
    {
 | 
						|
        $this->attributes[$this->idName] = $id;
 | 
						|
 | 
						|
        return $this;
 | 
						|
    }
 | 
						|
 | 
						|
    public function getId()
 | 
						|
    {
 | 
						|
        return $this->attributes[$this->idName];
 | 
						|
    }
 | 
						|
 | 
						|
    public function save(): void
 | 
						|
    {
 | 
						|
        if (isset($this->attributes[$this->idName])) {
 | 
						|
            $this->update();
 | 
						|
        } else {
 | 
						|
            $this->insert();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    public function delete(): void
 | 
						|
    {
 | 
						|
        if (!isset($this->attributes[$this->idName])) {
 | 
						|
            throw new \Exception('No primary key specified!');
 | 
						|
        }
 | 
						|
 | 
						|
        $query = 'DELETE FROM ' . Utils::backtick($this->table) . ' WHERE ' . Utils::backtick($this->idName) . '=?';
 | 
						|
 | 
						|
        $stmt = $this->connection->prepare($query);
 | 
						|
        $stmt->execute([$this->idName => $this->attributes[$this->idName]]);
 | 
						|
    }
 | 
						|
 | 
						|
    private function insert(): void
 | 
						|
    {
 | 
						|
        if ($this->externalId !== null) {
 | 
						|
            $this->attributes[$this->idName] = $this->externalId;
 | 
						|
        } elseif (!$this->autoIncrement) {
 | 
						|
            $this->attributes[$this->idName] = $this->generateKey();
 | 
						|
        }
 | 
						|
 | 
						|
        $set = $this->generateColumnsWithBinding(array_keys($this->attributes));
 | 
						|
 | 
						|
        $query = 'INSERT INTO ' . Utils::backtick($this->table) . ' SET ' . $set;
 | 
						|
 | 
						|
        $stmt = $this->connection->prepare($query);
 | 
						|
        $stmt->execute($this->attributes);
 | 
						|
 | 
						|
        if ($this->autoIncrement) {
 | 
						|
            $this->attributes[$this->idName] = $this->connection->lastId();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    private function update(): void
 | 
						|
    {
 | 
						|
        $attributes = $this->attributes;
 | 
						|
        unset($attributes[$this->idName]);
 | 
						|
 | 
						|
        $set = $this->generateColumnsWithBinding(array_keys($attributes));
 | 
						|
 | 
						|
        $query = 'UPDATE ' . Utils::backtick($this->table) . ' SET ' . $set . ' WHERE ' . Utils::backtick($this->idName) . '=?';
 | 
						|
 | 
						|
        $stmt = $this->connection->prepare($query);
 | 
						|
        $stmt->execute(array_merge($attributes, [$this->idName => $this->attributes[$this->idName]]));
 | 
						|
    }
 | 
						|
 | 
						|
    public static function generateColumnsWithBinding(array $columns): string
 | 
						|
    {
 | 
						|
        array_walk($columns, function(&$value, $key) {
 | 
						|
            $value = Utils::backtick($value) . '=?';
 | 
						|
        });
 | 
						|
 | 
						|
        return implode(',', $columns);
 | 
						|
    }
 | 
						|
 | 
						|
    private function generateKey(): string
 | 
						|
    {
 | 
						|
        return substr(hash('sha256', serialize($this->attributes) . random_bytes(5) . microtime()), 0, 7);
 | 
						|
    }
 | 
						|
}
 |