[FLOW3-general] Persistance\Query

Rik luiheidsgoeroe at hotmail.com
Wed May 12 01:57:00 CEST 2010


Georg Ortner wrote:

> I'm implementing a tree of categories. My category model got a property
> called parent which can be a parent category or NULL. Now I want to
> create a query to search for all categories which have no parent (The
> root categories).
> 
> $query->matching($query->equals('parent'), NULL)->execute();
> 
> But this doesn't work. Isn't this a proper way to ask if parent is a
> Category Object or NULL?
> 
> When I call $category->getParent() I'm getting NULL on the same Object
> which hasn't met the criteria for the above query...
> 
> Do I really have to introduce another property to store the information
> if this is a root category or not? I'm sure there is a better solution
> I'm just too much of a user to find it on my own right now.

A.T.M, I cannot see a NULL safe comparison in either:

F3\FLOW3\Persistence\Backend\GenericPdo\Backend or 
F3\FLOW3\Persistence\Backend\AbstractSqlBackend

and it's not defined in F3\FLOW3\Persistence\QueryInterface

equals() adds an OPERATOR_EQUAL_TO ('='), which won't work. People more into 
the code (just started checking Flow3 out), feel free to correct me... 

In MySQL only we could change it to '<=>', but AFAIK we should use 'IS NULL' 
instead to keep things compatible.

Quick & dirty fix would be altering
F3\FLOW3\Persistence\Backend\GenericPdo\Backend::parseComparison(),

...
} else if ($comparison->getOperator() === 
\F3\FLOW3\Persistence\QueryInterface::OPERATOR_EQUAL_TO && 
is_null($comparison->getOperand2())){
    $sql['where'] = '( '.$comparison->getOperand1()->getSelectorName().' IS 
NULL )';
} else {
  $this->parseDynamicOperand(//etc..


Probably it will have to be written a lot more robust from the beginning, it 
would mean altering F3\FLOW3\Persistence\Query:
  - Either equals() should check $operand & set a newly defined  
F3\FLOW3\Persistence\QueryInterface::OPERATOR_IS_NULL (or something like 
that name) 
  - Or an isnull() function should be created, possibly with a new 
Constraint class.

Which is quite scary, as I don't know how it will affect non- or other-SQL 
backends if there are any, anyway, to continue:
Depending on an earlier choice, when going with the 'keep using the 
Comparison class':

- F3\FLOW3\Persistence\Backend\AbstractSqlBackend::resolveOperator() should 
create / return 'IS NULL' (well, at least not throw an exception), 
- F3\FLOW3\Persistence\Backend\GenericPdo\Backend::parseComparison() should 
make an exception for the 
F3\FLOW3\Persistence\QueryInterface::OPERATOR_IS_NULL type, adding the 
getOperand1().' '.getOperator()

When going with the whole new 'is null' constraint:
-  Alter parseConstraint() (which imho could do with a switch  & exception 
on default instead of chaining if/else statements), adding the logic there.


Thought about just altering the parseDynamicOperand() function, but in that 
case  parseComparison() will still enter NULL as a parameter, which we don't 
want.

P.S: you're replying to an unrelated thread, please start a new one for a 
new question.
-- 
Rik


More information about the FLOW3-general mailing list