УСТАНОВКА

Установка

Вы можете установить GreenPig (далее именуемый GP) двумя способами:

  1. Используя Composer:

    composer require falbin/green-pig-dao

    Данный способ предпочтительнее, т.к. позволяет устанавливать новые обновления GP одной командой.
  2. Скачав архив (на GitHub).

Подготовка к работе в примерах

Перед тем как пользоваться библиотекой, необходимо написать класс для связи библиотеки с БД и фабрику, через которую будете пользоваться данной библиотекой. GP работает как с Oracle, так и с mySql, поэтому подготовку библиотеки к работе рассмотрим на двух примерах.

Пример 1

Допустим у нас есть самописный проект, использующий БД Oracle. В корне данного проекта создадим папку GreenPig, перейдем в консоли в данную папку и установим библиотеку через композер. Затем мы создадим два файла:

  • DataBaseGP.php - связь библиотеки GP с базой данных. В первую очередь данный класс нужен для того, чтобы можно было использовать уже существующие в проекте инструменты по работе с базой. Так же DataBaseGP.php нужен потому, что GP может работать и с Oracle, и с mySql, но кое-какие нюансы, все же, необходимо прописать явно.
  • GP.php – фабрика, через которую можно пользоваться библиотекой GP.

После всех манипуляций в файловой системе мы увидим нечто похожее:


GreenPig/
├── vendor/
│   ├── composer/
│   └── falbin/
│   │   └── green-pig-dao/
│   │       ├── tests/
│   │       ├── .gitignore
│   │       ├── composer.json
│   │       ├── BaseFunctions.php
│   │       ├── CollectionJoin.php
│   │       ├── Join.php
│   │       ├── Where.php
│   │       └── Query.php
│   └── autoload.php
├── composer.lock
├── composer.json
├── DataBaseGP.php
└── GP.php

DataBaseGP.php

// Если у нас уже описан свой синглтон класс для работы с БД, то инклудим этот класс, 
// если мы используем какой-то фреймворк, можем инклудить автолоудер данного фреймворка.
include_once /* .......... */;


class DataBaseGP
{
    private $db;

    public function __construct()
    {
        $this->db = /* экземпляр класса, реализующий паттерн синглтона для работы с базой */
    }

    public function query($sql, $binds = [])
    {
        return $this->db->query($sql, $binds);
    }

    public function fetchAll($sql, $binds = [])
    {
        return $this->db->fetchAll($sql, $binds);
    }

    public function fetchRow($sql, $binds = [])
    {
        return $this->db->fetchRow($sql, $binds);
    }

    // возвращаем новую вставленную строку
    public function insert($sql, $binds, $table, $pk)
    {
        $rowid = null;
        $stmt = $this->db->prepare($sql .' returning  rowid into :rid');
        $stmt->bindParam('rid', $rowid, null, 100);
        $stmt->execute($binds);
        // через бинды rowid вызывает фатальную ошибку !!!
        return $this->db->fetchRow("select * from $table where rowid = '$rowid'", []);
    }
}   

GP.php

include_once 'DataBaseGP.php';
include_once 'vendor/autoload.php';

use GreenPigDAO\Query;
use GreenPigDAO\Where;
use GreenPigDAO\Join;
use GreenPigDAO\CollectionJoin;


class GP
{
    // Обязательный массив настроек для GP, подробнее будет описано ниже.
    private static $settings = [
        'nameDatabase' => 'Oracle',
        'functions' => [
            'formatToDate' => 'dd.mm.yyyy hh24:mi::ss'
        ]
    ];

    public static function query($baseSQL = '')
    {
        $db = new DataBaseGP();
        return new Query($db, self::$settings, $baseSQL);
    }

    public static function where()
    {
        return new Where(self::$settings);
    }

    public static function leftJoin($table, $column, $outColumn)
    {
        return new Join(self::$settings, 'left', $table, $column, $outColumn);
    }

    public static function rightJoin($table, $column, $outColumn)
    {
        return new Join(self::$settings, 'right', $table, $column, $outColumn);
    }

    public static function innerJoin($table, $column, $outColumn)
    {
        return new Join(self::$settings, 'inner', $table, $column, $outColumn);
    }

    public static function collectionJoin()
    {
        return new CollectionJoin(self::$settings);
    }
}

На этом все, теперь подключаем нашу фабрику где надо и можно пользоваться.

// Сначала подключаем фабрику
require_once PATH .'/GreenPig/GP.php';

// Затем просто используем ее
$queryPhone = GP::query('SELECT * from phone /*_where_*/');
$rawPhones = $queryPhone->whereAnd('/*_where_*/', ['id', '=', $id])->all();

Пример 2

Допустим у нас проект использует базу mySql и написан на фреймворке yii2. Мы хотим установить GP как компонент фреймворка yii2.

  1. Устанавливаем через композер GP.
  2. В корне проекта создаем папку components (если еще не создана).
  3. В ней создаем файл DataBaseGP.php:
    namespace app\components;
    
    use Yii;
    
    
    class DataBaceGP
    {
        public function query($sql, $binds = [])
        {
            return Yii::$app->db->createCommand($sql)->bindValues($binds)->execute();
        }
    
        public function fetchAll($sql, $binds = [])
        {
            return Yii::$app->db->createCommand($sql)->bindValues($binds)->queryAll();
        }
    
        public function fetchRow($sql, $binds = [])
        {
            return Yii::$app->db->createCommand($sql)->bindValues($binds)->queryOne();
        }
    
        public function insert($sql, $binds, $table, $pk)
        {
            $beforeId = Yii::$app->db->getLastInsertID();
            Yii::$app->db->createCommand($sql)->bindValues($binds)->execute();
            $id = Yii::$app->db->getLastInsertID();
            if ($beforeId === $id) return false ;
            else {
                $bufSql = "select * from $table where $pk = :id";
                return Yii::$app->db->createCommand($bufSql)->bindValues(['id' => $id])->queryOne();
            }
        }
    }
    
  4. Также в папке components создаем файл GP.php:
    namespace app\components;
    
    use yii\base\Component;
    use GreenPigDAO\Query;
    use GreenPigDAO\Where;
    use GreenPigDAO\Join;
    use GreenPigDAO\CollectionJoin;
    
    
    
    class GP extends Component {
        private $db;
        private static $settings = [
            'nameDatabase' => 'mysql',
            'functions' => [
                'formatToDate' => '%d %M %Y'
            ]
        ];
    
        public function __construct($config = [])
        {
            $this->db = new DataBaceGP();;
            parent::__construct($config);
        }
    
        public function query($baseSQL = '')
        {
            return new Query($this->db, self::$settings, $baseSQL);
        }
    
        public function where()
        {
            return new Where(self::$settings);
        }
    
        public function leftJoin($table, $column, $outColumn)
        {
            return new Join(self::$settings, 'left', $table, $column, $outColumn);
        }
    
        public function rightJoin($table, $column, $outColumn)
        {
            return new Join(self::$settings, 'right', $table, $column, $outColumn);
        }
    
        public function innerJoin($table, $column, $outColumn)
        {
            return new Join(self::$settings, 'inner', $table, $column, $outColumn);
        }
    
        public function collectionJoin()
        {
            return new CollectionJoin(self::$settings);
        }
    }
    
  5. Осталось в настройках подключить созданный компонент. Для этого в файле config/web.php в массиве настроек в разделе 'components' => необходимо добавить 'gp' => [ 'class' => 'app\components\GP' ]
  6. На этом все, теперь библиотекой можно пользоваться:
    $queryPhone = Yii::$app->gp->query('SELECT * from phone /*_where_*/');
    $rawPhones = $queryPhone->whereAnd('/*_where_*/', ['id', '=', $id])->all();
    

Подробнее о DataBaseGP.php

Данный класс создается пользователем и может называться как угодно, но в нем обязательно должны быть следующие функции с указанным набором формальных параметров:

  • query($sql, $binds = []) - может использоваться как для извлечения данных, так и для запросов не возвращающих данные (insert, update…).
  • fetchAll($sql, $binds = []) - получение всех данных.
  • fetchRow($sql, $binds = []) - получение одной записи из БД.
  • insert($sql, $binds, $table, $pk) - функция должна записать данные в базу и вернуть только что вставленную запись.

При создании класса Query в его конструктор необходимо передавать экземпляр класса DataBaseGP.

// $db - экземпляр класса DataBaseGP
// $settings - массив настроек
new Query($db, $settings);

Массив настроек

При создании экземпляра любого класса библиотеки GreenPig в конструктор необходимо передавать массив настроек. Рассмотрим подробно этот массив настроек.

$settings = [
    // Используемая база данных. Возможно указать одно из двух значений: Oracle или MySQL.
    'nameDatabase' => 'Oracle',
    // Настройки для функций
    'functions' => [
        'formatToDate' => 'dd.mm.yyyy hh24:mi::ss'
    ]
];

formatToDate - используется для автоматического преобразования строки в дату с помощью sql функции. Необходимо указать формат, к которому будет преобразовываться строка. Автоматическое преобразование используется, например, в классе Where, можно при составлении массива запроса написать:

['build_date', 'between', '01.01.2016', '01.01.2019']

В конечном итоге данный фрагмент преобразует это в sql:

        build_date between TO_DATE(:al_where_fkD7nZg5lU, 'dd.mm.yyyy hh24:mi::ss') and TO_DATE(:al_where_LdyVRznPF8, 'dd.mm.yyyy hh24:mi::ss')
    

Причем, если в настройка БД указана mySql, то будет использована другая sql функция, а именно: STR_TO_DATE.