|
2 | 2 |
|
3 | 3 | namespace Mouf\Database;
|
4 | 4 |
|
| 5 | +use function array_filter; |
| 6 | +use function array_keys; |
5 | 7 | use Doctrine\Common\Cache\VoidCache;
|
| 8 | +use function hash; |
| 9 | +use function implode; |
6 | 10 | use Mouf\Database\MagicQuery\Twig\SqlTwigEnvironmentFactory;
|
7 | 11 | use Mouf\Database\SchemaAnalyzer\SchemaAnalyzer;
|
8 | 12 | use PHPSQLParser\PHPSQLParser;
|
@@ -83,9 +87,42 @@ public function build($sql, array $parameters = array())
|
83 | 87 | if ($this->enableTwig) {
|
84 | 88 | $sql = $this->getTwigEnvironment()->render($sql, $parameters);
|
85 | 89 | }
|
| 90 | + |
86 | 91 | $select = $this->parse($sql);
|
| 92 | + $newSql = $this->toSql($select, $parameters, true); |
87 | 93 |
|
88 |
| - return $this->toSql($select, $parameters); |
| 94 | + return $newSql; |
| 95 | + } |
| 96 | + |
| 97 | + /** |
| 98 | + * Returns modified SQL from $sql and $parameters. Any parameters not available will be striped down |
| 99 | + * from the SQL. Unlike with the `build` method, the parameters are NOT merged into the SQL. |
| 100 | + * This method is more efficient than `build` (because result is cached and statements interpolation |
| 101 | + * can be delegated to the database. |
| 102 | + * |
| 103 | + * @param string $sql |
| 104 | + * @param array $parameters |
| 105 | + * |
| 106 | + * @return string |
| 107 | + */ |
| 108 | + public function buildPreparedStatement(string $sql, array $parameters = []): string |
| 109 | + { |
| 110 | + if ($this->enableTwig) { |
| 111 | + $sql = $this->getTwigEnvironment()->render($sql, $parameters); |
| 112 | + } |
| 113 | + |
| 114 | + $availableParameterKeys = array_keys(array_filter($parameters, static function($param) { return $param !== null;})); |
| 115 | + // We choose md4 because it is fast. |
| 116 | + $cacheKey = 'request_build_'.hash('md4', $sql.'__'.implode('_/_', $availableParameterKeys)); |
| 117 | + $newSql = $this->cache->fetch($cacheKey); |
| 118 | + if ($newSql === false) { |
| 119 | + $select = $this->parse($sql); |
| 120 | + $newSql = $this->toSql($select, $parameters, false); |
| 121 | + |
| 122 | + $this->cache->save($cacheKey, $newSql); |
| 123 | + } |
| 124 | + |
| 125 | + return $newSql; |
89 | 126 | }
|
90 | 127 |
|
91 | 128 | /**
|
@@ -129,13 +166,14 @@ public function parse($sql)
|
129 | 166 | * Transforms back a tree of SQL node into a SQL string.
|
130 | 167 | *
|
131 | 168 | * @param NodeInterface $sqlNode
|
132 |
| - * @param array $parameters |
133 |
| - * |
| 169 | + * @param array $parameters |
| 170 | + * @param bool $extrapolateParameters Whether the parameters should be fed into the returned SQL query |
| 171 | +
|
134 | 172 | * @return string
|
135 | 173 | */
|
136 |
| - public function toSql(NodeInterface $sqlNode, array $parameters = array()) |
| 174 | + public function toSql(NodeInterface $sqlNode, array $parameters = array(), bool $extrapolateParameters = true) |
137 | 175 | {
|
138 |
| - return $sqlNode->toSql($parameters, $this->connection, 0, SqlRenderInterface::CONDITION_GUESS); |
| 176 | + return $sqlNode->toSql($parameters, $this->connection, 0, SqlRenderInterface::CONDITION_GUESS, $extrapolateParameters); |
139 | 177 | }
|
140 | 178 |
|
141 | 179 | /**
|
|
0 commit comments