Symfony Propel criteria - mysql

Is there any possible way to convert the MySQL object into criteria object? I tried this query:
select
p.disrepid,
p.subject, p.body,
c.disrepid as disrepid1,
c.subject as subject1,
c.body as body1
from discusreply as p, discusreply as c
where p.distopid=' . $this->id . '
and (c.disrepid = p.parentid or c.parentid = p.distopid)
order by p.disrepid ASC
I tried a lot for converting this query into a Criteria, But nothing happened. I want this criteria object for passing this into Pager class for completing the pagination.
$pager->setCriteria($c);.

You can use your own SQL do perform a query, but there is no automated way to turn sql into a Criteria object.
$con = Propel::getConnection(DATABASE_NAME);
$sql = "SELECT books.* FROM books
WHERE NOT EXISTS (SELECT id FROM review WHERE book_id = book.id)";
$stmt = $con->createStatement();
$rs = $stmt->executeQuery($sql, ResultSet::FETCHMODE_NUM);
$books = BookPeer::populateObjects($rs);
This bypasses Criterion objects all together. You mentioned wanting a criteria object so you could feed this into a pager. You can instead set a custom select method into your pager, which will then perform your custom query. If you need to pass a parameter into this, I would recommend extending sfPropel with your own pager class that can optionally pass parameters to your peer select methods so you don't have to use Criteria objects at all. As a quick alternative, you can do something like this, using your Criteria as a container for your select parameters:
$c = new Criteria();
$c->add(DiscussreplyPeer::ID, $myId);
$pager = new sfPropelPager();
$pager->setCriteria($c);
$pager->setPeerMethod('getReplies');
And then in your peer class:
public static function getReplies(Criteria $c) {
$map = $c->getMap();
$replyId = $map[DiscussreplyPeer::ID]->getValue();
$con = Propel::getConnection(DATABASE_NAME);
$sql = "select p.disrepid, p.subject, p.body, c.disrepid as disrepid1, c.subject as subject1, c.body as body1 from discusreply as p, discusreply as c where p.distopid=? and (c.disrepid = p.parentid or c.parentid = p.distopid) order by p.disrepid ASC";
$stmt = $con->prepareStatement($sql);
$stmt->setString(1, $replyId);
$rs = $stmt->executeQuery();
$results = array();
while ($rs->next()) {
// for example
$results['disrepid'] = $rs->getInt('disrepid');
}
return $results;
}
More tips on propel and symfony can be found at:
http://stereointeractive.com/blog/2007/06/12/propel-queries-using-custom-sql-peer-classes-and-criterion-objects/

This site will help a lot for learning to write criteria - you can use it to generate criteria code from pseudo SQL. I would also recommend grabbing the Symfony/Propel cheat sheets.
For your query in particular you will want something like this:
$c = new Criteria();
$c->addJoin(discusreply::DISREPID, discusreply::PARENTID, Criteria::INNER_JOIN);
$c->clearSelectColumns();
$c->addSelectColumn(discusreplyPeer::Disrepid);
...
$c->add(discusreplyPeer::DISTOPID, $this->id, Criteria::EQUAL);
...
$c->addAscendingOrderByColumn(discusreply::DISREPID);
I'm not sure that the Criteria system supports multiple clauses for an inner join so you may have to revert back to ad-hoc SQL for this query (if it does I would love to know how). The following code will create a ResultSet object similar to what you would get from simple database abstraction layers.
$sql = "SELECT ...";
$dbh = Propel::getConnection([DB]);
$sth = $dbh->createStatement();
$res = $sth->executeQuery($sql, ResultSet::FETCHMODE_NUM);
I don't think there is much of a disadvantage to using the ad-hoc method on a query like this since you will have to deal with ResultSet objects rather than table-specific objects when you are returning only specific columns.

You can try auto-generating the criteria from sql using this site.

Related

MySql Query build using Kohana's ORM

I'm having a hard time to translate the following query into kohana's ORM.
So, if I do the following works fine:
$query = DB::query(Database::SELECT, 'SELECT id_book, MATCH(title, author, isbn) AGAINST (:str) AS score FROM tab_books WHERE status = 1 AND MATCH(title, author, isbn) AGAINST (:str) HAVING score > '.$score.' ORDER BY score DESC LIMIT 100');
However, I need to use an specific class model. So far I have:
$books = new Model_Book();
$books = $books->where('status', '=', 1);
$books = $books->where(DB::expr('MATCH(`title`,`author`,`isbn`)'), 'AGAINST', DB::expr("(:str)"))->param(':str', $search_terms);
Which works fine, except for the fact that I'm unable to use the score value. I need the score because since I changed the table engine to InnoDB, the 2nd query is returning a lot of results.
ORM here: https://github.com/kohana/orm/blob/3.3/master/classes/Kohana/ORM.php
Thank you for your time.
So, you don't use query builder, but ORM object finding.
In first case you take result array on second array of objects.
Trust me, you don't want use list objects. (It's extremely slow)
$sq = DB::expr('MATCH(title, author, isbn) AGAINST (:str) AS score')
->param(":str", $search_terms);
$wq = DB::expr('MATCH(title, author, isbn)');
$query = DB::select('id_book', $sq)
->from('tab_books') // OR ->from($this->_table_name) for model method
->where('status','=',1) ->where($wq, 'AGAINST ', $search_terms)
->order_by('score', desc)->limit(100) //->offset(0)
->having('score', '>', $score);
$result = $query->execute()->as_array();
for query test:
die($query->compile(Database::instance()));
OT: Use
$books = ORM::factory('Book')->full_text($search_terms, $score);
instead $books = new Model_Book();

how to display count() sql function using php

how to display count() sql function using php
$results = "SELECT count(votesnumber) FROM `votes` WHERE `candidate_id` = '$candidate_id'";
$queryresults = mysqli_query($connect, $results);
if($queryresults) {
$rowresults = mysqli_fetch_assoc($queryresults);
echo $rowresults['votesnumber'];
} else {
echo "error";
}
i want to display the results of sql count() function using php. am counting specific columns WHERE ID = "some value" in phpmyadmin its working but with php its giving me headache . any ideas on how to solve this?
Try this:
$results = "SELECT count(votesnumber) AS VoteNum FROM `votes` WHERE `candidate_id` = '$candidate_id'";
$queryresults = mysqli_query($connect, $results);
if($queryresults) {
$rowresults = mysqli_fetch_assoc($queryresults);
echo $rowresults['VoteNum'];
} else {
echo "error";
}
First, if you want to refer to the column name by a reference, then you need to give it a better name using an alias:
SELECT COUNT(votesnumber) as votesnumber
ROM `votes`
WHERE `candidate_id` = '$candidate_id';
Second, you should not be munging query strings with parameter values. Instead of '$candidate_id', learn to use parameters. This prevents unexpected syntax errors and SQL injection accounts.
Third, if votesnumber is actually a number of votes, then you probably want SUM() rather than COUNT().
You need to add "AS" instruction to your SQL if you want to get this data as a specific index from array (like $rowresults['votes']):
$results = "SELECT count(votesnumber) AS votes FROM `votes` WHERE `candidate_id` = '$candidate_id'";
Remember that you can always print_r() (for arrays) or var_dump() your variable to check if it contains data you want to have.

Active Record in CodeIgniter 2

I have this code:
$places = $this->db
->select('*')
->from('places')
->where('postal_code',$search)
->limit($limit, $start)
->get()->result();
I want to know if is there something wrong, and which is the way to get a query with a simple where inside the query.
Like this..
$places = $this->db->get_where('places',array('postal_code'=>$search),$limit,$start)->result();//outputs result in object format
$places = $this->db->get_where('places',array('postal_code'=>$search),$limit,$start)->result_array();//outputs result in array format
See more docs https://www.codeigniter.com/userguide3/database/query_builder.html
At the end I do it in other way, as I can see is there some issues to do a where and limit sentence in CodeIgniter in the same query.
So I do it directly in SQL
$query = "SELECT * FROM places WHERE locality = '".$search."' LIMIT ".$start.",".$limit."";
$places = $this->db->query($query)->result();
Not nice, but it works.

DQL innerJoin query equivalent

I have the code below working correctly on phpMyAdmin:
select testers.department from testers
inner join request_details
on testers.id = request_details.test_id
where request_details.request_id = '12345'
I tried converting it to DQL as below:
$query = Doctrine_Query::create()
->select('t.department')
->from('testers t, request_details r')
->innerJoin('t.id r')
->where('t.id = r.tester_id')
->andWhere('r.request_id = ?', 12345);
However , a var_dump() on the variable holding the query result returns NULL.
Which Doctrine version are you using, because in Doctrine2 you should be using the QueryBuilder class and you should use class names and properties, not table names and fields in DQL.
Thus, you should join to the class field name, not the table field name.
innerJoin('t.request_details', 'r') // where request_details is a propery on Tester
Also, you do not need the where that joins them (where(t.id = r.tester_id)), this is managed by Doctrine and will work provided that the entities are properly mapped.
You also do not need the request_details r in the from part, Doctrine will take care of this too.
Also, use class names in from, not table names.
EDIT (forgot the getQuery() before getResults()):
In the end you query would look something like this:
$queryBuilder = EntityManager::create(//em options)->createQueryBuilder();
$queryBuilder->select('t.department')
->from('Tester', 't')
->innerJoin('t.request_details', 'r') // request details is a propery on Tester, that maps to RequestDetails
->where('r.request_id = ?1')
->setParameter(1, 123);
Doctrine will take care of turning this into SQL and joining the thing.
In the end you'll also need to fetch the stuff:
$departments = $queryBuilder->getQuery()->getResult();
EDIT:
for Doctrine 1, something like this should work:
$q = Doctrine_Query::create()
->select('t.department')
->from('Tester t')
->innerJoin('t.request_details r') // request details is a propery on Tester, that maps to RequestDetails
->where('r.request_id = ?', 123);
$depts = $q->fetchArray();
I am not really familiar with Doctrine 1, so take a look at this for more info:
http://docs.doctrine-project.org/projects/doctrine1/en/latest/en/manual/dql-doctrine-query-language.html

Propel ORM - Custom where clause

I'm trying to match md5(ID) to an id.
SELECT *
FROM `user` u
WHERE
MD5(`user_id`) = '66f041e16a60928b05a7e228a89c3799'
this is ID = 58
I tried something like this. I know I'm close I just don't know what I'm missing
$criteria = new Criteria();
$criteria->addAnd('md5('.User::USER_ID.')', $_REQUEST['fs'], Criteria::CUSTOM);
$user = UserPeer::doSelectOne($criteria);
Any ideas?
First of all, directly using Criteria objects is deprecated not recommended. You should use Active Query classes.
Using these classes, you will be able to write stuff like this :
UserQuery::create()
->where('md5(User.Password) = ?', $_REQUEST['fs'], PDO::PARAM_STR)
->findOne();
You'll notice that I use the PhpName both of the table and the column in the query.
EDIT : For raw conditions, the parameter type has to be specified. You'll find more information on this issue.
After lenghty T&E process I managed to get it done like this
$c = new Criteria();
$c->add(UserPeer::USER_ID, "md5(user.user_id) = \"".$_REQUEST['fs']."\"", Criteria::CUSTOM); // risk of SQL injection!!
$saved_search = UserPeer::doSelectOne($c);
For some reason PropelORM though that $_REQUEST['fs'] was name of the table rather than the value. \"" solved the problem.