Example #1
0
 /**
  * @param $clause
  * @param array $parameters - first is $statement followed by $parameters
  * @return $this|SelectQuery
  */
 public function __call($clause, $parameters = array())
 {
     $this->getContext();
     //context must be available
     $clause = Helpers::toUpperWords($clause);
     if ($clause == 'GROUP') {
         $clause = 'GROUP BY';
     } elseif ($clause == 'ORDER') {
         $clause = 'ORDER BY';
     } elseif ($clause == 'FOOT NOTE') {
         $clause = "\n--";
     } elseif ($clause == 'WHERE PRIMARY') {
         $clause = 'WHERE';
         $primaryKey = $this->context->getDatabaseReflection()->getPrimary($this->getTable());
         array_unshift($parameters, "{$this->getTableAlias()}.{$primaryKey}");
     }
     $args = array_merge(array($clause), $parameters);
     if (Strings::contains($clause, 'JOIN')) {
         return call_user_func_array(array($this, 'addJoinStatements'), $args);
     }
     return call_user_func_array(array($this, 'processStatement'), $args);
 }
Example #2
0
 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 '?';
     }
 }
Example #3
0
    public function getPanel()
    {
        $this->disabled = TRUE;
        $s = '';
        $h = 'htmlSpecialChars';
        $counts = array();
        $transactionTime = null;
        foreach ($this->queries as $i => $query) {
            list($sql, $params, $time, $rows, $connection, $source) = $query;
            $command = '';
            if (preg_match('#^\\s*(\\w+)#', $sql, $m)) {
                $command = strtoupper($m[1]);
                @$counts[$command]++;
            }
            if ($sql == 'TRANSACTION BEGIN') {
                $transactionTime = 0;
            } elseif (preg_match('#TRANSACTION (COMMIT|ROLLBACK)#', $sql)) {
                $time = $transactionTime;
                $transactionTime = null;
            } elseif ($transactionTime !== null) {
                $transactionTime += $time;
            }
            foreach ((array) $params as $param) {
                if (!is_numeric($param)) {
                    $param = str_replace("'", "\\'", $param);
                }
                $sql = preg_replace('#\\?#', "'{$param}'", $sql, 1);
            }
            $explain = NULL;
            // EXPLAIN is called here to work SELECT FOUND_ROWS()
            if ($this->explain && preg_match('#\\s*\\(?\\s*SELECT\\s#iA', $sql)) {
                try {
                    $cmd = is_string($this->explain) ? $this->explain : 'EXPLAIN';
                    $explain = $connection->queryArgs("{$cmd} {$sql}", $params)->fetchAll();
                } catch (PDOException $e) {
                }
            }
            $s .= "<tr class='nette-DbConnectionPanel-type-{$command}'><td>" . sprintf('%0.3f', $time * 1000);
            if ($explain) {
                static $counter;
                $counter++;
                $s .= "<br /><a href='#' class='nette-toggle-collapsed' data-ref='#nette-DbConnectionPanel-row-{$counter}'>explain&nbsp;</a>";
            }
            $s .= '</td><td class="nette-DbConnectionPanel-sql">' . Helpers::dumpSql(self::$maxLength ? Nette\Utils\Strings::truncate($sql, self::$maxLength) : $sql);
            if ($explain) {
                $s .= "<table id='nette-DbConnectionPanel-row-{$counter}' class='nette-collapsed'><tr>";
                foreach ($explain[0] as $col => $foo) {
                    $s .= "<th>{$h($col)}</th>";
                }
                $s .= "</tr>";
                foreach ($explain as $row) {
                    $s .= "<tr>";
                    foreach ($row as $col) {
                        $s .= "<td>{$h($col)}</td>";
                    }
                    $s .= "</tr>";
                }
                $s .= "</table>";
            }
            if ($source) {
                $s .= Nette\Diagnostics\Helpers::editorLink($source[0], $source[1])->class('nette-DbConnectionPanel-source');
            }
            $s .= '</td>';
            $s .= '<td>' . $rows . '</td></tr>';
        }
        $c = '';
        foreach ($counts as $command => $count) {
            $c .= "<tr><th>{$command}</th><td>{$count}</td><td><input type='checkbox' class='nette-DbConnectionPanel-type-switcher' name='{$command}' id='nette-DbConnectionPanel-type-{$command}' checked='checked' /></td></tr>";
        }
        return empty($this->queries) ? '' : '<style> #nette-debug td.nette-DbConnectionPanel-sql { background: white !important }
			#nette-debug .nette-DbConnectionPanel-source { color: #BBB !important } </style>
			<script type="text/javascript">
				(function() {
					var FW = typeof Tracy !== "undefined" ? Tracy : Nette;
					var $ = typeof FW.Q !== "undefined" ? FW.Q.factory : FW.Query.factory;
					$(".nette-DbConnectionPanel-type-switcher").bind("click", function(e) {
						var name = this.name;
						if (this.checked) {
							$(".nette-DbConnectionPanel-type-" + name).show();
						} else {
							$(".nette-DbConnectionPanel-type-" + name).hide();
						}
					});
				})();
			</script>
			<h1>Queries: ' . count($this->queries) . ($this->totalTime ? ', time: ' . sprintf('%0.3f', $this->totalTime * 1000) . ' ms' : '') . '</h1>
			<div class="nette-inner nette-DbConnectionPanel">
			<table>
				<tr><th>Type</th><th>Count</th><th>Filter</th></tr>' . $c . '
			</table>
			<br />
			<table>
				<tr><th>Time&nbsp;ms</th><th>SQL Statement</th><th>Rows</th></tr>' . $s . '
			</table>
			</div>';
    }
Example #4
0
 /**
  * Returns associative array of detected types (IReflection::FIELD_*) in result set.
  */
 public function getColumnTypes(PDOStatement $statement)
 {
     $types = array();
     $count = $statement->columnCount();
     for ($col = 0; $col < $count; $col++) {
         $meta = $statement->getColumnMeta($col);
         if (PHP_VERSION_ID < 50417) {
             // PHP bug #48724
             switch ($meta['name']) {
                 case 'tinyint':
                     $meta['native_type'] = 'TINY';
                     break;
                 case 'bit':
                     $meta['native_type'] = 'BIT';
                     break;
                 case 'year':
                     $meta['native_type'] = 'YEAR';
                     break;
                 default:
                     break;
             }
         }
         if (isset($meta['native_type'])) {
             $types[$meta['name']] = $type = Helpers::detectType($meta['native_type']);
             if ($type === IReflection::FIELD_TIME) {
                 $types[$meta['name']] = IReflection::FIELD_TIME_INTERVAL;
             }
         }
     }
     return $types;
 }
Example #5
0
 /**
  * Get query string with expanded params
  * @param boolean return
  * @return string
  */
 public function getQueryExpanded()
 {
     $query = $this->getQuery();
     //must be called before getParameters
     $containsNamedParams = false;
     if ($params = $this->getParameters()) {
         if ($containsNamedParams = Helpers::containsNamedParams($params)) {
             $params = array($params);
         }
         list($query, $params) = $this->context->getPreprocessor()->process(array_merge(array($query), $params));
     } else {
         list($query, $params) = $this->context->getPreprocessor()->process(array($query));
     }
     if ($containsNamedParams) {
         $that = $this;
         $query = preg_replace_callback('#(?<=\\s):[a-z]+#i', function ($m) use($params, $that) {
             return $that->quote($params[$m[0]]);
         }, $query);
     }
     return $query;
 }