summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Dorn <jeremy@jeremydorn.com>2013-09-02 10:12:06 -0700
committerJeremy Dorn <jeremy@jeremydorn.com>2013-09-02 10:12:06 -0700
commitf258a98eb42c5566da277acf8e97c1e918e04771 (patch)
tree65e33289acdb938cf3451d30fe6f0537812315a9
parent0b30579a48dc7deaa3905ea7d6a457998e33e5a8 (diff)
downloadsql-formatter-f258a98eb42c5566da277acf8e97c1e918e04771.zip
sql-formatter-f258a98eb42c5566da277acf8e97c1e918e04771.tar.gz
sql-formatter-f258a98eb42c5566da277acf8e97c1e918e04771.tar.bz2
Add highlighting support for binary/hex numbers and user-defined variables.
Add ":" to the boundary list (fixes ":=" assignment operator). Standardize whitespace around "if" clauses in the php code. Now there is always a space after "if" and before "(". Fixes #50
-rw-r--r--lib/SqlFormatter.php84
-rw-r--r--tests/clihighlight.html2
-rw-r--r--tests/format-highlight.html2
-rw-r--r--tests/highlight.html2
4 files changed, 70 insertions, 20 deletions
diff --git a/lib/SqlFormatter.php b/lib/SqlFormatter.php
index be326f0..9b07e33 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.12
+ * @version 1.2.13
*/
class SqlFormatter
{
@@ -26,6 +26,7 @@ class SqlFormatter
const TOKEN_TYPE_BLOCK_COMMENT = 9;
const TOKEN_TYPE_NUMBER = 10;
const TOKEN_TYPE_ERROR = 11;
+ const TOKEN_TYPE_VARIABLE = 12;
// Constants for different components of a token
const TOKEN_TYPE = 0;
@@ -101,7 +102,7 @@ class SqlFormatter
);
// Punctuation that can be used as a boundary between other tokens
- protected static $boundaries = array(',', ';', ')', '(', '.', '=', '<', '>', '+', '-', '*', '/', '!', '^', '%', '|', '&', '#');
+ protected static $boundaries = array(',', ';',':', ')', '(', '.', '=', '<', '>', '+', '-', '*', '/', '!', '^', '%', '|', '&', '#');
// For HTML syntax highlighting
// Styles applied to different token types
@@ -113,6 +114,7 @@ class SqlFormatter
public static $word_attributes = 'style="color: #333;"';
public static $error_attributes = 'style="background-color: red;"';
public static $comment_attributes = 'style="color: #aaa;"';
+ public static $variable_attributes = 'style="color: orange;"';
public static $pre_attributes = 'style="color: black; background-color: white;"';
// Boolean - whether or not the current environment is the CLI
@@ -130,6 +132,7 @@ class SqlFormatter
public static $cli_error = "\x1b[31;1;7m";
public static $cli_comment = "\x1b[30;1m";
public static $cli_functions = "\x1b[37m";
+ public static $cli_variable = "\x1b[36;1m";
// The tab character to use when formatting SQL
public static $tab = ' ';
@@ -173,7 +176,7 @@ class SqlFormatter
*/
protected static function init()
{
- if(self::$init) return;
+ if (self::$init) return;
// Sort reserved word list from longest word to shortest
usort(self::$reserved, array('SqlFormatter', 'sortLength'));
@@ -233,22 +236,40 @@ class SqlFormatter
if ($string[0]==='"' || $string[0]==='\'' || $string[0]==='`') {
$return = array(
self::TOKEN_TYPE => ($string[0]==='`'? self::TOKEN_TYPE_BACKTICK_QUOTE : self::TOKEN_TYPE_QUOTE),
- self::TOKEN_VALUE => $string
+ self::TOKEN_VALUE => self::getQuotedString($string)
);
-
- // 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[self::TOKEN_VALUE] = $matches[1];
+
+ // 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])) {
+ // 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
+ );
+ }
+ // 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
+ );
+ }
+ }
+ }
- // Number
- if (preg_match('/^([0-9]+(\.[0-9]+)?)($|\s|"\'`|'.self::$regex_boundaries.')/',$string,$matches)) {
+ // Number (decimal, binary, or hex)
+ if (preg_match('/^([0-9]+(\.[0-9]+)?|0x[0-9a-fA-F]+|0b[01]+)($|\s|"\'`|'.self::$regex_boundaries.')/',$string,$matches)) {
return array(
self::TOKEN_VALUE => $matches[1],
self::TOKEN_TYPE=>self::TOKEN_TYPE_NUMBER
@@ -310,6 +331,17 @@ class SqlFormatter
);
}
+ protected static function getQuotedString($string) {
+ // 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];
+ }
+ return null;
+ }
+
/**
* Takes a SQL string and breaks it into tokens.
* Each token is an associative array with type and value.
@@ -500,7 +532,7 @@ class SqlFormatter
$length = 0;
for ($j=1;$j<=250;$j++) {
// Reached end of string
- if(!isset($tokens[$i+$j])) break;
+ if (!isset($tokens[$i+$j])) break;
$next = $tokens[$i+$j];
@@ -823,6 +855,8 @@ class SqlFormatter
return self::highlightReservedWord($token);
} elseif ($type===self::TOKEN_TYPE_NUMBER) {
return self::highlightNumber($token);
+ } elseif ($type===self::TOKEN_TYPE_VARIABLE) {
+ return self::highlightVariable($token);
} elseif ($type===self::TOKEN_TYPE_COMMENT || $type===self::TOKEN_TYPE_BLOCK_COMMENT) {
return self::highlightComment($token);
}
@@ -887,7 +921,7 @@ class SqlFormatter
*/
protected static function highlightBoundary($value)
{
- if($value==='(' || $value===')') return $value;
+ if ($value==='(' || $value===')') return $value;
if (self::is_cli()) {
return self::$cli_boundary . $value . "\x1b[0m";
@@ -959,6 +993,22 @@ class SqlFormatter
return '<span ' . self::$word_attributes . '>' . $value . '</span>';
}
}
+
+ /**
+ * Highlights a variable token
+ *
+ * @param String $value The token's value
+ *
+ * @return String HTML code of the highlighted token.
+ */
+ protected static function highlightVariable($value)
+ {
+ if (self::is_cli()) {
+ return self::$cli_variable . $value . "\x1b[0m";
+ } else {
+ return '<span ' . self::$variable_attributes . '>' . $value . '</span>';
+ }
+ }
/**
* Helper function for sorting the list of reserved words by length
@@ -1008,7 +1058,7 @@ class SqlFormatter
private static function is_cli()
{
- if(isset(self::$cli)) return self::$cli;
+ if (isset(self::$cli)) return self::$cli;
else return php_sapi_name() === 'cli';
}
diff --git a/tests/clihighlight.html b/tests/clihighlight.html
index 936df43..657f324 100644
--- a/tests/clihighlight.html
+++ b/tests/clihighlight.html
@@ -207,7 +207,7 @@
`value` text
)
-SET @defaultOOS = (SELECT value FROM `PREFIX_configuration` WHERE name = 'PS_ORDER_OUT_OF_STOCK')
+SET @defaultOOS = (SELECT value FROM `PREFIX_configuration` WHERE name = 'PS_ORDER_OUT_OF_STOCK')
UPDATE `PREFIX_product` p SET `cache_default_attribute` = 0 WHERE `id_product` NOT IN (SELECT `id_product` FROM `PREFIX_product_attribute`)
diff --git a/tests/format-highlight.html b/tests/format-highlight.html
index 15908b1..ee70147 100644
--- a/tests/format-highlight.html
+++ b/tests/format-highlight.html
@@ -636,7 +636,7 @@
<pre style="color: black; background-color: white;"><span style="font-weight:bold;">CREATE</span> <span style="font-weight:bold;">TEMPORARY</span> <span style="font-weight:bold;">TABLE</span> <span style="color: purple;">`PREFIX_configuration_tmp`</span> (<span style="color: purple;">`value`</span> <span style="color: #333;">text</span>)</pre>
<pre style="color: black; background-color: white;"><span style="font-weight:bold;">SET</span>
- <span style="color: #333;">@defaultOOS</span> <span >=</span> (
+ <span style="color: orange;">@defaultOOS</span> <span >=</span> (
<span style="font-weight:bold;">SELECT</span>
<span style="color: #333;">value</span>
<span style="font-weight:bold;">FROM</span>
diff --git a/tests/highlight.html b/tests/highlight.html
index 5db651d..9579569 100644
--- a/tests/highlight.html
+++ b/tests/highlight.html
@@ -207,7 +207,7 @@
<span style="color: purple;">`value`</span> <span style="color: #333;">text</span>
)</pre>
-<pre style="color: black; background-color: white;"><span style="font-weight:bold;">SET</span> <span style="color: #333;">@defaultOOS</span> <span >=</span> (<span style="font-weight:bold;">SELECT</span> <span style="color: #333;">value</span> <span style="font-weight:bold;">FROM</span> <span style="color: purple;">`PREFIX_configuration`</span> <span style="font-weight:bold;">WHERE</span> <span style="color: #333;">name</span> <span >=</span> <span style="color: blue;">'PS_ORDER_OUT_OF_STOCK'</span>)</pre>
+<pre style="color: black; background-color: white;"><span style="font-weight:bold;">SET</span> <span style="color: orange;">@defaultOOS</span> <span >=</span> (<span style="font-weight:bold;">SELECT</span> <span style="color: #333;">value</span> <span style="font-weight:bold;">FROM</span> <span style="color: purple;">`PREFIX_configuration`</span> <span style="font-weight:bold;">WHERE</span> <span style="color: #333;">name</span> <span >=</span> <span style="color: blue;">'PS_ORDER_OUT_OF_STOCK'</span>)</pre>
<pre style="color: black; background-color: white;"><span style="font-weight:bold;">UPDATE</span> <span style="color: purple;">`PREFIX_product`</span> <span style="color: #333;">p</span> <span style="font-weight:bold;">SET</span> <span style="color: purple;">`cache_default_attribute`</span> <span >=</span> <span style="color: green;">0</span> <span style="font-weight:bold;">WHERE</span> <span style="color: purple;">`id_product`</span> <span style="font-weight:bold;">NOT</span> <span style="font-weight:bold;">IN</span> (<span style="font-weight:bold;">SELECT</span> <span style="color: purple;">`id_product`</span> <span style="font-weight:bold;">FROM</span> <span style="color: purple;">`PREFIX_product_attribute`</span>)</pre>