ФорумПрограммированиеПыхнуть хотите?Готовые решения → goDB — библиотека работы с MySQL

goDB — библиотека работы с MySQL

  • Serj

    Сообщения: 23 Репутация: N Группа: Кто попало

    Spritz 7 марта 2008 г. 10:56, спустя 10 минут 18 секунд

    Сенкс ;)
    joby.kharkov.ua
  • roksar

    Сообщения: 2 Репутация: N Группа: Кто попало

    Spritz 12 августа 2008 г. 21:03, спустя 158 дней 9 часов 7 минут

    Почему в запросе query('SELECT COUNT(*) FROM ?t',array('news'),'no'); возвращается просто объект?

    //пс. поставил 'el' теперь работает правильно..жаль что такой хорший класс не развиваеться..и мануал скудный
  • adw0rd

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

    Spritz 12 августа 2008 г. 21:41, спустя 37 минут 39 секунд

    roksar, он не скудный, он краткий! Ничего лишнего и все по существу. А чего именно в мануале не хватает?
    https://smappi.org/ - платформа по созданию API на все случаи жизни
  • roksar

    Сообщения: 2 Репутация: N Группа: Кто попало

    Spritz 12 августа 2008 г. 21:54, спустя 13 минут 12 секунд

    Он по существу я согласен и сделан грамотно, но живых примеров надо побольше, какой разбор где лучше применять (я имею ввиду конкретные примеры а не описание их работы) см. пример описания класса dbsimple :)
  • adw0rd

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

    Spritz 12 августа 2008 г. 22:02, спустя 7 минут 41 секунду

    roksar, по поводу примеров поддерживаю, больше примеров это только к лучшему! ;)
    https://smappi.org/ - платформа по созданию API на все случаи жизни
  • bvn

    Сообщения: 7 Репутация: N Группа: Кто попало

    Spritz 22 сентября 2008 г. 11:30, спустя 40 дней 13 часов 28 минут

    Есть предложение немного расширить функциональность модуля. Не знаю, почему автором была проигнорирована столь удобная функциональность, предоставляемая методом fetch_object… Я без претензий на соавторство, прошу рассмотреть возможность применения следующего патча (см. вложение), оформленного в виде diff-файла. Собственно, не знаю, какие мотивы мною движут, есть ли в них хоть доля тщеславия ;) ведь ничто не мешает мне юзать втихаря у себя исправленную версию, но что-то заставляет меня поделиться с миром данными исправлениями. Буду очень рад, если эти исправления будут учтены :)

    PS: Ах, да, чуть не забыл. За сам модуль огромное спасибо, я не далее как неделю назад изобрел свой велосипед для старого mysql, а потом понял, что есть mysqli и собирался изобретать подобный же велосипед для него, а оказалось, что есть готовый вполне рабочий велосипед :) За него автору низкий поклон, вот если бы еще глянуть в сторону dbal… пока для себя не определился, что можно в этой обалсти заюзать готовенького :)
  • von-hamster

    Сообщения: 4 Репутация: N Группа: Кто попало

    Spritz 2 октября 2008 г. 17:38, спустя 10 дней 6 часов 7 минут

    По поводу расширения функционала есть еще предложение (я у себя поправил).

    Предистория: нужно делать инсерт с заранее неизвестным количеством полей (ну или влом перечислять вначале поля, а потом подставлять массив результатов). Идею взял из dbsimple.

    Было раньше:
    $db->query("insert into ?t (?c,?c,?c) values(?i,?i,?i)", Array("table", "one", "two", "three", 1, 2, 3));


    При этом чтобы добавить поле нужно было добавить ?с и ?i Ну или если запрос:
    $db->query("insert into ?t (?c,?c,?c) values(?a)", Array("table", "one", "two", "three", array(1, 2, 3)));


    После моих изменений можно сделать так:
    $db->query("insert into ?t (?ca) values (?a)", Array("table", array("one", "two", "three"), array(1, 2, 3)));


    Ну или как я обычно делаю:

    $insert = array("one" => 1,
                        "two" => 2,
                        "three" => 3,
    );
    $db->query("insert into ?t (?ca) values (?a)", Array("table", array_keys($insert), array_values($insert)));


    При этом, если изменить таблицу (добавить поле) - достаточно добавить запись в массив…

    Вобщем, если кому так будет удобно, то вносим следующие изменения:
    1. добавить в private function _makeQuery($ph) после описания case ('c'): …


               case ('ac'):
               case ('ca'):
                   foreach ($el as &$e) {
                       $e = "`{$e}`";
                   }
                   return implode(',', $el);


    2. Добавить в регэксп в public function makeQuery($pattern, $data, $prefix = '') одну букву с во вторые скобки, чтобы получилось следующее:

    $q = @preg_replace_callback('/\?([int?ca]?[inac]?);?/', Array($this, '_makeQuery'), $pattern);

           
    И все…

    ЗЫ… В этом случае, нельзя указать таблицу для поля, кроме как вручную без крайних апострофов, например (один из вариантов),

    $insert = array("table`.`one" => 1,
                        "table`.`two" => 2,
                        "table`.`three" => 3,
    );
    $db->query("insert into ?t (?ca) values (?a)", Array("table", array_keys($insert), array_values($insert)));

    Ну или

    $table = 'table';
    $insert = array("{$table}`.`one" => 1,
                        "{$table}`.`two" => 2,
                        "{$table}`.`three" => 3,
    );
    $db->query("insert into ?t (?ca) values (?a)", Array($table, array_keys($insert), array_values($insert)));

  • adw0rd

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

    Spritz 2 октября 2008 г. 17:49, спустя 11 минут 14 секунд

    von-hamster, да, бывает иногда не хватает….

    $db->query("insert into ?t (?ca) values (?a)", Array("table", array("one", "two", "three"), array(1, 2, 3)));

    а как данный запрос оформить?
    insert into `table` set `one` = 1, `two` = 2, `three` = 3

    тоже самое и с update
    https://smappi.org/ - платформа по созданию API на все случаи жизни
  • von-hamster

    Сообщения: 4 Репутация: N Группа: Кто попало

    Spritz 3 октября 2008 г. 9:44, спустя 15 часов 55 минут 28 секунд

    Например, так:

    1. в в private function _makeQuery($ph):

    case ('sa'):
    foreach ($el as $k => &$e) {
    $e = "`{$k}` = '" . $this->real_escape_string($e) . "'";
    }
    return implode(',', $el);


    2. в public function makeQuery($pattern, $data, $prefix = '')
            $q = @preg_replace_callback('/\?([int?cas]?[inac]?);?/', Array($this, '_makeQuery'), $pattern);


    Тогда запрос будет выглядеть, как:

    $insert = array("one" => 1,
    "two" => 2,
    "three" => 3,
    );
    $db->query("UPDATE ?t SET ?sa;", Array("table", $insert));


    Но в этом случае, все значения заключаются в одинарные кавычки, что для числовых значений mysql вобщем-то не критично…

    Вообще слишком много получается букав для плейсхолдеров - можно запутаться…
    Например, для порядка лучше оставить только один вариант двойных…
  • adw0rd

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

    Spritz 3 октября 2008 г. 9:58, спустя 13 минут 56 секунд

    Вообще слишком много получается букав для плейсхолдеров - можно запутаться…
    Например, для порядка лучше оставить только один вариант двойных…


    угу. и я об этом
    https://smappi.org/ - платформа по созданию API на все случаи жизни
  • vasa_c

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

    Spritz 12 ноября 2008 г. 18:35, спустя 40 дней 9 часов 36 минут

    Ждал и надеялся, что в ближайшее выйдет таки 5.3, чтобы переписывать библиотечки уже под него. Как видно, надеялся зря. Поэтому перепишу goDB под старый добрый 5.2.

    TODO на версию 1.1. Кто заинтересован, дополняйте.

    1. Сделать отложенное подключение к базе (если в сценарии запросов может вообще не быть):

    $db = new goDB($host, $username /*, … */ )
    /* … */
    $db->query($query); // Подключение происходит только здесь


    2. Возможность передавать параметры подключения также и в виде ассоциативного массива. Как в конструктор, так и в makeDB.

    $configDB = Array(
    'host' => 'localhost',
    'username' => 'vasa',
    'passwd' => 'peta',
    );
    /* … */
    $db = new goDB($configDB);


    3. Возможность использовать sizeOf() и count() так же и для результатов-итераторов. Сейчас только $res->count().

    4. Наследовать исключений не от Exception, а от LogicException

    5. Плейсхолдер "?set":

    $set = Array(
    'one' => 1,
    'two' => 2,
    'three' => 3,
    );
    $db->query('UPDATE `table` SET ?set WHERE `id`=?i', Array($set, $id)); // `one`=1,`two`=2,`three`=3


    6. Плейсхолдер "?where". Для раздела WHERE. Хз пока как лучше.

    7. Метод insertRows() для запросов типа:

    INSERT INTO `table` (`one`,`two`) VALUES (1,2), (3,4), (5,6)


    Два варианта:

    // 1
    $cols = Array('one', 'two');
    $values = Array(Array(1,2), Array(3,4), Array(5,6));
    $db->insertRows('table', $cols, $values);

    // 2
    $rows = Array(
    Array(
    'one' => 1,
    'two' => 2,
    ),
    Array(
    'one' => 3,
    'two' => 4,
    ),
    );
    $db->insertRows('table', $rows);


    8. Форматы результата "kcol", "kassoc", "krow". Вместо порядковых массивов в качестве ключа используется значение первого столбца (обычно это `id`).

    9. Что-нибудь по транзакциям. Возможно, сопру у AlexB.

    10. Что-нибудь по мультизапросам.
  • adw0rd

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

    Spritz 12 ноября 2008 г. 19:26, спустя 51 минуту 18 секунд

    vasa_c, плейсхолдеры:


    для списков ?a
    для хэшей ?h
    для двумерных массивов ?sa (можно и по другому)


    ?set == ?h
    ?where - не надо
    insertRows() - не надо, для него есть ?sa
    https://smappi.org/ - платформа по созданию API на все случаи жизни
  • adw0rd

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

    Spritz 12 ноября 2008 г. 19:27, спустя 59 секунд

    Вообще ?a лучше бы быть ?l… но для совместимости лучше оставить
    https://smappi.org/ - платформа по созданию API на все случаи жизни
  • vasa_c

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

    Spritz 9 декабря 2008 г. 19:07, спустя 26 дней 23 часа 40 минут

    Так как goDB2.0 с кучей всякого барахла откладывается в силу действия сил неодолимого характера (неодолимая лень), выкладываю промежуточную 1.1

    Плейсхолдер ?s - раздел SET


    $set = Array(
    'one' => 1,
    'two' => 'two',
    'three' => null,
    'four' => 'f"our"'
    );

    $pattern = 'INSERT INTO `table` SET ?s';
    $data = Array($set);

    $db->query($pattern, $data);



    INSERT INTO `table` SET `one`="1",`two`="two",`three`=NULL,`four`="f\"our\""



    Плейсхолдер ?v - много строк одним INSERTом


    $values = Array(
    Array(1, 2, 3),
    Array(3, 4, 5),
    Array(6, 7, 8),
    );

    $pattern = 'INSERT INTO `table` (`one`,`two`,`three`) VALUES ?v';
    $data = Array($values);

    $db->query($pattern, $data);



    INSERT INTO `table` (`one`,`two`,`three`) VALUES ("1","2","3"),("3","4","5"),("6","7","8")



    Результат в виде объекта

    Для особых гурманов добавлены форматы разбора - "object", "rowobject", "iobject"


    Выборка переменных

    Добавлен формат разбора "vars". При выборке по двум столбцам, первый становится ключем, второй - значением.

    Например, таблица переменных связанных с пользователем:

    CREATE TABLE `users_vars` (
    `user` INT UNSIGNED NOT NULL,
    `name` VARCHAR(50) NOT NULL,
    `value` VARCHAR(100) NOT NULL,
    PRIMARY KEY (`user`,`name`)
    );


    Выбираем переменные принадлежащие пользователю в ассоциативный массив:

    $vars = $db->query('SELECT `name`,`value` FROM `users_vars` WHERE `user_id`=?i', Array($userId), 'vars');



    Интерфейс countable для итераторов

    Теперь получать количество записей в итераторах ("iassoc", "irow", "icol", "iobject") можно, как и в обычных массивах - count($result).


    Формат подключения

    Ещё один вариант конструктора - ассоциативный массив одним аргументом. Удобно при хранении конфигурации в массивах.


    /* Конфигурационный массив */
    $configDB = Array(
    'host' => 'localhost',
    'username' => 'user',
    'passwd' => 'qwerty',
    'dbname' => 'db',
    'prefix' => 'prefix_',
    );

    /* Старый вариант */
    $db = new goDB($configDB['host'], $configDB['username'], $configDB['passwd'], $configDB['dbname']);
    if ($configDB['prefix']) {
    $db->setPrefix($configDB['prefix']);
    }

    /* Новый вариант */
    $db = new goDB($configDB);


    Возможные поля конфигурационного массива - host, username, passwd, dbname, port, socket (аргументы конструктора), prefix, debug (сами догадайтесь).
    Все поля необязательны.

    Так же массив можно использовать при создании БД в пространстве имён:
    goDB::makeDB($configDB);

    Но аргументы $name (имя базы) и $postmake (отложенное подключение) должны идти полями массива.


    Порт в хосте

    В любом из вариантов создания базы порт можно указывать в параметре host ("localhost:3307").


    Ассоциация баз в пространстве имён

    На сайте используется две базы (теоретически):

    $db1 = goDB::makeDB($host, $username, $passwd, $dbname, 'base'); // Основная база
    $db2 = goDB::makeDB($host, $username, $passwd, $dbname, 'forum'); // База форума


    Хотим указать, чтобы форум использовал основную базу:

    $db1 = goDB::makeDB($host, $username, $passwd, $dbname, 'base'); // Основная база
    $db2 = goDB::assocDB('forum', 'base'); // Ассоциировали их
    goDB::queryDB($pattern, $data, $fetch, null, 'forum'); // Запросы пойдут к основной базе



    Декоратор запросов

    goDB::queryDecorated("wrapper");


    Теперь все запросы через query() будут валиться первым делом в функцию wrapper.


    function wrapper($query, $fetch)
    {
    print 'Запрос: '.$query.'<br />';
    print 'Разбор: '.$fetch.'<br />';
    return true;
    }


    Запрос приходит уже сформированным (pattern + data). Его можно изменить:


    function wrapper(&$query, $fetch)
    {
    $query = 'TRUNCATE TABLE `users`'; // В итоге выполнится эта гадость
    return true;
    }


    Если вернуть false, то запрос не будет выполнен.


    По мелочам

    Имена итераторов скопипастил из старого в виде DBResult, теперь исправил на goDBResult.
    goDBException наследуется от LogicException.
  • Timur

    Сообщения: 1068 Репутация: N Группа: Джедаи

    Spritz 9 декабря 2008 г. 19:29, спустя 21 минуту 23 секунды

    гуд! )

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