function getStatementForBuilder(SqlBuilder $builder, $action, PdoDataSource $source)
{
$criteria = $builder->getCriteria();
$builderTable = $builder->getTable();
$tableDescriptors = array();
foreach ($criteria as $criterion) {
$table = $builderTable;
$column = $criterion->column;
if (strpos($column, '.') !== false) {
$parts = explode('.', $column);
$table = $parts[0];
$column = $parts[1];
}
if (!isset($tableDescriptors[$table])) {
$tableDescriptors[$table] = $source->getTableDescriptor($table)->getColumns();
}
if (isset($tableDescriptors[$table][$column])) {
switch ($tableDescriptors[$table][$column]->type) {
case RecessType::DATETIME:
case RecessType::TIMESTAMP:
if (is_int($criterion->value)) {
$criterion->value = date('Y-m-d H:i:s', $criterion->value);
} else {
$criterion->value = null;
}
break;
case RecessType::DATE:
$criterion->value = date('Y-m-d', $criterion->value);
break;
case RecessType::TIME:
$criterion->value = date('H:i:s', $criterion->value);
break;
case RecessType::BOOLEAN:
$criterion->value = $criterion->value == true ? 1 : 0;
break;
case RecessType::INTEGER:
if (is_array($criterion->value)) {
break;
} else {
if (is_numeric($criterion->value)) {
$criterion->value = (int) $criterion->value;
} else {
$criterion->value = null;
}
}
break;
case RecessType::FLOAT:
if (!is_numeric($criterion->value)) {
$criterion->value = null;
}
break;
}
}
}
$sql = $builder->{$action}();
$statement = $source->prepare($sql);
$arguments = $builder->getPdoArguments();
foreach ($arguments as &$argument) {
// Begin workaround for PDO's poor numeric binding
$param = $argument->getQueryParameter();
if (is_numeric($param)) {
continue;
}
if (is_string($param) && strlen($param) > 0 && substr($param, 0, 1) !== ':') {
continue;
}
// End Workaround
// Ignore parameters that aren't used in this $action (i.e. assignments in select)
if ('' === $param || strpos($sql, $param) === false) {
continue;
}
$statement->bindValue($param, $argument->value);
}
return $statement;
}