classes/bfw/database/Database.php
author Markus Bröker <broeker.markus@googlemail.com>
Fri, 13 Nov 2015 22:27:12 +0100
changeset 20 fe950de090e4
parent 17 e7d8b7d8852a
child 23 975b2839f1f3
permissions -rw-r--r--
Datenbank: Keine Backticks!

<?php

/**
 * Copyright(C) 2015 Markus Bröker<broeker.markus@googlemail.com>
 *
 */

namespace bfw\database;

use bfw\Configuration;
use Logger;
use PDO;
use PDOException;

class Database implements DBInterface {
    private static $handle = null;
    private $logger;
    /**
     * @var PDO
     */
    private $pdo;

    /**
     * Database constructor.
     * @param null|array $cfg
     */
    private function __construct($cfg = null) {
        $this->logger = Logger::getLogger(__CLASS__);

        if ($cfg == null) {
            $cfg = Configuration::getDataSourceProperties();
        }

        $dsn = $cfg['dsn'];
        $config = $cfg['config'];
        $username = $cfg['username'];
        $password = $cfg['password'];

        $this->pdo = new PDO($dsn, $username, $password, $config);
    }

    /**
     * <b>Liefert das Singleton-Pattern der Datenbank-Schicht</b>
     *
     * Es existiert in einem Lauf, einem Scope, immer nur ein DB-Handle zur gleichen Zeit.
     *
     * Damit das ganze vernünftig flutscht, muss man natürlich berücksichtigen, dass ein SP state-lastig ist!
     *
     * Definition des States: Ein Abfrageergebnis stellt solange den State des SP da, bis eine neue Abfrage
     * einen neuen State erzeugt.
     *
     * @param null|array $cfg
     * @return Database
     */
    public static function getInstance($cfg = null) {
        if (self::$handle == null) {
            self::$handle = new Database($cfg);
        }

        return self::$handle;
    }

    /**
     * <b>Diese Methode löscht alle Tickets, History und Benutzer weg</b>
     *
     * Diese Methode sollte dann aufgerufen werden, wenn die Anwendung deployed wird
     *
     * Auf Deutsch: "Vor der Präsi alles weglöschen."
     *
     * @return bool
     */
    public function cleanup() {
        try {
            $this->pdo->exec("DELETE FROM t_user WHERE id > 2;");
            $this->pdo->exec("DELETE FROM t_group WHERE id > 5;");

            $this->pdo->exec("ALTER TABLE t_user AUTO_INCREMENT = 2;");
            $this->pdo->exec("ALTER TABLE t_group AUTO_INCREMENT = 5;");
        } catch (PDOException $pdoe) {
            return false;
        }

        return true;
    }

    /**
     *
     * @param string $table
     * @param array $fields
     * @param string $filename
     * @param string $seperator
     *
     * @throws InvalidArgumentException
     */
    public function csvExport($table, $fields, $filename, $seperator = ';') {
        $handle = fopen($filename, "w+");

        if ($handle == FALSE) {
            throw new InvalidArgumentException("Datei nicht gefunden: " . $filename);
        }

        $rows = $this->fetchAll(sprintf("SELECT %s FROM %s ORDER BY id", implode(", ", $fields), $table));

        fwrite($handle, sprintf("%s\n", implode($seperator, $fields)));
        foreach ($rows as $row) {
            fwrite($handle, sprintf("%s\n", implode($seperator, $row)));
        }

        fclose($handle);
    }

    /**
     * @param $table
     * @param $cond
     * @return array|null
     */
    public function fetchAll($table, $cond = 'id > 0') {
        $this->logger->info(sprintf('%s(%s, %s) ', __METHOD__, $table, $cond));

        $stmt = $this->pdo->prepare(sprintf('
            SELECT
                *
            FROM
              %s
            WHERE
              %s
            ', $table, $cond
        ));

        if ($stmt->execute()) {
            return $stmt->fetchAll(PDO::FETCH_ASSOC);
        }

        return null;
    }

    /**
     * @param $table
     * @param $cond
     * @return array|null
     */
    public function fetch($table, $cond = 'id > 0') {
        $this->logger->info(sprintf('%s(%s, %s) ', __METHOD__, $table, $cond));

        $stmt = $this->pdo->prepare(sprintf('
            SELECT
                *
            FROM
              %s
            WHERE
              %s
            LIMIT 1
            ', $table, $cond
        ));

        if ($stmt->execute()) {
            return $stmt->fetch(PDO::FETCH_ASSOC);
        }

        return null;
    }

    /**
     *
     * @param string $table
     * @param string $filename
     * @param string $seperator
     *
     * @throws InvalidArgumentException
     */
    public function csvImport($table, $filename, $seperator = ';') {
        $handle = fopen($filename, "r");

        if ($handle == FALSE) {
            throw new InvalidArgumentException("Datei nicht gefunden: " . $filename);
        }

        $firstLine = trim(fgets($handle, 1024));
        $firstExplodedLine = explode($seperator, $firstLine);
        $firstImplodedLine = implode(", ", $firstExplodedLine);

        while (($line = fgets($handle, 1024)) != NULL) {
            $explodedLine = explode($seperator, trim($line));
            $row = array();
            foreach ($explodedLine as $explodedField) {
                $row[] = "'$explodedField'";
            }

            $implodedLine = implode(", ", $row);
            $this->pdo->exec(sprintf("INSERT INTO %s(id, %s) VALUES(NULL, %s);\n", $table, $firstImplodedLine, $implodedLine));
        }

        fclose($handle);
    }

    /**
     * @param $table
     * @param $id
     * @return mixed|null
     */
    public function find($table, $id) {
        $this->logger->info(sprintf('%s(%s, %d) ', __METHOD__, $table, $id));

        $stmt = $this->pdo->prepare(
            sprintf('
              SELECT
                *
              FROM
                %s
              WHERE
                id = :id
              LIMIT 1
            ', $table
            ));

        $stmt->bindParam(':id', $id);

        $status = $stmt->execute();
        if ($status) {
            return $stmt->fetch(PDO::FETCH_ASSOC);
        }

        return null;
    }

    /**
     * @param $table
     * @param bool $sys
     * @return array|null
     */
    public function findAll($table, $sys) {
        $this->logger->info(sprintf('%s(%s, %d) ', __METHOD__, $table, $sys));

        $stmt = $this->pdo->prepare(
            sprintf('
              SELECT
                *
              FROM
                %s
              WHERE
                id > :id
            ', $table
            ));

        $id = ($sys ? 0 : 1);
        $stmt->bindParam(':id', $id);

        if ($stmt->execute()) {
            return $stmt->fetchAll(PDO::FETCH_ASSOC);
        }

        return null;
    }

    /**
     * @param $table
     * @param $field
     * @param $value
     * @return mixed|null
     */
    public function findByField($table, $field, $value) {
        $this->logger->info(sprintf('%s(%s, %s, %s) ', __METHOD__, $table, $field, $value));

        $stmt = $this->pdo->prepare(
            sprintf('
              SELECT
                *
              FROM
                %s
              WHERE
                %s = :value
              LIMIT 1
            ', $table, $field
            ));

        $stmt->bindParam(':value', $value);

        if ($stmt->execute()) {
            return $stmt->fetch(PDO::FETCH_ASSOC);
        }

        return null;
    }

    /**
     * @param $table
     * @param $field
     * @param $value
     * @return array|null
     */
    function findAllByField($table, $field, $value) {
        $this->logger->info(sprintf('%s(%s, %s, %s) ', __METHOD__, $table, $field, $value));

        $stmt = $this->pdo->prepare(
            sprintf('
              SELECT
                *
              FROM
                %s
              WHERE
                %s = :value
            ', $table, $field
            ));

        $stmt->bindParam(':value', $value);

        if ($stmt->execute()) {
            return $stmt->fetchAll(PDO::FETCH_ASSOC);
        }

        return null;
    }

    /**
     * @param $sql
     * @return array|null
     */
    public function query($sql) {
        $this->logger->info(sprintf('%s(%s, %s) ', __METHOD__, $sql));

        $stmt = $this->pdo->query($sql);

        if ($stmt) {
            return $stmt->fetchAll(PDO::FETCH_ASSOC);
        }

        return null;
    }

    /**
     * @param $sql
     * @return int
     */
    public function execute($sql) {
        return $this->pdo->exec($sql);
    }

    /**
     * @param $table
     * @param $array
     * @return int
     */
    public function persist($table, $array) {
        $this->logger->info(sprintf('%s(%s, %s) ', __METHOD__, $table, print_r($array, true)));

        $keys = array();
        foreach (array_keys($array) as $key) {
            if ($key != 'id') {
                $keys[] = sprintf("%s", $key);
            }
        }

        $fieldList = implode(", ", $keys);

        $values = array();
        foreach ($array as $key => $value) {
            if ($key != 'id') {
                $values[] = sprintf("'%s'", $value);
            }
        }

        $fields = implode(",", $values);

        $sql = sprintf("
            INSERT INTO %s
            (id, %s) VALUES (NULL, %s)
        ", $table, $fieldList, $fields);

        return $this->pdo->exec($sql);
    }

    /**
     * @param $table
     * @param $id
     * @param $array
     * @return int
     */
    public function store($table, $id, $array) {
        $this->logger->info(sprintf('%s(%s, %d, %s) ', __METHOD__, $table, $id, print_r($array, true)));

        $list = array();
        foreach ($array as $key => $value) {
            if ($key != 'id') {
                $list[] = sprintf("%s = '%s'", $key, $value);
            }
        }

        $listItems = implode(", ", $list);

        $sql = sprintf("
            UPDATE %s
            SET %s
            WHERE id = %d
        ", $table, $listItems, $id);

        return $this->pdo->exec($sql);
    }

    /**
     * @param $table
     * @param $id
     * @return int
     */
    public function delete($table, $id) {
        $this->logger->info(sprintf('%s(%s, %s) ', __METHOD__, $table, $id));

        $sql = sprintf("
            DELETE FROM %s
            WHERE id = %d;
        ", $table, $id);

        return $this->pdo->exec($sql);
    }

    public function getLastInsertedId() {
        return $this->pdo->lastInsertId();
    }
}