Skip to content

Commit 89d7306

Browse files
committed
Adding UI to try requests
1 parent 766658d commit 89d7306

File tree

5 files changed

+309
-5
lines changed

5 files changed

+309
-5
lines changed

src/Mouf/Database/QueryWriter/Controllers/SelectController.php

Lines changed: 79 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
<?php
22
namespace Mouf\Database\QueryWriter\Controllers;
33

4+
use Mouf\Database\QueryWriter\Utils\FindParametersService;
5+
6+
use Mouf\MoufPropertyDescriptor;
7+
8+
use Mouf\Reflection\MoufReflectionClass;
9+
10+
use Mouf\MoufInstanceDescriptor;
11+
412
use SQLParser\Query\StatementFactory;
513

614
use SQLParser\SQLParser;
@@ -16,6 +24,9 @@
1624
use Mouf\Reflection\MoufReflectionProxy;
1725

1826
use Mouf\Html\HtmlElement\HtmlBlock;
27+
use Mouf\InstanceProxy;
28+
use Mouf\Html\Utils\WebLibraryManager\WebLibrary;
29+
use Mouf\Html\Widgets\EvoluGrid\EvoluGridResultSet;
1930

2031
/**
2132
* The controller to generate automatically the Beans, Daos, etc...
@@ -30,11 +41,20 @@ class SelectController extends AbstractMoufInstanceController {
3041
* @var HtmlBlock
3142
*/
3243
public $content;
33-
44+
45+
/**
46+
* @var string
47+
*/
3448
protected $sql;
3549

3650
/**
37-
* Admin page used to display the DAO generation form.
51+
* List of available parameters.
52+
* @var string[]
53+
*/
54+
protected $parameters;
55+
56+
/**
57+
* Admin page used to edit the SQL of a SELECT instance.
3858
*
3959
* @Action
4060
* //@Admin
@@ -73,7 +93,7 @@ public function parse($name, $sql,$selfedit="false") {
7393
$select->overwriteInstanceDescriptor($name, $moufManager);
7494
$moufManager->rewriteMouf();
7595

76-
header("Location: ".ROOT_URL."ajaxinstance/?name=".urlencode($name)."&selfedit=".$selfedit);
96+
header("Location: ".ROOT_URL."parseselect/tryQuery?name=".urlencode($name)."&selfedit=".$selfedit);
7797
}
7898

7999
/**
@@ -104,6 +124,61 @@ public function doCreateQuery($name, $sql,$selfedit="false") {
104124
$instanceDescriptor->setName($name);
105125
$moufManager->rewriteMouf();
106126

107-
header("Location: ".ROOT_URL."ajaxinstance/?name=".urlencode($name)."&selfedit=".$selfedit);
127+
header("Location: ".ROOT_URL."parseselect/tryQuery?name=".urlencode($name)."&selfedit=".$selfedit);
128+
}
129+
130+
131+
/**
132+
* @Action
133+
* @param string $name
134+
* @param string $selfedit
135+
*/
136+
public function tryQuery($name,$selfedit="false") {
137+
$this->instanceName = $name;
138+
139+
$moufManager = MoufManager::getMoufManagerHiddenInstance();
140+
$instanceDescriptor = $moufManager->getInstanceDescriptor($name);
141+
$this->parameters = FindParametersService::findParameters($instanceDescriptor);
142+
143+
$select = MoufManager::getMoufManagerHiddenInstance()->getInstance($name);
144+
$this->sql = $select->toSql(null, array(), 0, true);
145+
146+
$this->template->getWebLibraryManager()->addLibrary(new WebLibrary(
147+
array("../../../vendor/mouf/html.widgets.evolugrid/js/evolugrid.js")
148+
));
149+
150+
$this->content->addFile(dirname(__FILE__)."/../../../../views/tryQuery.php", $this);
151+
$this->template->toHtml();
152+
}
153+
154+
/**
155+
* @Action
156+
* @param string $name
157+
* @param string $selfedit
158+
*/
159+
public function getParameterizedQuery($name,$parameters,$selfedit="false") {
160+
$select = new InstanceProxy($name);
161+
echo $select->toSql(null, $parameters);
162+
}
163+
164+
/**
165+
*
166+
* @Action
167+
* @param string $name
168+
* @param int $offset
169+
* @param int $limit
170+
*/
171+
public function runQuery($name, $parameters, $offset = null, $limit = null) {
172+
$select = new InstanceProxy($name);
173+
$sql = $select->toSql(null, $parameters);
174+
175+
// TODO: point to the right dbConnection
176+
$dbConnection = new InstanceProxy("dbConnection");
177+
$results = $dbConnection->getAll($sql, \PDO::FETCH_ASSOC, "stdClass", $offset, $limit);
178+
179+
$evolugridResultSet = new EvoluGridResultSet();
180+
$evolugridResultSet->setResults($results);
181+
182+
$evolugridResultSet->output(EvoluGridResultSet::FORMAT_JSON);
108183
}
109184
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
<?php
2+
namespace Mouf\Database\QueryWriter\Utils;
3+
4+
use Mouf\MoufInstanceDescriptor;
5+
6+
/**
7+
* This class is used to find conditions recursively inside a MoufInstanceDescriptor
8+
*
9+
*/
10+
class FindParametersService {
11+
/**
12+
* Tries to find parameters recursively in the instances and retrieves the list of parameters found.
13+
*
14+
* @param unknown $instanceName
15+
*/
16+
public static function findParameters(MoufInstanceDescriptor $instanceDescriptor) {
17+
return array_keys(self::recursiveFindParameters($instanceDescriptor)[1]);
18+
}
19+
20+
/**
21+
*
22+
* @param MoufInstanceDescriptor $instanceDescriptor
23+
* @param array<string> $visitedInstances The list of names of visited instances.
24+
*/
25+
private static function recursiveFindParameters(MoufInstanceDescriptor $instanceDescriptor, array $visitedInstances = array(), array $foundParameters = array()) {
26+
if (isset($visitedInstances[$instanceDescriptor->getIdentifierName()])) {
27+
return array($visitedInstances, $foundParameters);
28+
}
29+
$visitedInstances[$instanceDescriptor->getIdentifierName()] = true;
30+
31+
if ($instanceDescriptor->getClassDescriptor()->getName() == "SQLParser\\Node\\Parameter") {
32+
$foundParameters[$instanceDescriptor->getProperty("name")->getValue()] = true;
33+
return array($visitedInstances, $foundParameters);
34+
}
35+
if ($instanceDescriptor->getClassDescriptor()->getName() == "Mouf\\Database\\QueryWriter\\Condition\\ParamAvailableCondition"
36+
|| $instanceDescriptor->getClassDescriptor()->getName() == "Mouf\\Database\\QueryWriter\\Condition\\ParamEqualsCondition"
37+
|| $instanceDescriptor->getClassDescriptor()->getName() == "Mouf\\Database\\QueryWriter\\Condition\\ParamNotAvailableCondition") {
38+
$foundParameters[$instanceDescriptor->getProperty("parameterName")->getValue()] = true;
39+
return array($visitedInstances, $foundParameters);
40+
}
41+
42+
$classDescriptor = $instanceDescriptor->getClassDescriptor();
43+
/* @var $classDescriptor MoufReflectionClass */
44+
foreach ($classDescriptor->getInjectablePropertiesByConstructor() as $moufPropertyDescriptor) {
45+
/* @var $moufPropertyDescriptor MoufPropertyDescriptor */
46+
$name = $moufPropertyDescriptor->getName();
47+
48+
$value = $instanceDescriptor->getConstructorArgumentProperty($name)->getValue();
49+
if ($value instanceof MoufInstanceDescriptor) {
50+
list($visitedInstances, $foundParameters) = self::recursiveFindParameters($value, $visitedInstances, $foundParameters);
51+
} elseif (is_array($value)) {
52+
foreach ($value as $val) {
53+
if ($val instanceof MoufInstanceDescriptor) {
54+
list($visitedInstances, $foundParameters) = self::recursiveFindParameters($val, $visitedInstances, $foundParameters);
55+
}
56+
}
57+
}
58+
}
59+
60+
foreach ($classDescriptor->getInjectablePropertiesBySetter() as $moufPropertyDescriptor) {
61+
/* @var $moufPropertyDescriptor MoufPropertyDescriptor */
62+
$name = $moufPropertyDescriptor->getName();
63+
64+
$value = $instanceDescriptor->getSetterProperty($name)->getValue();
65+
if ($value instanceof MoufInstanceDescriptor) {
66+
list($visitedInstances, $foundParameters) = self::recursiveFindParameters($value, $visitedInstances, $foundParameters);
67+
} elseif (is_array($value)) {
68+
foreach ($value as $val) {
69+
if ($val instanceof MoufInstanceDescriptor) {
70+
list($visitedInstances, $foundParameters) = self::recursiveFindParameters($val, $visitedInstances, $foundParameters);
71+
}
72+
}
73+
}
74+
}
75+
76+
foreach ($classDescriptor->getInjectablePropertiesByPublicProperty() as $moufPropertyDescriptor) {
77+
/* @var $moufPropertyDescriptor MoufPropertyDescriptor */
78+
$name = $moufPropertyDescriptor->getName();
79+
80+
$value = $instanceDescriptor->getInjectablePropertiesByPublicProperty($name)->getValue();
81+
if ($value instanceof MoufInstanceDescriptor) {
82+
list($visitedInstances, $foundParameters) = self::recursiveFindParameters($value, $visitedInstances, $foundParameters);
83+
} elseif (is_array($value)) {
84+
foreach ($value as $val) {
85+
if ($val instanceof MoufInstanceDescriptor) {
86+
list($visitedInstances, $foundParameters) = self::recursiveFindParameters($val, $visitedInstances, $foundParameters);
87+
}
88+
}
89+
}
90+
}
91+
92+
return array($visitedInstances, $foundParameters);
93+
}
94+
}

src/SQLParser/Node/Parameter.php

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,58 @@ public function getName() {
6565
public function setName($name) {
6666
$this->name = $name;
6767
}
68+
69+
/**
70+
* @var string
71+
*/
72+
private $autoPrepend;
73+
74+
/**
75+
* @var string
76+
*/
77+
private $autoAppend;
6878

79+
/**
80+
* @return string
81+
*/
82+
public function getAutoPrepend() {
83+
return $this->autoPrepend;
84+
}
85+
86+
/**
87+
* Sets a string that will automatically be appended to the parameter, if the parameter is available.
88+
* Very useful to automatically add "%" to a parameter used in a LIKE.
89+
*
90+
* @Important IfSet
91+
* @param string $autoPrepend
92+
*/
93+
public function setAutoPrepend($autoPrepend) {
94+
$this->autoPrepend = $autoPrepend;
95+
return $this;
96+
}
97+
98+
/**
99+
* @return string
100+
*/
101+
public function getAutoAppend() {
102+
return $this->autoAppend;
103+
}
104+
105+
/**
106+
* Sets a string that will automatically be preprended to the parameter, if the parameter is available.
107+
* Very useful to automatically add "%" to a parameter used in a LIKE.
108+
*
109+
* @Important IfSet
110+
* @param string $autoAppend
111+
*/
112+
public function setAutoAppend($autoAppend) {
113+
$this->autoAppend = $autoAppend;
114+
return $this;
115+
}
116+
117+
118+
119+
69120
/**
70121
* Returns a Mouf instance descriptor describing this object.
71122
*
@@ -75,6 +126,8 @@ public function setName($name) {
75126
public function toInstanceDescriptor(MoufManager $moufManager) {
76127
$instanceDescriptor = $moufManager->createInstance(get_called_class());
77128
$instanceDescriptor->getProperty("name")->setValue($this->name);
129+
$instanceDescriptor->getProperty("autoPrepend")->setValue($this->autoPrepend);
130+
$instanceDescriptor->getProperty("autoAppend")->setValue($this->autoAppend);
78131
return $instanceDescriptor;
79132
}
80133

@@ -95,7 +148,7 @@ public function toSql(ConnectionInterface $dbConnection = null, array $parameter
95148
if ($parameters[$this->name] === null) {
96149
return NULL;
97150
} else {
98-
return "'".addslashes($parameters[$this->name])."'";
151+
return "'".addslashes($this->autoPrepend.$parameters[$this->name].$this->autoAppend)."'";
99152
}
100153
}
101154
} else {

src/SQLParser/Query/Select.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
*
5151
* @author David Négrier <[email protected]>
5252
* @ExtendedAction {"name":"Generate from SQL", "url":"parseselect/", "default":false}
53+
* @ExtendedAction {"name":"Test query", "url":"parseselect/tryQuery", "default":false}
5354
*/
5455
class Select implements StatementInterface {
5556

src/views/tryQuery.php

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<?php
2+
/* @var $this Mouf\Database\QueryWriter\Controllers\SelectController */
3+
?>
4+
<h1>Test your query</h1>
5+
6+
<pre id="mainQuery"><code><?php echo $this->sql; ?></code></pre>
7+
8+
<?php if (!empty($this->parameters)): ?>
9+
<div class="row">
10+
<div class="span6">
11+
<h2>Configure parameters</h2>
12+
13+
<form action="" class="form-horizontal" id="parametersform">
14+
<input type="hidden" name="name" value="<?php echo plainstring_to_htmlprotected($this->instanceName); ?>" />
15+
<?php foreach ($this->parameters as $parameter) { ?>
16+
<div class="control-group">
17+
<label class="control-label"><?php echo plainstring_to_htmlprotected($parameter); ?>: </label>
18+
<div class="controls">
19+
<input type="text" name="parameters[<?php echo plainstring_to_htmlprotected($parameter); ?>]" value="" />
20+
</div>
21+
</div>
22+
<?php } ?>
23+
</form>
24+
</div>
25+
<div class="span6">
26+
<h2>Query with parameters</h2>
27+
<pre><code id="createdSql"></code></pre>
28+
</div>
29+
</div>
30+
31+
<script type="text/javascript">
32+
function updateQuery() {
33+
var jqxhr = $.ajax( "getParameterizedQuery?"+$("#parametersform").serialize() )
34+
.done(function(data) {
35+
$("#createdSql").text(data);
36+
$('code#createdSql').each(function(i, e) {hljs.highlightBlock(e)});
37+
})
38+
.fail(function(jqXHR, textStatus, errorThrown) {
39+
addMessage("<pre>"+textStatus+":"+errorThrown+"</pre>", "error");
40+
});
41+
}
42+
43+
$(document).ready(function() {
44+
$("#parametersform input").keyup(function() {
45+
updateQuery();
46+
});
47+
updateQuery();
48+
49+
$('pre#mainQuery code').each(function(i, e) {hljs.highlightBlock(e)});
50+
});
51+
</script>
52+
53+
<?php endif; ?>
54+
55+
<div class="form-actions">
56+
<a href=".?name=<?php echo urlencode($this->instanceName) ?>" class="btn">&lt; Edit Query</a>
57+
<button type="button" class="btn btn-primary" id="runQueryButton">Run Query</button>
58+
<a href="<?php echo ROOT_URL ?>ajaxinstance/?name=<?php echo urlencode($this->instanceName) ?>" class="btn">View instance &gt;</a>
59+
</div>
60+
61+
<div id="resultsContainer"></div>
62+
63+
<script type="text/javascript">
64+
$(document).ready(function() {
65+
$("#parametersform").submit(function(e) {
66+
e.preventDefault();
67+
$("#resultsContainer").empty();
68+
var grid = $("<div></div>").appendTo("#resultsContainer");
69+
grid.evolugrid({
70+
url: MoufInstanceManager.rootUrl+"parseselect/runQuery?"+$("#parametersform").serialize(),
71+
limit : 50,
72+
infiniteScroll: true
73+
});
74+
});
75+
76+
$("#runQueryButton").click(function() {
77+
$("#parametersform").trigger("submit");
78+
});
79+
80+
});
81+
</script>

0 commit comments

Comments
 (0)