Можно создать одноименные обработчики функций для каждого из адаптеров.
Что то типа такого:
class GroupConcatFunction
{
public function getSql(GroupConcatExpression $expression)
{
return sprintf("GROUP_CONCAT(%s, %s)", $expression->getField(), $expression->getSeparator());
}
}
class GroupConcatFunction
{
public function getSql(GroupConcatExpression $expression)
{
return sprintf("string_agg(%s, %s)", $expression->getField(), $expression->getSeparator());
}
}
class Expression
{
protected $type;
protected $params = [];
public function __construct($type, $params)
{
$this->type;
$this->params = $params;
}
public function getType()
{
return $this->type;
}
public function getParams()
{
return $this->params;
}
}
class GroupConcatExpression
{
protected $field;
protected $separator;
public function __construct($field, $separator = ',')
{
$this->field = $field;
$this->separator = $separator;
}
public function getField()
{
return $this->field;
}
public function getSeparator()
{
return $this->separator;
}
}
class ExpressionFactory
{
public static function build($type, $params)
{
$className = $type.'Expression';
return (new ReflectionClass($className))->newInstanceArgs($params);
}
}
class FunctionFactory
{
public static function build($type)
{
$className = $type.'Function';
return new $className();
}
}
$queryBuilder = new QueryBuilder();
$queryBuilder->select(new Expression('GroupConcat', 'id', '-'));
$sql = '';
foreach ($this->selectFields as $field){
if($field instanceof Expression){
$expression = ExpressionFactory::build($field->getType(), $field->getParams());
$function = FunctionFactory::build($field->getType());
$sql .= $function->getSql($expression);
}
}
Естественно пример не претендует на полноту.
Для простых решений такое вполне подойдет, для более сложных придется разбивать запрос на лексемы и делать обработчики этих самых лексем.
_____________
Mysql, Postgresql, Redis, Memcached, Unit Testing, CI, Kohana, Yii, Phalcon, Zend Framework, Joomla, Open Cart, Ymaps, VK Api