-
Is it possible to rewrite statements with a WHERE clause. So given this: "SELECT * FROM inventory ORDER BY date LIMIT 10" Should become: "SELECT * FROM inventory WHERE userid='Jack' ORDER BY date LIMIT 10 " And do this for arbitrary statements: SELECT, DELETE, UPDATE, UNION, sub-queries? The use-case is an application which let users run arbitrary statements over HTTP and we want to add a rule based system, so users only can select and change data according to rules. A rule could be: User: Jack; Relation: inventory; Operation: SELECT; rule: userid='jack' |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments
-
Assuming I correctly understand your question, you need to create a $select = $factory->createFromString("SELECT * FROM inventory ORDER BY date LIMIT 10"); and then add the criterion to its $select->where->and("userid='Jack'"); This will work for any type of statement having a WHERE clause. Only I'd recommend against embedding constants in criteria, use parameters instead $select->where->and("userid = :userid"); |
Beta Was this translation helpful? Give feedback.
-
Yes, that works. But now I have a sub-query like this: SELECT *, (select foo from bar limit 1) as bib FROM bup; And I get this: select *, (
select foo
from bar
limit 1
) as bib
from bup
where userid = 'Jack' I would like to add one WHERE clause to the bup SELECT and another to the sub-query on bib. Can it be done? |
Beta Was this translation helpful? Give feedback.
-
If $select->list[1]->expression->query->where is the WHERE clause of the subselect in its target list. A bit of explanation: |
Beta Was this translation helpful? Give feedback.
-
Thanks for the input. I figured out how to create a walker class, which will (I think) set WHERE clause on all statements. Thanks for the great work! class TableWalker extends BlankWalker
{
public function walkSelectStatement(Select $statement)
{
foreach ($statement->from->getIterator() as $from) {
// Check rule for $from->name->relation->value and set WHERE
$statement->where->and("userid='SELECT'");
}
parent::walkSelectStatement($statement);
}
public function walkUpdateStatement(Update $statement)
{
// Check rule for $statement->relation->relation->relation->value and set WHERE
$statement->where->and("userid='UPDATE'");
parent::walkUpdateStatement($statement);
}
public function walkDeleteStatement(Delete $statement): void
{
foreach ($statement->using->getIterator() as $using) {
// Check rule for $using->name->relation->value and set WHERE
$statement->where->and("userid='USING'");
}
// Check rule for $statement->relation->relation->relation->value and set WHERE
$statement->where->and("userid='DELETE'");
parent::walkDeleteStatement($statement);
}
public function walkInsertStatement(Insert $statement)
{
// Check rule for $statement->relation->relation->relation->value and set WHERE
if (!empty($statement->onConflict)) $statement->onConflict->where->and("userid='INSERT'");
parent::walkInsertStatement($statement);
}
} |
Beta Was this translation helpful? Give feedback.
Thanks for the input. I figured out how to create a walker class, which will (I think) set WHERE clause on all statements. Thanks for the great work!