/** * Normalizes result row. * @param array * @return array */ public function normalizeRow($row) { if ($this->columnTypes === NULL) { $this->columnTypes = (array) $this->driver->getColumnTypes($this); $this->columnTypes += array_values($this->columnTypes); } $row = (array) $row; foreach ($row as $key => $value) { $type = $this->columnTypes[$key]; if ($value === NULL || $value === FALSE || $type === IReflection::FIELD_TEXT) { } elseif ($type === IReflection::FIELD_INTEGER) { $row[$key] = is_float($tmp = $value * 1) ? $value : $tmp; } elseif ($type === IReflection::FIELD_FLOAT) { if (($pos = strpos($value, '.')) !== FALSE) { $value = rtrim(rtrim($pos === 0 ? "0{$value}" : $value, '0'), '.'); } $float = (double) $value; $row[$key] = (string) $float === $value ? $float : $value; } elseif ($type === IReflection::FIELD_BOOL) { $row[$key] = (bool) $value && $value !== 'f' && $value !== 'F'; } elseif ($type === IReflection::FIELD_DATETIME || $type === IReflection::FIELD_DATE || $type === IReflection::FIELD_TIME) { $row[$key] = new DateTime($value); } elseif ($type === IReflection::FIELD_TIME_INTERVAL) { preg_match('#^(-?)(\\d+)\\D(\\d+)\\D(\\d+)\\z#', $value, $m); $row[$key] = new DateInterval("PT{$m['2']}H{$m['3']}M{$m['4']}S"); $row[$key]->invert = (int) (bool) $m[1]; } elseif ($type === IReflection::FIELD_UNIX_TIMESTAMP) { $row[$key] = DateTime::from($value); } } return $this->driver->normalizeRow($row); }
protected function formatValue($value) { if (is_string($value)) { if (strlen($value) > 20) { $this->remaining[] = $value; return '?'; } else { return $this->connection->quote($value); } } elseif (is_int($value)) { return (string) $value; } elseif (is_float($value)) { return rtrim(rtrim(number_format($value, 10, '.', ''), '0'), '.'); } elseif (is_bool($value)) { return $this->driver->formatBool($value); } elseif ($value === NULL) { return 'NULL'; } elseif ($value instanceof ActiveRow) { return $value->getPrimary(); } elseif (is_array($value) || $value instanceof Traversable) { $vx = $kx = array(); if ($value instanceof Traversable) { $value = iterator_to_array($value); } reset($value); if (isset($value[0])) { // non-associative; value, value, value foreach ($value as $v) { if (is_array($v) && isset($v[0]) && count($v) > 1) { // no-associative; (value), (value), (value) $vx[] = '(' . $this->formatValue($v) . ')'; } else { $vx[] = $this->formatValue($v); } } if ($this->arrayMode === 'union') { return implode(' ', $vx); } return implode(', ', $vx); } elseif (Helpers::containsNamedParams($value)) { //named params e.g. ":id" foreach ($value as $k => $v) { if (is_array($v)) { throw new InvalidArgumentException("Named param '{$k}' contains unsupported array as value."); } } $this->remaining = $this->remaining + $value; } elseif ($this->arrayMode === 'values') { // (key, key, ...) VALUES (value, value, ...) $this->arrayMode = 'multi'; foreach ($value as $k => $v) { $kx[] = $this->driver->delimite($k); $vx[] = $this->formatValue($v); } return '(' . implode(', ', $kx) . ') VALUES (' . implode(', ', $vx) . ')'; } elseif ($this->arrayMode === 'select') { // (key, key, ...) SELECT value, value, ... $this->arrayMode = 'union'; foreach ($value as $k => $v) { $kx[] = $this->driver->delimite($k); $vx[] = $this->formatValue($v); } return '(' . implode(', ', $kx) . ') SELECT ' . implode(', ', $vx); } elseif ($this->arrayMode === 'assoc') { // key=value, key=value, ... foreach ($value as $k => $v) { if (substr($k, -1) === '=') { $k2 = $this->driver->delimite(substr($k, 0, -2)); $vx[] = $k2 . '=' . $k2 . ' ' . substr($k, -2, 1) . ' ' . $this->formatValue($v); } else { $vx[] = $this->driver->delimite($k) . '=' . $this->formatValue($v); } } return implode(', ', $vx); } elseif ($this->arrayMode === 'multi') { // multiple insert (value, value, ...), ... foreach ($value as $v) { $vx[] = $this->formatValue($v); } return '(' . implode(', ', $vx) . ')'; } elseif ($this->arrayMode === 'union') { // UNION ALL SELECT value, value, ... foreach ($value as $v) { $vx[] = $this->formatValue($v); } return 'UNION ALL SELECT ' . implode(', ', $vx); } elseif ($this->arrayMode === 'and') { // (key [operator] value) AND ... foreach ($value as $k => $v) { $k = $this->driver->delimite($k); if (is_array($v)) { $vx[] = $v ? $k . ' IN (' . $this->formatValue(array_values($v)) . ')' : '1=0'; } else { $v = $this->formatValue($v); $vx[] = $k . ($v === 'NULL' ? ' IS ' : ' = ') . $v; } } return $value ? '(' . implode(') AND (', $vx) . ')' : '1=1'; } elseif ($this->arrayMode === 'order') { // key, key DESC, ... foreach ($value as $k => $v) { $vx[] = $this->driver->delimite($k) . ($v > 0 ? '' : ' DESC'); } return implode(', ', $vx); } } elseif ($value instanceof DateTime || $value instanceof DateTimeInterface) { return $this->driver->formatDateTime($value); } elseif ($value instanceof SqlLiteral) { $this->remaining = array_merge($this->remaining, $value->getParameters()); return $value->__toString(); } else { $this->remaining[] = $value; return '?'; } }