Пример #1
0
 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 '?';
     }
 }
Пример #2
0
 /**
  * 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);
 }
Пример #3
0
 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;
 }
Пример #4
0
 /**
  * @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);
     }
 }
Пример #5
0
 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);
     }
 }
Пример #6
0
 /**
  * @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']);
     }
 }
Пример #7
0
 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)));
     }
 }
Пример #8
0
 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 '?';
     }
 }