From 8859d664737492d313c34796731b35eca851b362 Mon Sep 17 00:00:00 2001 From: Jeremy Dorn Date: Wed, 27 Nov 2013 14:51:13 -0800 Subject: [PATCH] Fix formatting of negative numbers (fixes #49). Improve phpunit code coverage. --- lib/SqlFormatter.php | 40 +++++++++++++++++++++---------------- tests/clihighlight.html | 23 +++++++++++++++++++++ tests/compress.html | 4 ++++ tests/format-highlight.html | 23 +++++++++++++++++++++ tests/format.html | 23 +++++++++++++++++++++ tests/highlight.html | 10 ++++++++++ tests/sql.sql | 10 ++++++++++ 7 files changed, 116 insertions(+), 17 deletions(-) diff --git a/lib/SqlFormatter.php b/lib/SqlFormatter.php index 2e81755..531aac4 100644 --- a/lib/SqlFormatter.php +++ b/lib/SqlFormatter.php @@ -9,7 +9,7 @@ * @copyright 2013 Jeremy Dorn * @license http://opensource.org/licenses/MIT * @link http://github.com/jdorn/sql-formatter - * @version 1.2.15 + * @version 1.2.16 */ class SqlFormatter { @@ -241,33 +241,29 @@ protected static function getNextToken($string, $previous = null) self::TOKEN_VALUE => self::getQuotedString($string) ); - // If a quote was opened, but doesn't have a closing quote, return the remaining string - if ($return[self::TOKEN_VALUE] === null) { - $return[self::TOKEN_VALUE] = $string; - } - return $return; } // User-defined Variable if ($string[0] === '@' && isset($string[1])) { + $ret = array( + self::TOKEN_VALUE => null, + self::TOKEN_TYPE => self::TOKEN_TYPE_VARIABLE + ); + // If the variable name is quoted if ($string[1]==='"' || $string[1]==='\'' || $string[1]==='`') { - return array( - self::TOKEN_VALUE => '@'.self::getQuotedString(substr($string,1)), - self::TOKEN_TYPE => self::TOKEN_TYPE_VARIABLE - ); + $ret[self::TOKEN_VALUE] = '@'.self::getQuotedString(substr($string,1)); } // Non-quoted variable name else { preg_match('/^(@[a-zA-Z0-9\._\$]+)/',$string,$matches); if ($matches) { - return array( - self::TOKEN_VALUE => $matches[1], - self::TOKEN_TYPE => self::TOKEN_TYPE_VARIABLE - ); + $ret[self::TOKEN_VALUE] = $matches[1]; } } + + if($ret[self::TOKEN_VALUE] !== null) return $ret; } // Number (decimal, binary, or hex) @@ -335,15 +331,17 @@ protected static function getNextToken($string, $previous = null) protected static function getQuotedString($string) { + $ret = null; + // This checks for the following patterns: // 1. backtick quoted string using `` to escape // 2. double quoted string using "" or \" to escape // 3. single quoted string using '' or \' to escape if ( preg_match('/^(((`[^`]*($|`))+)|(("[^"\\\\]*(?:\\\\.[^"\\\\]*)*("|$))+)|((\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*(\'|$))+))/s', $string, $matches)) { - return $matches[1]; + $ret = $matches[1]; } - - return null; + + return $ret; } /** @@ -696,6 +694,14 @@ public static function format($string, $highlight=true) if ($token[self::TOKEN_VALUE] === '(' || $token[self::TOKEN_VALUE] === '.') { $return = rtrim($return,' '); } + + // If this is the "-" of a negative number, it shouldn't have a space after it + if($token[self::TOKEN_VALUE] === '-' && isset($tokens[$i+1]) && $tokens[$i+1][self::TOKEN_TYPE] === self::TOKEN_TYPE_NUMBER && isset($tokens[$i-1])) { + $prev = $tokens[$i-1][self::TOKEN_TYPE]; + if($prev !== self::TOKEN_TYPE_QUOTE && $prev !== self::TOKEN_TYPE_BACKTICK_QUOTE && $prev !== self::TOKEN_TYPE_WORD && $prev !== self::TOKEN_TYPE_NUMBER) { + $return = rtrim($return,' '); + } + } } // If there are unmatched parentheses diff --git a/tests/clihighlight.html b/tests/clihighlight.html index a5d4510..6ccfc12 100644 --- a/tests/clihighlight.html +++ b/tests/clihighlight.html @@ -778,6 +778,29 @@ a in (1, 2, 3, 4, 5) and b = 5; +SELECT + count - 50 +WHERE + a - 50 = b +WHERE + 1 + and -50 +WHERE + -50 = a +WHERE + a = -50 +WHERE + 1 + /*test*/ + -50 +WHERE + 1 + and -50; + +SELECT + @ + and b; + SELECT @"weird variable name"; diff --git a/tests/compress.html b/tests/compress.html index 22d9a0f..bb2fcf7 100644 --- a/tests/compress.html +++ b/tests/compress.html @@ -68,6 +68,10 @@ SELECT * LIMIT 1; SELECT a,b,c,d FROM e LIMIT 1, 2; SELECT 1,2,3 WHERE a in (1,2,3,4,5) and b=5; +SELECT count - 50 WHERE a-50 = b WHERE 1 and - 50 WHERE -50 = a WHERE a = -50 WHERE 1 - 50 WHERE 1 and -50; + +SELECT @ and b; + SELECT @"weird variable name"; SELECT "no closing quote \ No newline at end of file diff --git a/tests/format-highlight.html b/tests/format-highlight.html index 62ddfe5..73af253 100644 --- a/tests/format-highlight.html +++ b/tests/format-highlight.html @@ -778,6 +778,29 @@ a in (1, 2, 3, 4, 5) and b = 5; +
SELECT 
+  count - 50 
+WHERE 
+  a - 50 = b 
+WHERE 
+  1 
+  and -50 
+WHERE 
+  -50 = a 
+WHERE 
+  a = -50 
+WHERE 
+  1 
+  /*test*/
+  -50 
+WHERE 
+  1 
+  and -50;
+ +
SELECT 
+  @ 
+  and b;
+
SELECT 
   @"weird variable name";
diff --git a/tests/format.html b/tests/format.html index 8a00903..dcbac03 100644 --- a/tests/format.html +++ b/tests/format.html @@ -777,6 +777,29 @@ a in (1, 2, 3, 4, 5) and b = 5; +SELECT + count - 50 +WHERE + a - 50 = b +WHERE + 1 + and -50 +WHERE + -50 = a +WHERE + a = -50 +WHERE + 1 + /*test*/ + -50 +WHERE + 1 + and -50; + +SELECT + @ + and b; + SELECT @"weird variable name"; diff --git a/tests/highlight.html b/tests/highlight.html index eace684..e26af9a 100644 --- a/tests/highlight.html +++ b/tests/highlight.html @@ -246,6 +246,16 @@
SELECT * LIMIT 1; SELECT a,b,c,d FROM e LIMIT 1, 2; SELECT 1,2,3 WHERE a in (1,2,3,4,5) and b=5;
+
SELECT count - 50
+WHERE a-50 = b
+WHERE 1 and - 50
+WHERE -50 = a
+WHERE a = -50
+WHERE 1 /*test*/ - 50
+WHERE 1 and -50;
+ +
SELECT @ and b;
+
SELECT @"weird variable name";
SELECT "no closing quote
diff --git a/tests/sql.sql b/tests/sql.sql
index c78282f..4e2d988 100644
--- a/tests/sql.sql
+++ b/tests/sql.sql
@@ -246,6 +246,16 @@ SELECT Test FROM Test WHERE
 
 SELECT * LIMIT 1; SELECT a,b,c,d FROM e LIMIT 1, 2; SELECT 1,2,3 WHERE a in (1,2,3,4,5) and b=5;
 
+SELECT count - 50
+WHERE a-50 = b
+WHERE 1 and - 50
+WHERE -50 = a
+WHERE a = -50
+WHERE 1 /*test*/ - 50
+WHERE 1 and -50;
+
+SELECT @ and b;
+
 SELECT @"weird variable name";
 
 SELECT "no closing quote