Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/phpmyadmin/phpmyadmin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Ungureanu <udan1107@gmail.com>2015-07-13 20:22:30 +0300
committerDan Ungureanu <udan1107@gmail.com>2015-07-15 16:48:13 +0300
commiteef994f122121253e2bea856f7259b2a4578bc64 (patch)
treec3dadccc588c16ea6e3b4347b60cbf11c8976c88 /lint.php
parentea015a53890954837f2207734224ec3134a8e5d6 (diff)
Added lint.
Signed-off-by: Dan Ungureanu <udan1107@gmail.com>
Diffstat (limited to 'lint.php')
-rw-r--r--lint.php137
1 files changed, 137 insertions, 0 deletions
diff --git a/lint.php b/lint.php
new file mode 100644
index 0000000000..d434de81b2
--- /dev/null
+++ b/lint.php
@@ -0,0 +1,137 @@
+<?php
+
+// Loads the SQL lexer and parser, which are used to parse this error to detect
+// any errors.
+require_once 'libraries/sql-parser/autoload.php';
+
+/**
+ * Gets the starting position of each line.
+ *
+ * @param string $str String to be analyzed.
+ *
+ * @return array
+ */
+function getLines($str)
+{
+ $lines = array(0);
+ for ($i = 0, $len = strlen($str); $i < $len; ++$i) {
+ if ($str[$i] === "\n") {
+ $lines[] = $i;
+ }
+ }
+ return $lines;
+}
+
+/**
+ * Computes the number of the line and column given an absolute position.
+ *
+ * @param array $lines The starting position of each line.
+ * @param int $pos The absolute position
+ *
+ * @return void
+ */
+function findLineNumberAndColumn($lines, $pos)
+{
+ $line = 0;
+ foreach ($lines as $lineNo => $lineStart) {
+ if ($lineStart >= $pos) {
+ break;
+ }
+ $line = $lineNo;
+ }
+ return array($line, $pos - $lines[$line]);
+}
+
+/**
+ * Runs the linting process.
+ *
+ * @param string $query The query to be checked.
+ *
+ * @return void
+ */
+function linter($query)
+{
+ // Disabling lint for huge queries to save some resources.
+ if (strlen($query) > 10000) {
+ echo json_encode(
+ array(
+ array(
+ 'message' => 'The linting is disabled for this query because it exceededs the maxmimum length',
+ 'fromLine' => 0,
+ 'fromColumn' => 0,
+ 'toLine' => 0,
+ 'toColumn' => 0,
+ 'severity' => 'warning',
+ )
+ )
+ );
+ return;
+ }
+
+ /**
+ * Lexer used for tokenizing the query.
+ *
+ * @var SqlParser\Lexer
+ */
+ $lexer = new SqlParser\Lexer($query);
+
+ /**
+ * Parsed used for analysing the query.
+ *
+ * @var SqlParser\Parser
+ */
+ $parser = new SqlParser\Parser($lexer->list);
+
+ /**
+ * Array containing all errors.
+ *
+ * @var array
+ */
+ $errors = SqlParser\Utils\Error::get(array($lexer, $parser));
+
+ /**
+ * The response containing of all errors.
+ *
+ * @var array
+ */
+ $response = array();
+
+ /**
+ * The starting position for each line.
+ *
+ * CodeMirror requires relative position to line, but the parser stores
+ * only the absolute position of the character in string.
+ *
+ * @var array
+ */
+ $lines = getLines($query);
+
+ // Building the response.
+ foreach ($errors as $idx => $error) {
+
+ // Starting position of the string that caused the error.
+ list($fromLine, $fromColumn) = findLineNumberAndColumn(
+ $lines, $error[3]
+ );
+
+ // Ending position of the string that caused the error.
+ list($toLine, $toColumn) = findLineNumberAndColumn(
+ $lines, $error[3] + strlen($error[2])
+ );
+
+ // Building the response.
+ $response[] = array(
+ 'message' => $error[0] . ' (near ' . $error[2] . ')',
+ 'fromLine' => $fromLine,
+ 'fromColumn' => $fromColumn,
+ 'toLine' => $toLine,
+ 'toColumn' => $toColumn,
+ 'severity' => 'error',
+ );
+ }
+
+ // Sending back the answer.
+ echo json_encode($response);
+}
+
+linter($_REQUEST['sql_query']);