ФорумПрограммированиеПыхнуть хотите?Готовые решения → Библиотека для БД II

Библиотека для БД II

  • vasa_c

    Сообщения: 3127 Репутация: N Группа: в ухо

    Spritz 8 декабря 2007 г. 14:19

    [size=12]DB version 0.0 beta[/size]

    3 кило

    Требуется PHP5 + mysqli

    Библиотека представляет собой расширение над mysqli.
    Дополнения сделаны в стиле предыдущей версии либы.
    Основное отличие от предыдущей версии в том, что вместо одного статического класса используются объекты, что позволяет работать в одном сценарии с несколькими базами. Кроме того, класс DB является расширением над mysqli, что позволяет использовать все mysqli-методы (хотя некоторые изменены).


    [size=11]Конструктор[/size]

    Конструктор совпадает с mysqli-конструктором.
    Единственное отличие — в случае ошибочного подключения генерируется исключение DBExceptionConnect.


    try {
    $db = new DB('localhost', 'test', 'test', 'test');
    $db->select('table'); // Используем методы библиотеки
    $db->autocommit(true); // Использует обычные методы mysqli
    $db->query('select * from ?t', Array('table'), 'assoc'); // Используем переопределенный метод
    } catch (DBExceptionConnect $e) {
    print 'error';
    }



    [size=11]Запрос к базе[/size]

    Для запроса используется метод query(), переопределенный в DB.
    Метод real_query() не переопределен, его можно продолжать использовать в стиле mysqli.

    mixed query(string $pattern [, array $data [, int $fetch [, $prefix])

    Аргументы практически аналогичны старому DB::query.

    Отличия:

    Теперь формат результата указывается не в виде констаны (DB::fAssoc), а в виде строки (регистронезависимой): "no", "id", "ar", "num", "row", "assoc", "col", "irow", "iassoc", "icol", "rowrow", "rowassoc", "el". Убран "bool" - в нем и раньше особого смысла не было.

    Добавлен параметр prefix, позволяющий указывать префикс имен таблиц только для данного запроса, не затрагивая префикс по умолчанию, устанавливаемый методом setPrefix().


    $db->query('insert into ?t (?c,?c,?c) values(?,?,?i)', Array('table', 'one', 'two', 'three', 'value1', 'value2', 3), 'id');



    [size=11]setPrefix, setDebug[/size]

    Как и в прошлой либе позволяют установить префикс имен таблиц (добавляются к именам при использовании плейсхолдера ?t) и вывод запросов в браузер.


    [size=11]makeQuery и fetch[/size]

    string makeQuery(string $pattern, array $data) - формирование sql-запроса на основании шаблона и входных данных
    mixed fetch(mysqli_result $result, string $fetch) - разбор результата запроса в нужном формате

    Вспомогательный методы, используемые в query(). Вынесены в public, так как могут быть полезны при обработке мультизапросов:

    $sql = Array(
    $db->makeQuery('select ?c from ?t where ?c=?i', Array('one', 'tbl', 'id', 1)),
    $db->makeQuery('select ?c from ?t where ?c=?i', Array('two', 'tbl', 'id', 2)),
    $db->makeQuery('select ?c from ?t where ?c=?i', Array('two', 'tbl', 'id', 3)),
    );
    $sql = implode(";\r\n", $sql);
    #select `one` from `tbl` where `id`>=5;
    #select `two` from `tbl` where `id`>=15;
    #select `two` from `tbl` where `id`>=25
    if ($db->multi_query($sql)) {
    do {
    var_dump($db->fetch($db->store_result(), 'el'));
    } while ($db->next_result());
    }


    При таком обращении в fetch() недоступны форматы "id" (последний автоинкремент) и "ar" (количество затронутых записей), так как они не привязаны к результату.


    На специфические методы забил.


    [size=11]Исключения[/size]

    По сравнению с прошлым разом иерархия исключений несколько изменена.

    Убраны DBExceptionConnectHost и DBExceptionConnectBase. Оставлен один DBExceptionConnect.
    DBExceptionConfig и производные убраны, так как используются различные базы.
    DBExceptionData и производные оставлены как были.
    Добавлены DBExceptionDB и производные DBExceptionDBAlready, DBExceptionDBNotFound о чем ниже.


    [size=11]Итераторы[/size]

    По сравнению с прошлым разом для итераторов (возвращаемый формат "irow", "iassoc", "icol") реализован интерфейс ArrayAccess. То есть их можно не просто перебирать в foreach(), но и получать данные обычным "массивным" синтаксисом:

    $res = $db->query('select * from ?t', Array('table'), 'iassoc');
    print 'Столбец ONE для 4-й строки: '.$res[3]['one'];



    [size=11]Пространство имен[/size]

    Чтобы объекты баз не болтались по глобальному пространству имен их можно хранить непосредственно в классе DB.

    setDB(DB $db, string $name) - сохраняет в DB объект базы под именем name.
    getDB(string $name) - возвращает объект базы с заданным именем
    make(string $host, string $user, string $password, string $dbname, string $name) - создает базу с заданными параметрами и сохраняет её у себя.

    Параметр $name можно не указывать, тогда вместо него будет использоваться определенное базовое имя. Что удобно при использовании одной базы в сценарии (или одной основной базы).


    // В начале
    DB::make('localhost', 'test', 'test', 'test');

    // Где-то в недрах программы
    $db = DB::get();
    $db->query('…');
    $db->query('…');


    либо


    // В начале
    DB::make('localhost', 'test', 'test', 'test1', 'one');
    DB::make('localhost', 'test', 'test', 'test1', 'two');

    // Где-то в недрах программы
    $db = DB::get('one')->query('…');
    $db = DB::get('two')->query('…');


    При попытке создать базу с уже существующем именем или запросить несуществующую, генерируются исключения DBExceptionDBAlready, DBExceptionDBNotFound.

    Основной метод (query) так же реализован и в статическом виде (queryDB), последним параметром так же добавляется имя базы.


    DB::queryDB('select ?c from ?t', Array('id', 'table'), 'el'); // И не надо париться с объектами.
  • adw0rd

    Сообщения: 22905 Репутация: N Группа: в ухо

    Spritz 9 декабря 2007 г. 16:26, спустя 1 день 2 часа 6 минут

    vasa_c, премного благодарен за твои труды, особенно за данную либу! Буду пользоваться!
    adw/0
  • vasa_c

    Сообщения: 3127 Репутация: N Группа: в ухо

    Spritz 10 декабря 2007 г. 0:27, спустя 8 часов 1 минуту 2 секунды

    Рад, что понравилось.
    Заодно и потести :)
  • adw0rd

    Сообщения: 22905 Репутация: N Группа: в ухо

    Spritz 16 декабря 2007 г. 8:44, спустя 6 дней 8 часов 17 минут

    А зачем забил на "Специфические методы", которые были в старой либе? Для разгрузки либы?
    adw/0
  • vasa_c

    Сообщения: 3127 Репутация: N Группа: в ухо

    Spritz 16 декабря 2007 г. 8:50, спустя 5 минут 39 секунд

    Да я ими как-то активно не пользуюсь.
    Как думаешь, нужны?
  • adw0rd

    Сообщения: 22905 Репутация: N Группа: в ухо

    Spritz 16 декабря 2007 г. 9:00, спустя 9 минут 39 секунд

    Олег, СПАСИБО! Клевая либа, полчаса поигрался и получил огромное удовольствие от либы!
    Сейчас пишу каталог для авто-магазина, очень пригодилась!
    adw/0
  • adw0rd

    Сообщения: 22905 Репутация: N Группа: в ухо

    Spritz 16 декабря 2007 г. 9:01, спустя 1 минуту 3 секунды


    Да я ими как-то активно не пользуюсь.
    Как думаешь, нужны?


    В принципе не так уж и нужны, сильно загрузит думаю, а сейчас она такая легкая и удобная :)
    adw/0
  • adw0rd

    Сообщения: 22905 Репутация: N Группа: в ухо

    Spritz 16 декабря 2007 г. 9:02, спустя 1 минуту 15 секунд

    Поработаю с ней еще неделю (поищу косяки, но думаю их нет :) и пропиарю на своем блоге! Не против?
    adw/0
  • vasa_c

    Сообщения: 3127 Репутация: N Группа: в ухо

    Spritz 16 декабря 2007 г. 9:27, спустя 25 минут 1 секунду

    Не против :)
  • adw0rd

    Сообщения: 22905 Репутация: N Группа: в ухо

    Spritz 16 декабря 2007 г. 9:34, спустя 6 минут 51 секунду


    Не против :)


    спасиб :)
    adw/0
  • adw0rd

    Сообщения: 22905 Репутация: N Группа: в ухо

    Spritz 17 декабря 2007 г. 16:13, спустя 1 день 6 часов 39 минут

    vasa_c, а как вставить логическое значение (булеанное), то есть 'true' или 'false' при использовании плейсхолдеров?
    adw/0
  • adw0rd

    Сообщения: 22905 Репутация: N Группа: в ухо

    Spritz 17 декабря 2007 г. 16:54, спустя 41 минуту 10 секунд

    $sqlArray = $db->query('SELECT * FROM ?t WHERE ?c IN(?)', Array('catalog_marks', 'pid', '1,2'), 'assoc');


    Как передавать холдер в IN() ?

    Я так понял "в лоб":


    $inValue = '1,2';
    $sqlArray = $db->query('SELECT * FROM ?t WHERE ?c IN('.$inValue.')', Array('catalog_marks', 'pid'), 'assoc');


    или


    $sqlArray = $db->query('SELECT * FROM ?t WHERE ?c IN(1,2)', Array('catalog_marks', 'pid'), 'assoc');
    adw/0
  • vasa_c

    Сообщения: 3127 Репутация: N Группа: в ухо

    Spritz 18 декабря 2007 г. 3:18, спустя 10 часов 23 минуты 53 секунды

    BOOL, насколько помню, синоним TINYINT, т.е. вставлять лучше, как 1/0. Поэтому лучше использовать "?i" и значения будут приводится к int.

    В IN() еще так можно:
    query('… IN(?, ?, ?)', Array(…, 1, 2, 3))


    Хотя, возможно, для этого непомешает отдельный формат. Как сделать лучше?
    Предлагаю: ?a - список, ?ai - список чисел:

    $in = Array(1, 2, 3);
    $db->query('select * from ?t where ?c in (?a)', Array('table', 'id', Array(1, 2, 3)));
  • adw0rd

    Сообщения: 22905 Репутация: N Группа: в ухо

    Spritz 18 декабря 2007 г. 5:54, спустя 2 часа 35 минут 19 секунд

    BOOL, насколько помню, синоним TINYINT, т.е. вставлять лучше, как 1/0. Поэтому лучше использовать "?i" и значения будут приводится к int.

    Да TINYINT можно использовать как логический тип, но только TINYINT(1) ибо по умолчанию TINYINT(4), я так и делаю. Жить не мешает :)

    В IN() еще так можно:
    query('… IN(?, ?, ?)', Array(…, 1, 2, 3))


    это неудобно, когда заранее не знаешь сколько параметров будет в списке :(


    Хотя, возможно, для этого непомешает отдельный формат. Как сделать лучше?
    Предлагаю: ?a - список, ?ai - список чисел:

    $in = Array(1, 2, 3);
    $db->query('select * from ?t where ?c in (?a)', Array('table', 'id', Array(1, 2, 3)));



    Буду очень признателен :)
    adw/0
  • adw0rd

    Сообщения: 22905 Репутация: N Группа: в ухо

    Spritz 6 января 2008 г. 4:48, спустя 18 дней 22 часа 54 минуты

    Олег, а когда допишешь?


    Хотя, возможно, для этого непомешает отдельный формат. Как сделать лучше?
    Предлагаю: ?a - список, ?ai - список чисел:

    $in = Array(1, 2, 3);
    $db->query('select * from ?t where ?c in (?a)', Array('table', 'id', Array(1, 2, 3)));

    adw/0

Пожалуйста, авторизуйтесь, чтобы написать комментарий!