CakePHP query binding - php

I want to create a sql statement with cakePHP 3.6.10:
SELECT id FROM table_xy WHERE (status != 1 OR name IS NULL) AND id IN(1,2,3);
Now, copying from the sophistated examples in the cookbook I got this:
$userIds = [2,212,232];
$table = TableRegistry::getTableLocator()->get('TableXY');
$query = $table->find()
->select(['id'])
->where(function(QueryExpression $exp) {
$orConditions = $exp->or_(function($or) {
return $or->isNull('name')
->notEq('status', 1);
});
return $exp
->add($orConditions)
->in('id', ':id');
})
->bind(':id', $userIds, 'int[]');
$results = $query->all();
This results in an error, saying "unknown type int[]". But this is exactly the same as described in the documentation
$query->bind(':id', [1, 2, 3], 'int[]');
Any ideas?

Instead of such sophisticated example, you can try like this:
// an array is not automatically converted
$result = $this->table_xy->find('all')->where(['id IN' => $userIds,
'OR' => [
'status !=' => 1,
'name is NULL'
]
])->select(['id']);
CAKEPHP > Query Builder > Advanced Conditions

Related

Php Sphinx, Using Or in setFilter()

Below is my fetch code for sphinx. We have a filter named typeId which we use to compare bureau type. Now I have added one more filter named as altTypeId. Now I have to compare typeId and altTypeId both for same value such typeId = 6 OR altTypeId = 6.
I have tried several solutions but no one is working. I followed the solution on this link: https://sphx.org/forum/view.html?id=13474 but its not working as well.
protected function fetch() {
$this->_searchCriteria->orders = $this->sort;
$this->pagination->validateCurrentPage = false;
$this->_searchCriteria->paginator = $this->pagination;
$this->_searchCriteria->query.=" profileTypePlaceholderTexxxxxt";
Yii::app()->search->SetLimits($this->pagination->offset, $this->pagination->limit);
Yii::app()->search->SetFieldWeights($this->_fieldWeights);
if ($this->_searchCriteria->query)
Yii::app()->search->setMatchMode(SPH_MATCH_ALL);
else
Yii::app()->search->setMatchMode(SPH_MATCH_FULLSCAN);
Yii::app()->search->setFieldWeights(array(
'primary_comp' => 100,
'premium' => 80,
'standard' => 60,
'free' => 40,
'comp' => 20,
'title' => 5,
'description' => 5,
));
//Yii::app()->search->SetSortMode(SPH_SORT_EXTENDED, '#weight DESC');
Yii::app()->search->SetSortMode(SPH_SORT_EXTENDED,'#weight DESC, random DESC');
foreach ($this->_searchCriteria->filters as $filter) {
if ($filter[0] == 'range')
Yii::app()->search->SetFilterFloatRange($filter[1], (float) $filter[2] + 0.01, (float) $filter[3]);
else
Yii::app()->search->SetFilter($filter[0], array($filter[1]));
}
$results = Yii::app()->search->Query($this->_searchCriteria->query, $this->_searchCriteria->from);
$this->_data = array();
$this->_keys = array();
$this->_itemCount = $results['total'];
$this->pagination->itemCount = $this->_itemCount;
if ($this->_itemCount) {
$this->_populateItems($results['matches']);
}
}
Frankly putting both values in the same sphinx attrbute, seems easiest. MVA is perfect for this!
Couple of ways could be done, but just...
sql_query = SELECT id,title, CONCAT_WS(',',typeId,altTypeId) AS typeids FROM ...
sql_attr_multi = uint typeids from field
then just
->SetFilter('typeids', array(6));
finds results from EITHER column.
Otherwise if really want to only do it at query time, its something like
if ($filter[0] == 'typeid') {
Yii::app()->search->SetSelect("*, (typeid = {$filter[1]} OR altTypeId = {$filter[1]}) AS myfilter");
Yii::app()->search->SetFilter('myfilter', array(1));
} else ...

Codeigniter Select and (conditional) Update Query

I am using Codeigniter 3, PHP and MySQL.
I'm trying to select a record from a MySQL database, and depending on the result run an update query.
If result = 0, update.
If result = 1, do nothing.
My code so far is;
public function addData($itemId) {
$gDescription = 'test';
$gPreviewLink = 'test';
$gThumbnail = 'test';
$gPageCount = 'test';
$this->db->select('g_data');
$this->db->from('item');
$this->db->where('item_id', $itemId);
$query = $this->db->get();
$result = $query->result();
// var_dump($result) returns array(1) { [0]=> object(stdClass)#22 (1) { ["g_data"]=> string(1) "0" } }
$data = array(
'item_description' => $gDescription,
'item_preview_link' => $gPreviewLink,
'item_thumbnail' => $gThumbnail,
'item_pageCount' => $gPageCount,
'g_data' => '1',
'g_data_timestamp' => 'NOW()'
);
// if result = 0 update
if($result == '0') {
$this->db->where('item_id',$itemId);
$this->db->update('item', $data);
}
}
Is there any reason the data won't update in my database? I'm not receiving any error messages.
Any help would be appreciated.
$query->result() returns an array of objects where each object is a row from the table. (As you can see in the var_dump in your comments)
Without other changes your conditional should be
if($result->g_data == '0') { ...
That said, you should have checked earlier in the method that the database atually returned results. Also, you don't need more than one row so don't use result() use 'row()' instead
...
$query = $this->db->get();
// The following will set $result to the value of "g_data" if there
// are rows and to "0" if there are none.
$result = $query->num_rows() > 0 ? $query->row()->g_data: '0';
...
If you do the above then the conditional can remain as you have it coded
if($result == '0') {...
Executing the SELECT query means making an unnecessary extra trip to the database. Just build your 0 criteria into your UPDATE query -- if it is not satisfied, then no rows will be affected.
Code:
$data = [
'item_description' => $gDescription,
'item_preview_link' => $gPreviewLink,
'item_thumbnail' => $gThumbnail,
'item_pageCount' => $gPageCount,
'g_data' => '1'
];
$this->db->where([
'item_id' => $itemId,
'g_data' => 0
]);
$this->db->set('g_data_timestamp', 'NOW()', false);
$this->db->update('item', $data);
// return (bool)$this->db->affected_rows();
All done in a single query execution. I also took the liberty of demonstrating how to pass a MySQL function as a value using set()'s third parameter.

php mongoclient - trying to query records that only have a "department" field

I have made the following attempt to query documents that have a department value filled in:
$collection = $this->mongo_db->db->selectCollection('widget');
$result = $collection->find(
array("department"=>array('$ne' => null),"department"=> array('$ne' => ""))
)->sort(['department'=>1]);
return iterator_to_array($result);
But this is still returning documents that look like this:
{
"_id" : ObjectId("5824b9376b6347a422aae017"),
"widgetnum" : "1840023",
"last_assigned" : "missing"
}
I thought the
"department"=>array('$ne' => null)
would have filtered this out.
Any suggestions?
For you perfect will be $exists operator.
https://docs.mongodb.com/manual/reference/operator/query/exists/
Query should look something like this(select all documents where department exists and does not equal to "").
$collection = $this->mongo_db->db->selectCollection('widget');
$result = $collection->find(
array( "department"=> array('$exists' => "true", '$nin': [""]) )
)->sort(['department'=>1]);
return iterator_to_array($result);
Hope this helps.

How to filter a result returned by a function get_entries() of a stream entries driver in pyrocms?

I have a stream/table named profiles. All of its column are stream-fields. I am trying to restrict the result returned by the the function, get_entries() depending on some criteria. Below is my code:
$data = [
'stream' => 'profiles',
'namespace' => 'users',
'where' => 'user_id = 3' // lets say, this is my criteria
];
$row = $this->streams->entries->get_entries($data); // returns empty
The varaible, $row resulted in empty array. Although there is one row in table, profiles where user_id is 3. I have read the documentation of pyrocms and it pretty much says the exact way to use the where clause (just like above).
NOTE: I have also tried writing like
'where' => 'profiles.user_id = 3'`
joy !to avoid table conflict. Still no
But when I write the code like this:
$row = $this->streams->entries->get_entries($query);
$query = [
'stream' => 'profiles',
'namespace' => 'users'
];
// No where clause this time
$row = $this->streams->entries->get_entries($query);
This time $row returns all rows including the row with user id 3.
I am unable to use the where clause in get_entries in a right way. I might have done some mistake. Help me out guyz
NOTE: I am using community edition.
I think this might be due to a bug (well, not a bug, but a feature that doesn't work as intended).
If I'm intentionally issue a wrong query, the sql query output is
SELECT [ ... ] LEFT JOIN `default_profiles` as `profiles` ON `profiles`.`user_id`=`default_profiles`.`created_by` WHERE (user_id` = 1) ORDER BY `default_profiles`.`created` DESC
Here you see that PyroCMS tries to lookup the data for the "created_by" field. And that doesn't work in this case.
If you disable the 'created_by' field, you should get the correct row:
$this->streams->entries->get_entries(
array(
'stream' => 'profiles',
'namespace' => 'users',
'where' => 'user_id = 3',
'disable' => 'created_by'
)
);
It would be great if you could file an issue on the pyrocms github page. If you won't I'll do it in the next few days.
Model
public function get_entries($table, $where) {
$this->db->select('*');
$this->db->from($table);
foreach ($where as $key => $value) {
$this->db->where($key, $value);
}
$this->query = $this->db->get();
foreach ($this->query->result_array() as $row) {
$array1[] = $row;
}
if ($this->query->num_rows() == 0)
return false;
else
return $array1;
}
call this model function as
$row = $this->streams->entries->get_entries('profiles',array('user_id '=>3));

How to get _id MongoDB/php?

I do this way:
$cursorLocations = $collection->find( array("locationName" => $locationName) )->limit(1);
if ($cursorLocations->count(true) == 1) {
$idLocations = $cursorLocations->getNext();
echo $idLocations["_id"];
}
I immediately apologize if this question has been, but read the documentation did not find an answer.
Maybe some other way to get the _id?
in Mongo :
db.collection.find({'field': 'value'}, {'_id' : 1});
in PHP:
$cursorLocations = $collection->find( array("locationName" => $locationName), array('_id' => 1) )->limit(1);
The above code will limit your query to retrieving only the _id field and not the other fields, you would still have to extract the value of that field from the result of the find() function - from the $cursor object, like in:
$_id = $cursorLoactions[`_id`];
There is also a MongoCursor method key() which returns the current _id:
http://www.php.net/manual/en/mongocursor.key.php
So you could do this:
$cursorLocations = $collection->find( array("locationName" => $locationName) )->limit(1);
$_id = $cursorLocations->key();

Categories