While it is possible to have multiple arguments for the updateOrInsert in Laravel query builder and what is the operator used by default.
For example in the documentation it is mentioned:
DB::table('users')
->updateOrInsert(
['email' => 'john#example.com', 'name' => 'John'],
['votes' => '2']
);
Does that mean that email && name are checked or does it mean email || name is checked? How can we control it for one or the other if required?
Please forgive me if this is a silly question or if it is not worded as per the correct vocabulary, as I am new to Laravel. I couldn't find this information in the documentation or API.
updateOrInsert() method is used to update an existing record in the database if matching the condition or create if no matching record exists. Its return type is Boolean.
Syntax :
DB::table('blogs')->updateOrInsert(
[Conditions],
[fields with value]
);
In your query :
DB::table('users')->updateOrInsert(
['email' => 'john#example.com', 'name' => 'John'],
['votes' => '2']
);
It will check if email == 'john#example.com' & name == 'john', then it will update votes=2.
I have this query that does what I want which is to return true if any of the materials is comparable in the material groups list.
mgroup.MaterialGroups.Select(x => x.Materials
.Any(m => Convert.ToBoolean(m.Comparable)))
.Any(x => x.Equals(true))
What I would like to add to this query is to also include this one.
mgroup.Materials.Any(m => Convert.ToBoolean(m.Comparable));
How can I combine mgroup and it's materialgroups together in the query so I can select both of their Materials? Thanks.
EDIT - After fighting with LINQ for awhile I broke down and just combined as
mgroup.Materials.Any(m => Convert.ToBoolean(m.Comparable) ||
mgroup.MaterialGroups.Select(x => x.Materials
.Any(c => Convert.ToBoolean(c.Comparable)))
.Any(x => x.Equals(true)))
It works as expected but it's horribly long and it's embedded in an Asp.net MVC view to makes things even worse. If anyone can simplify this that would be amazing.
P.S.- If you are wondering why I added the extra .Any(x => x.Equals(true) at the end it's because without it the query returns an IEnumerable of bools instead of bool.
IEnumerable<Material> allMaterials =
mgroup.Materials.Concat(
mgroup.MaterialGroups.SelectMany(group => group.Materials));
bool result = allMaterials.Any(m => Convert.ToBoolean(m.Comparable));
i want the alternative cakephp code for the above query
Select * from book where title like '%java%;
OK, assuming you are using a find() query.
You can specify the conditions array as follows:
"conditions" => array("Book.title like" => "%java%")
or
"conditions" => array("Book.title like '%java%'")
I think both will work
Docu complex find conditions
$this->Post->find('first', array (
"Author.name" => "Bob",
"OR" => array (
"Post.title LIKE" => "%magic%",
"Post.created >" => date('Y-m-d', strtotime("-2 weeks"))
)
));
I want to use composite key in ActiveRecord.
I got two tables.
Quotes and Comments.
Quotes contains pk - id;
Comments pk is composite - module, section, cid
module - module name, where comments come from.
section - section of this module
cid - identificator, in this situaction this is id of quote.
In comments I defined primary key like so.
public function primaryKey()
{
return array('module', 'section', 'cid');
}
Next one, I want to get those records, what related to quotes.
So, in Quotes I declared relation:
'comments' => array(self::HAS_MANY, 'Comment', 'module, section, cid', 'params' => array(
':ypl0' => '"quotes"',
':ypl1' => '"quote"',
':ypl2' => 'id'
)),
The required result is:
SELECT * FROM quotes q
LEFT JOIN comments c ON (c.cid = q.id AND module = "quotes" AND section = "quote")
WHERE c.id IS NULL
SQL is working, relation - not. What I'm doing wrong?
Try the following untested code
'comments' => array(self::HAS_MANY, 'Comment', 'cid','condition'=>'module=:param1 AND section=:param2','params' => array(':param1' => 'quotes',':param2' => 'quote',)),
I am trying to build a query dynamically. It's initial state is fine. This is the initial where clause that should be present on every query
$qb->add('where', $qb->expr()->andx(
$qb->expr()->eq('s.competitor', $competitor),
$qb->expr()->eq('s.ignored', $ignored),
$qb->expr()->eq('s.id', $params['s_id']),
$qb->expr()->eq('s.id', 'k.targetSite')
), true);
But the app I am building allows users to filter. When that happens, I want to add additional where clauses into my query builder. When this line is executed later in the code, it overwrites the above where statement.
$qb->add('where', $qb->expr()->like($col, $val), true );
From what I have read, the 3rd parameter $append should keep the previous statements, but that's not happening. In Doctrine 1.2, I could just do something like this:
foreach($filter as $col => $val) {
$dql->addWhere($col = ?, array($val));
}
How do I dynamically add where clauses to my QueryBuilder?
Update
Here is a full statement
$where = array('col' => 'k.text', 'val' => 'some word%');
$qb = $this->entityManager->createQueryBuilder()
->select('s, sc')
->from('Dashboard\Entity\Section', 'sc')
->innerJoin('sc.keyword', 'k')
->innerJoin('sc.site', 's')
->leftJoin('k.keywordCategory', 'kc')
->leftJoin('k.keywordSubCategory', 'ksc');
$qb->add('where', $qb->expr()->andx(
$qb->expr()->eq('s.competitor', $competitor),
$qb->expr()->eq('s.ignored', $ignored),
$qb->expr()->eq('s.id', $params['s_id']),
$qb->expr()->eq('s.id', 'k.targetSite')
), true);
if ($where) {
$qb->add('where', $qb->expr()->andx(
$qb->expr()->like($where['col'], $where['val'])
), true);
}
$qb->addGroupBy('k.id');
$qb->addGroupBy('s.id');
$qb->setFirstResult( $params['start'] )
->setMaxResults( $params['limit'] );
$q = $qb->getQuery();
echo $q->getSql();
And the output is
SELECT s0_.id AS id0, k1_.id AS id1, k1_.name AS name2, k2_.id AS id3, k2_.name AS name4, k3_.id AS id5, k3_.text AS text6, k3_.search_vol AS search_vol7, s4_.id AS id8, s4_.sub_domain AS sub_domain9, MIN(s0_.rank) AS sclr10, MAX(s0_.created) AS sclr11
FROM section s0_
INNER JOIN keyword k3_ ON s0_.k_id = k3_.id
INNER JOIN site s4_ ON s0_.s_id = s4_.id
LEFT JOIN keyword_category k1_ ON k3_.k_cat_id = k1_.id
LEFT JOIN keyword_sub_category k2_ ON k3_.k_subcat_id = k2_.id
WHERE k3_.text LIKE 'some word%'
GROUP BY k3_.id, s4_.id LIMIT 25 OFFSET 0
If I don't add in that if ($where) clause, then the first andx where statements are still in place. But when I try to dynamically add them, only the final WHERE statement is added, all others are cleared. I should also add, that I tried it like this as well.
if ($where) {
$qb->add('where', $qb->expr()->like($where['col'], $where['val']), true);
}
I can successfully use
$qb->andWhere( $qb->expr()->like($where['col'], $where['val']) );
But the API docs for Query Builder state the way I am trying to use it should be valid too. Wanted to make sure I was doing it right, or if it was a bug.
You're able to use the ->andWhere() normally (and it will also fixes your issue).
Doctrine 2 QueryBuilder is a rather innovative concept (because it mixes both programmatic and fluent styles), and there are likely bugs associated to it.
One point that you should notice in your code: Instead of play with ->add('where', ...), you should think programmatic. Add more items to andX() object and at the end associate to the ->add('where', ...) (or even better: ->where(...))
Looking at the code, it seems like what you're trying to do won't work, though whether that's documented anywhere or is just a bug is open to question, I think.
In add(), the DQL part you pass in seems only ever to be appended if the part is already stored as an array in the query builder:
$isMultiple = is_array($this->_dqlParts[$dqlPartName]);
...
if ($append && $isMultiple) {
if (is_array($dqlPart)) {
$key = key($dqlPart);
$this->_dqlParts[$dqlPartName][$key][] = $dqlPart[$key];
} else {
$this->_dqlParts[$dqlPartName][] = $dqlPart;
}
} else {
$this->_dqlParts[$dqlPartName] = ($isMultiple) ? array($dqlPart) : $dqlPart;
}
And the WHERE clause, unlike most of the other DQL parts, is not initialised to an array:
private $_dqlParts = array(
'select' => array(),
'from' => array(),
'join' => array(),
'set' => array(),
'where' => null,
'groupBy' => array(),
'having' => null,
'orderBy' => array()
);
Now, this looks a bit like it's by design, but Doctrine 2 is fairly new and this bit seems to have been evolving recently. Personally, I'd raise a bug against this behaviour and see what the project people say. If nothing else, you might end up with improved documentation...