private 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 Table\ActiveRow) { return $value->getPrimary(); } elseif (is_array($value) || $value instanceof \Traversable) { $vx = $kx = array(); if ($value instanceof \Traversable) { $value = iterator_to_array($value); } if (isset($value[0])) { // non-associative; value, value, value foreach ($value as $v) { $vx[] = $this->formatValue($v); } return implode(', ', $vx); } 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 === 'assoc') { // key=value, key=value, ... foreach ($value as $k => $v) { $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 ($value instanceof \DateTime || $value instanceof \DateTimeInterface) { return $this->driver->formatDateTime($value); } elseif ($value instanceof SqlLiteral) { return $value->__toString(); } else { $this->remaining[] = $value; return '?'; } }
/** * Normalizes result row. * @param array * @return array */ public function normalizeRow($row) { if ($this->types === NULL) { $this->types = (array) $this->supplementalDriver->getColumnTypes($this->pdoStatement); } foreach ($this->types as $key => $type) { $value = $row[$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 Nette\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] = Nette\DateTime::from($value); } } return $this->supplementalDriver->normalizeRow($row); }
protected function buildJoins($val, $inner = FALSE) { $joins = array(); preg_match_all('~\\b([a-z][\\w.:]*[.:])([a-z]\\w*|\\*)(\\s+IS\\b|\\s*<=>)?~i', $val, $matches); foreach ($matches[1] as $names) { $parent = $parentAlias = $this->tableName; if ($names !== "{$parent}.") { // case-sensitive preg_match_all('~\\b([a-z][\\w]*|\\*)([.:])~i', $names, $matches, PREG_SET_ORDER); foreach ($matches as $match) { list(, $name, $delimiter) = $match; if ($delimiter === ':') { list($table, $primary) = $this->databaseReflection->getHasManyReference($parent, $name); $column = $this->databaseReflection->getPrimary($parent); } else { list($table, $column) = $this->databaseReflection->getBelongsToReference($parent, $name); $primary = $this->databaseReflection->getPrimary($table); } $joins[$name] = ' ' . (!isset($joins[$name]) && $inner && !isset($match[3]) ? 'INNER' : 'LEFT') . ' JOIN ' . $this->driver->delimite($table) . ($table !== $name ? ' AS ' . $this->driver->delimite($name) : '') . ' ON ' . $this->driver->delimite($parentAlias) . '.' . $this->driver->delimite($column) . ' = ' . $this->driver->delimite($name) . '.' . $this->driver->delimite($primary); $parent = $table; $parentAlias = $name; } } } return $joins; }
/** * @param string sequence object * @return string */ public function getInsertId($name = NULL) { try { return $this->getPdo()->lastInsertId($name); } catch (PDOException $e) { throw $this->driver->convertException($e); } }
protected function addWhereComposition(array $columns, array $parameters) { if ($this->driver->isSupported(ISupplementalDriver::SUPPORT_MULTI_COLUMN_AS_OR_COND)) { $conditionFragment = '(' . implode(' = ? AND ', $columns) . ' = ?) OR '; $condition = substr(str_repeat($conditionFragment, count($parameters)), 0, -4); return $this->addWhere($condition, Nette\Utils\Arrays::flatten($parameters)); } else { return $this->addWhere('(' . implode(', ', $columns) . ') IN', $parameters); } }
/** * @param Table $table */ protected function analyseIndexes(Table $table) { $tableName = $table->getName(); // Analyse indexes $indexes = $this->driver->getIndexes($tableName); $keys = $this->driver->getForeignKeys($tableName); foreach ($indexes as $index) { foreach ($index['columns'] as $col) { $column = $table->getColumn($col); $column->setPrimary($index['primary']); $column->setUnique($index['unique']); $column->setIndex(TRUE); } } foreach ($keys as $key) { $column = $table->getColumn($key['local']); $column->setForeignKey($foreign = new ForeignKey()); $foreign->setSourceTable($table->getName()); $foreign->setSourceColumn($key['local']); $foreign->setReferenceTable($key['table']); $foreign->setReferenceColumn($key['foreign']); } }
private function formatValue($value, $mode = NULL) { if (!$mode || $mode === 'auto') { 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 Table\IRow) { return $value->getPrimary(); } elseif ($value instanceof SqlLiteral) { $prep = clone $this; list($res, $params) = $prep->process(array_merge([$value->__toString()], $value->getParameters())); $this->remaining = array_merge($this->remaining, $params); return $res; } elseif ($value instanceof \DateTimeInterface) { return $this->driver->formatDateTime($value); } elseif ($value instanceof \DateInterval) { return $this->driver->formatDateInterval($value); } elseif (is_object($value) && method_exists($value, '__toString')) { return $this->formatValue((string) $value); } elseif (is_resource($value)) { $this->remaining[] = $value; return '?'; } } elseif ($mode === 'name') { if (!is_string($value)) { $type = gettype($value); throw new Nette\InvalidArgumentException("Placeholder ?{$mode} expects string, {$type} given."); } return $this->delimite($value); } if ($value instanceof \Traversable && !$value instanceof Table\IRow) { $value = iterator_to_array($value); } if (is_array($value)) { $vx = $kx = []; if ($mode === 'auto') { $mode = $this->arrayMode; } if ($mode === 'values') { // (key, key, ...) VALUES (value, value, ...) if (array_key_exists(0, $value)) { // multi-insert foreach ($value[0] as $k => $v) { $kx[] = $this->delimite($k); } foreach ($value as $val) { $vx2 = []; foreach ($val as $v) { $vx2[] = $this->formatValue($v); } $vx[] = implode(', ', $vx2); } $select = $this->driver->isSupported(ISupplementalDriver::SUPPORT_MULTI_INSERT_AS_SELECT); return '(' . implode(', ', $kx) . ($select ? ') SELECT ' : ') VALUES (') . implode($select ? ' UNION ALL SELECT ' : '), (', $vx) . ($select ? '' : ')'); } foreach ($value as $k => $v) { $kx[] = $this->delimite($k); $vx[] = $this->formatValue($v); } return '(' . implode(', ', $kx) . ') VALUES (' . implode(', ', $vx) . ')'; } elseif (!$mode || $mode === 'set') { foreach ($value as $k => $v) { if (is_int($k)) { // value, value, ... OR (1, 2), (3, 4) $vx[] = is_array($v) ? '(' . $this->formatValue($v) . ')' : $this->formatValue($v); } elseif (substr($k, -1) === '=') { // key+=value, key-=value, ... $k2 = $this->delimite(substr($k, 0, -2)); $vx[] = $k2 . '=' . $k2 . ' ' . substr($k, -2, 1) . ' ' . $this->formatValue($v); } else { // key=value, key=value, ... $vx[] = $this->delimite($k) . '=' . $this->formatValue($v); } } return implode(', ', $vx); } elseif ($mode === 'and' || $mode === 'or') { // (key [operator] value) AND ... foreach ($value as $k => $v) { if (is_int($k)) { $vx[] = $this->formatValue($v); continue; } list($k, $operator) = explode(' ', $k . ' '); $k = $this->delimite($k); if (is_array($v)) { if ($v) { $vx[] = $k . ' ' . ($operator ? $operator . ' ' : '') . 'IN (' . $this->formatValue(array_values($v)) . ')'; } elseif ($operator === 'NOT') { } else { $vx[] = '1=0'; } } else { $v = $this->formatValue($v); $vx[] = $k . ' ' . ($operator ?: ($v === 'NULL' ? 'IS' : '=')) . ' ' . $v; } } return $value ? '(' . implode(') ' . strtoupper($mode) . ' (', $vx) . ')' : '1=1'; } elseif ($mode === 'order') { // key, key DESC, ... foreach ($value as $k => $v) { $vx[] = $this->delimite($k) . ($v > 0 ? '' : ' DESC'); } return implode(', ', $vx); } else { throw new Nette\InvalidArgumentException("Unknown placeholder ?{$mode}."); } } elseif (in_array($mode, ['and', 'or', 'set', 'values', 'order'], TRUE)) { $type = gettype($value); throw new Nette\InvalidArgumentException("Placeholder ?{$mode} expects array or Traversable object, {$type} given."); } elseif ($mode && $mode !== 'auto') { throw new Nette\InvalidArgumentException("Unknown placeholder ?{$mode}."); } else { throw new Nette\InvalidArgumentException('Unexpected type of parameter: ' . (is_object($value) ? get_class($value) : gettype($value))); } }
private 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 Table\IRow) { return $value->getPrimary(); } elseif (is_array($value) || $value instanceof \Traversable) { $vx = $kx = array(); if ($value instanceof \Traversable) { $value = iterator_to_array($value); } if (isset($value[0])) { // non-associative; value, value, value foreach ($value as $v) { if (is_array($v) && isset($v[0])) { // 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 ($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 '?'; } }