Update multiple rows with Propel 1.4 - symfony1

I need to execute following query (Using Propel 1.4/Symfony 1.4)
update notification
set read=1
where to=6 AND
action=0
For this, I wrote following code in symfony 1.4
$c=new Criteria()
$c->add(NotificationPeer::TO, $memberId, Criteria::EQUAL);
$c->add(NotificationPeer::ACTION, 0, Criteria::EQUAL);
$notification = NotificationPeer::doSelect($c);
foreach($notification as $notice)
{
$notice->setRead(1);
$notice->save();
}
Its working but if there are 100's of notification for any user, it will cost 100s of query and unnecessary load to server. I looked on doUpdate method of propel, I guess it can work for me but unable to figure out how.
IS there any way (I know there is but I don't know it) to do all that stuff in single query?

You should build two criteria:
one for the where clause
the other one for the update clause.
// Build WHERE criteria
$wherec = new Criteria();
$wherec->add(NotificationPeer::TO, $memberId, Criteria::EQUAL);
$wherec->add(NotificationPeer::ACTION, 0, Criteria::EQUAL);
// Build updated field criteria
$updc = new Criteria();
$updc->add(NotificationPeer::READ, 1);
BasePeer::doUpdate($wherec, $updc, $con);
It performs one (could be big) query. See this snippet.

Related

Spring data elasticsearch - Aggregations in new version

We have been using spring-data-elasticsearch for 4.1.13 until recently for querying from elastic search. For grouping something we used aggregations
Consider a index of books. For each book there can be one or multipe authors
To get count of books by author we used TermsAggregationbuilder to get this grouping as shown below
SearchSourceBuilder builder = this.getQuery(filter, false);
String aggregationName = "group_by_author_id";
TermsAggregationBuilder aggregationBuilders =
AggregationBuilders.terms(aggregationName).field("authors");
var query =
new NativeSearchQueryBuilder()
.withQuery(builder.query())
.addAggregation(aggregationBuilders)
.build();
var result = elasticsearchOperations.search(query, EsBook.class, ALIAS_COORDS);
if (!result.hasAggregations()) {
throw new IllegalStateException("No aggregations found after query with aggregations!");
}
Terms groupById = result.getAggregations().get(aggregationName);
var buckets = groupById.getBuckets();
Map<Long, Integer> booksCount = new HashMap<>();
buckets.forEach(
bucket ->
booksCount.put(
bucket.getKeyAsNumber().longValue(), Math.toIntExact(bucket.getDocCount())));
return booksCount ;
We recently upgraded to spring-data-elasticsearch 4.4.2 and saw that there are some breaking changes.
First .addAggregations were replaced by withAggregations
Second unlike before I cant seem to directly get Terms and buckets after querying as
result.getAggregations().get(aggregationName); is no more possible and only other option I see is result.getAggregations().aggregations(). So am wondering if anyone has done the same. The documentation itself is so poor in Elastic search.
First .addAggregations were replaced by withAggregations
addAggregation(AbstractAggregationBuilder<?>) has been deprecated and should be replaced by withAggregations. This is not a breaking change.
The change in the returned value for SearchHits.getAggregations() is documented in the migration guides from 4.2 to 4.3 "Removal of org.elasticsearch classes from the API."
So from 4.3 on result.getAggregations().aggregations() returns the same that previously result.getAggregations() returned.

How to use was clause with Jql

i am developing report plugin for jira where i need to get assignee for given duration.it could be diffrent than current assignee in given duration.
now i am building my query in report like below.
JqlQueryBuilder queryBuilder = JqlQueryBuilder.newBuilder();
query = queryBuilder.where().updatedBetween(stdate,endDate).and().assignee() in(status_val).buildQuery();
return searchProvider.searchCount(query, remoteUser);
i want to get the count for prior assigned issues for given duration.
please let me know how i can use Was clause with assignee and updatedbetween dates.
regards,
tousif shaikh.
Try reading this answer. In short, you'll need to define a new clause and use it in your query, like this:
JqlQueryBuilder builder = JqlQueryBuilder.newBuilder();
WasClauseImpl wasClause = new WasClauseImpl("status", Operator.WAS, new SingleValueOperand("Resolved"), new TerminalHistoryPredicate(Operator.AFTER, new SingleValueOperand(3500000L)));
JqlClauseBuilder clauseBuilder = JqlQueryBuilder.newClauseBuilder(wasClause);
Query query = clauseBuilder.buildQuery();

web server memory leak issue

i'm create a dating website using symfony 1.4 (it's my first project using symfony). the problem is there server freezes if there is only 10 or less users online. i tryied optimizing my js, css, sprites using yslow i got grade A but still the problem is always there. that's why i think the way i build the application might be wrong so here is the website naijaconnexion.com i'm asking u for advices and things to do so i overcome this problem
If i wasn't clear enough just ask, if you want cpanel admin access i'll post it
i realy realy needs your help
for instance i have this code on my home page action does it seems ok or it needs to be optimized and how
$this->me = $this->getUser()->getGuardUser()->getPerson();
$this->cities = Doctrine_Core::getTable('City')->findByDql("zipcode=''");
$this->countries = Doctrine_Core::getTable('City')->findByDql("zipcode='10'");
$this->contacts = $this->me->getContacts();
$this->favorites = $this->me->getFavorites();
$this->matches = $this->me->getMatches();
$this->pager = new sfDoctrinePager('Conversation', sfConfig::get('app_home_conversations_per_page'));
$this->pager->setQuery($this->me->getConversationsQuery());
$this->pager->setPage($request->getParameter('page', 1));
$this->pager->init();
without HYDRATE_ARRAY
i can do this
if i use HYDRATE_ARRAY
will i be able to do stuff like $this->contacts[0]['username'];
help please
The problem is doctrine...
Try to fetch the needed values as array and set a limit!
How many objects are returned by the following queries:
$this->cities = Doctrine_Core::getTable('City')->findByDql("zipcode=''");
$this->countries = Doctrine_Core::getTable('City')->findByDql("zipcode='10'");
$this->contacts = $this->me->getContacts();
$this->favorites = $this->me->getFavorites();
$this->matches = $this->me->getMatches();
? Do not forget that they are object with references to other objects!
And yes, this will work $this->contacts[0]['username'];.
if you join the tables with the doctrine query, you can access related entities too - without executing additional queries.
$this->contacts = Doctrine_Core::getTable('Contact')
->createQuery('c')
->leftJoin('c.Users u')
->addWhere('...')
->execute(array(), Doctrine_Core::HYDRATE_ARRAY);
$this->contacts[0]['Users'][0]['username']

Fetch values of aggregated columns in Propel

I am trying to make following query in Propel:
$criteria = new Criteria();
$criteria->clearSelectColumns();
$criteria->addSelectColumn(TableName::COLUMN1)
->addSelectColumn(TableName::COLUMN2)
->addAsColumn('alias1', 'DATE('.TableName::INIT_TIME.')')
->addAsColumn('alias2', 'COUNT('.TableName::DOWNLOAD_START_TIME.')')
->addGroupByColumn('DATE('.TableName::INIT_TIME.')')
->addGroupByColumn(TableName::DOWNLOAD_START_TIME);
$logs = TableName::doSelect($criteria);
It seems that everything OK and according to MySQL log file query generated and saved to server right. However I cannot get values of aggregated columns.
doSelect returns array of TableName objects which have no methods to fetch aggregated columns. So, how can I do it?
PS: I am talking about symfony 1.4 with Propel if it matters.
You should avoid the use of Criteria, use the ModelCriteria API instead (documentation available at: http://www.propelorm.org/reference/model-criteria.html)
The following query:
<?php
$criteria = new Criteria();
$criteria->clearSelectColumns();
$criteria->addSelectColumn(TableName::COLUMN1)
->addSelectColumn(TableName::COLUMN2)
->addAsColumn('alias1', 'DATE('.TableName::INIT_TIME.')')
->addAsColumn('alias2', 'COUNT('.TableName::DOWNLOAD_START_TIME.')')
->addGroupByColumn('DATE('.TableName::INIT_TIME.')')
->addGroupByColumn(TableName::DOWNLOAD_START_TIME);
$logs = TableName::doSelect($criteria);
Can be rewritten as below:
$query = TableNameQuery::create()
->select(array('Column1', 'Column2'))
->withColumn('DATE(InitTime)', 'alias1')
->withColumn('COUNT(DownloadStartTime)', 'alias2')
->groupBy('alias1')
->groupByDownloadStartTime()
;
$logs = $query->find();
Note you won't select both columns alias1 and alias2 as you didn't add them to the selected columns in your code. You can do that by adding the two alias to the select() clause:
->select(array('Column1', 'Column2', 'alias1', 'alias2'))
I used this snippet to retrieve and fetch data when I followed this same approach, but selecting only one column in my criteria through addSelectColumn:
$logs = TableName::doSelectStmt($criteria);
$data = $logs->fetchAll(PDO::FETCH_COLUMN, 0);
I hope this can help you.
My method is to make a query and iterate through a recordset. As suggested I use FETCH_BOTH to get array positions, but names as well. I take those values and hydrate my object, but also manually populate the properties of the object that are meant to hold the aggregate values. I pass those objects back to my application and use them as normal objects would be used in my view.
$stmt = self::doSelectStmt($c);
// empty array for now
$results = array();
// lets iterate through this
while($row = $stmt->fetch(PDO::FETCH_BOTH)) {
// we need to create a new object
$division = new Division();
// and we'll hydrate each row turning into an object so we can use it easily
$division->hydrate($row);
// now here's the magic, this object did not exist from our tables, we'll fix that
$division->setNumPlayers($row['num_players']);
$division->setNumTeams($row['teams']);
// set the output object
$results[] = $division;
}
return $results; // array of objects including aggregate values

symfony pagination with join

How do you paginate a query that has a join in symfony? I am trying this code but it times out:
$query=Doctrine_Query::create()
->select('c.name, d.phone')
->from('company c, companyDetails d')
->where('c.companyId=d.companyId');
$pager = new sfDoctrinePager('company',10);
$pager->setQuery($query);
$pager->setPage(1);
$pager->init();
$this->companys=$pager->getResults();
Your paginator code seems fine. I thk the problem is with your query.
Try running it without the pager and see the result.
If you continue facing issues with the query,Give this a try.
$query=Doctrine_Query::create()
->select('c.name, d.phone')
->from('company c')
->innerJoin('c.companyDetails d');
I havent tried it myself but it should work if your schema relations are defined the way i think.
One more thing, probably u already know that.
$pager->setPage(1);
should be something like
$pager->setPage($request->getParameter('page', 1));
I needed to change the count query in the pagination. To do this:
$pager = new Doctrine_Pager($query,$request->getParameter('page',1),10);
$pager->setCountQuery('SELECT COUNT(id) FROM items WHERE city_id='.$city.' AND category_id='.$category);
$this->pager=$pager;
The only thing you have to do is in your pagination helper, use:
$pagerRange = $pager->getRange('Sliding',array('chunk' => 5));
$pages = $pagerRange->rangeAroundPage();

Resources