Обсуждение различных реализаций ORM

dark-demon

d(^-^)b
PHP:
$dbq= $db->_birth()
-> select(' * ')
-> select(' count( [numb] ) as [sum] ')
-> from(' [tag] ')
-> groupBy(' [tag] ')
-> orderBy(' [sum] desc ')
-> limit( 10 )
;
if( $space= (string)@$reg['params']['space'] ) $dbq->andWhere(' [space] = ', $space );
$tags= $dbq->getTable();
автоэкранирование, поддержка различных субд, динамическое формирование запроса в любой последовательности и всё такое :)
 

FractalizeR

Новичок
А что это было-то вообще? Вроде на ZF не похоже. Видимо, Query Builder. Если и так, то ведь это только частичное решение.
 

dark-demon

d(^-^)b
неявные джойны реализуются посредством указания нескольких from, а вложенные запросы пока так:

PHP:
$articles= $db->_birth()
-> select(' * ')
-> from(' [article] ')
-> andWhere(' [numb] in ('. $db->_birth()
	-> select(' max( [numb] ) ')
	-> from(' [article] ')
	-> groupBy(' [id] ')
	-> makeSQL( )
.')')
-> orderBy(' [time] desc ')
-> getTable( );
 

atv

Новичок
Не скажу что буду оригинален, но тоже сделал вот такой query builder с поддержкой join, маппингом, выражениями и всё такое :)
 

dark-demon

d(^-^)b
если ты об этом: http://www.mzz.ru/docs/db.queries.html
то у тебя получился слишком сложный и многословный интерфейс.

особенно убивает вот это:
$select = new simpleSelect($criteria);
$select->toString();

нафиг этот класс нужен? критерия не может сама себя сериализовать?
 

zerkms

TDD infected
Команда форума
dark-demon
критерию можно передавать simpleMysqlSelect и simpleMssqlSelect
результаты будут разные, это если оперировать непосредственно raw sql
обычно же конкретные генераторы + субд спрятаны за мапперами, и работа происходит исключительно с критериями
 

atv

Новичок
zerkms, то что увидел, очень похоже на Criteria из Propel, который, на практике, оказался не очень удобный. Есть, конечно, и отличия, причём в лучшую сторону, по сравнению с Propel, но в целом выглядит громоздким.

Вот пример использования моего билдера

Я код не смотрел, а в доке не увидел вложенных запросов по полям типа:
Код:
select (select field from table) as field1, field2 from table2
 

zerkms

TDD infected
Команда форума
atv
хехе, респект за наблюдательность ;) сие есть симбиоз идей из propel + phpDoctrine

ps: в отличие от пропеловских - мои критерии мне юзать удобно
pps: в тестах есть, доку обновлять времени вообще нет ;(
но (пока) - только для join (как только понадобится - допишу ;) )

PHP:
    public function testSubselectInJoin()
    {
        $this->criteria->setTable('table');
        $this->criteria->addSelectField('table.*')->addSelectField('foo.id', 'foo_id');

        $criteria = new criteria('zzz');
        $criteria->add('asd', 666);

        $this->criteria->addJoin($criteria, new criterion('x.id', 'table.id', criteria::EQUAL, true), 'x');

        $this->assertEqual($this->select->toString(), "SELECT `table`.*, `foo`.`id` AS `foo_id` FROM `table` LEFT JOIN (SELECT * FROM `zzz` WHERE `zzz`.`asd` = 666) `x` ON `x`.`id` = `table`.`id`");
    }
 

dark-demon

d(^-^)b
> критерию можно передавать simpleMysqlSelect и simpleMssqlSelect

почему драйвер оборачивает критерию, а не наоборот?
 

zerkms

TDD infected
Команда форума
dark-demon
потому что критерий - абстрактен. он хранит атомы, из которых, в соответствии с конкретным диалектом sql, можно построить запрос под субд
 

dark-demon

d(^-^)b
дык прикладной код и должен работать с абстракциями. а конкретный диалект должен впыскиваться в неё один раз где-то вначале.

-~{}~ 16.01.08 18:38:

а у тебя получается так:

$criteria= new simpleCriteria( );
...
$select = new simpleMysqlSelect($criteria);
$select->toString();

...

$criteria2= new simpleCriteria( );
...
$select2 = new simpleMysqlSelect($criteria);
$select2->toString();


и так далее...
 

zerkms

TDD infected
Команда форума
dark-demon
почему бы не рассматривать критерию как тупо контейнер? ;) который просто хранит данные и умеет отдавать их коду, который из этих данных собирает нужное? ;)

-~{}~ 17.01.08 01:40:

а у тебя получается так:
контр-вариант покажи?

-~{}~ 17.01.08 01:45:

...
$criteria->setDialect('mysql');
...
$criteria->toString();

так?
 

dark-demon

d(^-^)b
чтобы не писать каждый раз:
$select2 = new simpleMysqlSelect($criteria);
$select2->toString();

и чтобы в случае смены субд не приходилось изменять имя класса в десяти местах.

-~{}~ 16.01.08 18:48:

> контр-вариант покажи?

ну хотябы так:

$criteria= $dbHandler->createCriteria();
...
$criteria->toString();
 
Сверху