Skip to content

Commit 89726a0

Browse files
committed
rework everything; add emacs output mode
1 parent 0f7963b commit 89726a0

File tree

6 files changed

+466
-65
lines changed

6 files changed

+466
-65
lines changed

bin/php-sqllint

Lines changed: 23 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,26 @@
11
#!/usr/bin/env php
22
<?php
3-
use SqlParser\Parser;
4-
5-
require_once __DIR__ . '/../vendor/autoload.php';
6-
7-
if ($argc < 2) {
8-
echo "SQL file name missing\n";
9-
exit(1);
10-
}
11-
$file = $argv[1];
12-
if ($file == '') {
13-
echo "SQL file name empty\n";
14-
exit(1);
15-
}
16-
if (!file_exists($file)) {
17-
echo "SQL file does not exist\n";
18-
exit(1);
19-
}
20-
21-
$sql = file_get_contents($file);
22-
if (trim($sql) == '') {
23-
echo "SQL file empty\n";
24-
exit(1);
25-
}
26-
27-
$parser = new Parser($sql);
28-
29-
if (count($parser->errors) == 0) {
30-
echo "No syntax errors detected\n";
31-
exit(0);
32-
}
33-
34-
$lines = array(1 => 0);
35-
$pos = -1;
36-
$line = 1;
37-
while (false !== $pos = strpos($sql, "\n", ++$pos)) {
38-
$lines[++$line] = $pos;
39-
}
40-
41-
echo "Syntax errors found\n";
42-
foreach ($parser->errors as $error) {
43-
reset($lines);
44-
$line = 1;
45-
while (next($lines) && $error->token->position >= current($lines)) {
46-
++$line;
47-
}
48-
$col = $error->token->position - $lines[$line];
49-
50-
/** @var SqlParser\Exceptions\ParserException $error) */
51-
echo 'Line ' . $line
52-
. ' col ' . $col
53-
//FIXME: ->token or ->value?
54-
. ' at "' . niceToken($error->token->token) . '":'
55-
. ' ' . $error->getMessage()
56-
. "\n";
57-
//var_dump($error->token);
58-
}
59-
60-
function niceToken($str)
61-
{
62-
return str_replace(
63-
["\n", "\r", "\t"],
64-
['\n', '\r', '\t'],
65-
$str
66-
);
67-
}
3+
/**
4+
* SQL linter (syntax checker) written in PHP
5+
*
6+
* PHP version 5
7+
*
8+
* @category Tools
9+
* @package PHP-SQLlint
10+
* @author Christian Weiske <[email protected]>
11+
* @license http://www.gnu.org/licenses/agpl.html GNU AGPL v3
12+
* @link http://cweiske.de/php-sqllint.htm
13+
*/
14+
namespace phpsqllint;
15+
16+
if (file_exists(__DIR__ . '/../vendor/autoload.php')) {
17+
include_once __DIR__ . '/../vendor/autoload.php';
18+
}
19+
if (file_exists(__DIR__ . '/../src/phpsqllint/Autoloader.php')) {
20+
include_once __DIR__ . '/../src/phpsqllint/Autoloader.php';
21+
Autoloader::register();
22+
}
23+
24+
$cli = new Cli();
25+
$cli->run();
6826
?>

src/phpsqllint/Autoloader.php

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
/**
3+
* Part of php-sqllint
4+
*
5+
* PHP version 5
6+
*
7+
* @category Tools
8+
* @package PHP-SQLlint
9+
* @author Christian Weiske <[email protected]>
10+
* @copyright 2014 Christian Weiske
11+
* @license http://www.gnu.org/licenses/agpl.html GNU AGPL v3
12+
* @link http://cweiske.de/php-sqllint.htm
13+
*/
14+
namespace phpsqllint;
15+
16+
/**
17+
* Class autoloader, PSR-0 compliant.
18+
*
19+
* @category Tools
20+
* @package PHP-SQLlint
21+
* @author Christian Weiske <[email protected]>
22+
* @copyright 2014 Christian Weiske
23+
* @license http://www.gnu.org/licenses/agpl.html GNU AGPL v3
24+
* @version Release: @package_version@
25+
* @link http://cweiske.de/php-sqllint.htm
26+
*/
27+
class Autoloader
28+
{
29+
/**
30+
* Load the given class
31+
*
32+
* @param string $class Class name
33+
*
34+
* @return void
35+
*/
36+
public function load($class)
37+
{
38+
$file = strtr($class, '_\\', '//') . '.php';
39+
if (stream_resolve_include_path($file)) {
40+
include $file;
41+
}
42+
}
43+
44+
/**
45+
* Register this autoloader
46+
*
47+
* @return void
48+
*/
49+
public static function register()
50+
{
51+
set_include_path(
52+
get_include_path() . PATH_SEPARATOR . __DIR__ . '/../'
53+
);
54+
spl_autoload_register(array(new self(), 'load'));
55+
}
56+
}
57+
?>

src/phpsqllint/Cli.php

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
<?php
2+
/**
3+
* Part of php-sqllint
4+
*
5+
* PHP version 5
6+
*
7+
* @category Tools
8+
* @package PHP-SQLlint
9+
* @author Christian Weiske <[email protected]>
10+
* @license http://www.gnu.org/licenses/agpl.html GNU AGPL v3
11+
* @link http://cweiske.de/php-sqllint.htm
12+
*/
13+
namespace phpsqllint;
14+
use SqlParser\Parser;
15+
16+
require_once 'Console/CommandLine.php';
17+
18+
/**
19+
* Command line interface
20+
*
21+
* @category Tools
22+
* @package PHP-SQLlint
23+
* @author Christian Weiske <[email protected]>
24+
* @license http://www.gnu.org/licenses/agpl.html GNU AGPL v3
25+
* @link http://www.emacswiki.org/emacs/CreatingYourOwnCompileErrorRegexp
26+
*/
27+
class Cli
28+
{
29+
protected $renderer;
30+
31+
/**
32+
* Start processing.
33+
*
34+
* @return void
35+
*/
36+
public function run()
37+
{
38+
try {
39+
$parser = $this->loadParameters();
40+
$files = $this->parseParameters($parser);
41+
42+
$allfine = true;
43+
foreach ($files as $filename) {
44+
$allfine &= $this->checkFile($filename);
45+
}
46+
47+
if ($allfine == true) {
48+
exit(0);
49+
} else {
50+
exit(10);
51+
}
52+
} catch (\Exception $e) {
53+
echo 'Error: ' . $e->getMessage() . "\n";
54+
exit(1);
55+
}
56+
}
57+
58+
/**
59+
* Check a .sql file for syntax errors
60+
*
61+
* @param string $filename File path
62+
*
63+
* @return boolean True if there were no errors, false if there were some
64+
*/
65+
public function checkFile($filename)
66+
{
67+
$this->renderer->startRendering($filename);
68+
69+
$sql = file_get_contents($filename);
70+
if (trim($sql) == '') {
71+
$this->renderer->displayError('SQL file empty', '', 0, 0);
72+
return false;
73+
}
74+
75+
$parser = new \SqlParser\Parser($sql);
76+
if (count($parser->errors) == 0) {
77+
$this->renderer->finishOk();
78+
return true;
79+
}
80+
81+
$lines = array(1 => 0);
82+
$pos = -1;
83+
$line = 1;
84+
while (false !== $pos = strpos($sql, "\n", ++$pos)) {
85+
$lines[++$line] = $pos;
86+
}
87+
88+
foreach ($parser->errors as $error) {
89+
/* @var SqlParser\Exceptions\ParserException $error) */
90+
reset($lines);
91+
$line = 1;
92+
while (next($lines) && $error->token->position >= current($lines)) {
93+
++$line;
94+
}
95+
$col = $error->token->position - $lines[$line];
96+
97+
$this->renderer->displayError(
98+
$error->getMessage(),
99+
//FIXME: ->token or ->value?
100+
$error->token->token,
101+
$line,
102+
$col
103+
);
104+
}
105+
106+
return false;
107+
}
108+
109+
/**
110+
* Load parameters for the CLI option parser.
111+
*
112+
* @return \Console_CommandLine CLI option parser
113+
*/
114+
protected function loadParameters()
115+
{
116+
$parser = new \Console_CommandLine();
117+
$parser->description = 'php-sqllint';
118+
$parser->version = '0.0.1';
119+
120+
$parser->addOption(
121+
'renderer',
122+
array(
123+
'short_name' => '-r',
124+
'long_name' => '--renderer',
125+
'description' => 'Output mode',
126+
'action' => 'StoreString',
127+
'choices' => array(
128+
'emacs',
129+
'text',
130+
),
131+
'default' => 'text',
132+
'add_list_option' => true,
133+
)
134+
);
135+
136+
$parser->addArgument(
137+
'sql_files',
138+
array(
139+
'multiple' => true
140+
)
141+
);
142+
143+
return $parser;
144+
}
145+
146+
/**
147+
* Let the CLI option parser parse the options.
148+
*
149+
* @param object $parser Option parser
150+
*
151+
* @return array Array of file names
152+
*/
153+
protected function parseParameters(\Console_CommandLine $parser)
154+
{
155+
try {
156+
$result = $parser->parse();
157+
158+
$rendClass = '\\phpsqllint\\Renderer_'
159+
. ucfirst($result->options['renderer']);
160+
$this->renderer = new $rendClass();
161+
162+
foreach ($result->args['sql_files'] as $filename) {
163+
if (!file_exists($filename)) {
164+
throw new \Exception('File does not exist: ' . $filename);
165+
}
166+
if (!is_file($filename)) {
167+
throw new \Exception('Not a file: ' . $filename);
168+
}
169+
}
170+
171+
return $result->args['sql_files'];
172+
} catch (\Exception $exc) {
173+
$parser->displayError($exc->getMessage());
174+
}
175+
}
176+
177+
}
178+
?>

src/phpsqllint/Renderer.php

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
/**
3+
* Part of php-sqllint
4+
*
5+
* PHP version 5
6+
*
7+
* @category Tools
8+
* @package PHP-SQLlint
9+
* @author Christian Weiske <[email protected]>
10+
* @license http://www.gnu.org/licenses/agpl.html GNU AGPL v3
11+
* @link http://cweiske.de/php-sqllint.htm
12+
*/
13+
namespace phpsqllint;
14+
15+
/**
16+
* What every renderer has to implement
17+
*
18+
* @category Tools
19+
* @package PHP-SQLlint
20+
* @author Christian Weiske <[email protected]>
21+
* @license http://www.gnu.org/licenses/agpl.html GNU AGPL v3
22+
* @link http://www.emacswiki.org/emacs/CreatingYourOwnCompileErrorRegexp
23+
*/
24+
interface Renderer
25+
{
26+
/**
27+
* Begin syntax check output rendering
28+
*
29+
* @param string $filename Path to the SQL file
30+
*
31+
* @return void
32+
*/
33+
public function startRendering($filename);
34+
35+
/**
36+
* Output errors in GNU style; see emacs compilation.txt
37+
*
38+
* @param string $msg Error message
39+
* @param string $token Character which caused the error
40+
* @param integer $line Line at which the error occured
41+
* @param integer $col Column at which the error occured
42+
*
43+
* @return void
44+
*/
45+
public function displayError($msg, $token, $line, $col);
46+
47+
/**
48+
* Finish syntax check output rendering; no syntax errors found
49+
*
50+
* @return void
51+
*/
52+
public function finishOk();
53+
}
54+
?>

0 commit comments

Comments
 (0)