From: <gem...@li...> - 2013-04-10 09:59:11
|
Revision: 1218 http://sourceforge.net/p/gemstracker/code/1218 Author: mennodekker Date: 2013-04-10 09:59:07 +0000 (Wed, 10 Apr 2013) Log Message: ----------- Preparation for batch export of results, allow for limit and offset Retrieval of rowcount for export is now more efficient Modified Paths: -------------- trunk/library/classes/Gems/Default/ExportAction.php trunk/library/classes/Gems/Tracker/Source/LimeSurvey1m9Database.php trunk/library/classes/Gems/Tracker/Source/SourceAbstract.php trunk/library/classes/Gems/Tracker/Source/SourceInterface.php trunk/library/classes/Gems/Tracker/Survey.php Modified: trunk/library/classes/Gems/Default/ExportAction.php =================================================================== --- trunk/library/classes/Gems/Default/ExportAction.php 2013-04-10 08:51:22 UTC (rev 1217) +++ trunk/library/classes/Gems/Default/ExportAction.php 2013-04-10 09:59:07 UTC (rev 1218) @@ -114,7 +114,7 @@ //$filter['organizationid'] = '-1'; } $filter['consentcode'] = array_diff((array) $this->util->getConsentTypes(), (array) $this->util->getConsentRejected()); - + // Gems_Tracker::$verbose = true; return $filter; } @@ -161,10 +161,12 @@ if (isset($data['sid'])) { $survey = $this->loader->getTracker()->getSurvey(intval($data['sid'])); $filter = $this->_getFilter($data); - $answers = $survey->getRawTokenAnswerRows($filter); + //$answers = $survey->getRawTokenAnswerRows($filter); + //$recordCount = count($answers); + $recordCount = $survey->getRawTokenAnswerRowsCount($filter); $element = new MUtil_Form_Element_Exhibitor('records'); - $element->setValue(sprintf($this->_('%s records found.'), count($answers))); + $element->setValue(sprintf($this->_('%s records found.'), $recordCount)); $elements[] = $element; } Modified: trunk/library/classes/Gems/Tracker/Source/LimeSurvey1m9Database.php =================================================================== --- trunk/library/classes/Gems/Tracker/Source/LimeSurvey1m9Database.php 2013-04-10 08:51:22 UTC (rev 1217) +++ trunk/library/classes/Gems/Tracker/Source/LimeSurvey1m9Database.php 2013-04-10 09:59:07 UTC (rev 1218) @@ -828,7 +828,80 @@ if (null === $sourceSurveyId) { $sourceSurveyId = $this->_getSid($surveyId); } + $select = $this->getRawTokenAnswerRowsSelect($filter, $surveyId, $sourceSurveyId); + + //Now process the filters + $lsSurveyTable = $this->_getSurveyTableName($sourceSurveyId); + $tokenField = $lsSurveyTable . '.token'; + if (is_array($filter)) { + //first preprocess the tokens + if (isset($filter['token'])) { + foreach ((array) $filter['token'] as $key => $tokenId) { + $token = $this->_getToken($tokenId); + $originals[$token] = $tokenId; + $filter[$tokenField][$key] = $token; + } + unset($filter['token']); + } + } + + $rows = $select->query()->fetchAll(Zend_Db::FETCH_ASSOC); + $results = array(); + //@@TODO: check if we really need this, or can just change the 'token' field to have the 'original' + // this way other sources that don't perform changes on the token field don't have to loop + // over this field. The survey(answer)model could possibly perform the translation for this source + if ($rows) { + $map = $this->_getFieldMap($sourceSurveyId); + if (isset($filter[$tokenField])) { + foreach ($rows as $values) { + $token = $originals[$values['token']]; + $results[$token] = $map->mapKeysToTitles($values); + } + return $results; + } else { + //@@TODO If we do the mapping in the select statement, maybe we can gain some performance here + foreach ($rows as $values) { + $results[] = $map->mapKeysToTitles($values); + } + return $results; + } + } + + return array(); + } + + /** + * Returns the recordcount for a given filter + * + * @param array $filter filter array + * @param int $surveyId Gems Survey Id + * @param string $sourceSurveyId Optional Survey Id used by source + * @return int + */ + public function getRawTokenAnswerRowsCount(array $filter, $surveyId, $sourceSurveyId = null) { + $select = $this->getRawTokenAnswerRowsSelect($filter, $surveyId, $sourceSurveyId); + + $p = new Zend_Paginator_Adapter_DbSelect($select); + MUtil_Echo::track($p->getCountSelect()->__toString()); + $count = $p->getCountSelect()->query()->fetchColumn(); + + return $count; + } + + /** + * Get the select object to use for RawTokenAnswerRows + * + * @param array $filter + * @param type $surveyId + * @param type $sourceSurveyId + * @return Zend_Db_Select + */ + public function getRawTokenAnswerRowsSelect(array $filter, $surveyId, $sourceSurveyId = null) { + if (null === $sourceSurveyId) { + $sourceSurveyId = $this->_getSid($surveyId); + } + $lsDb = $this->getSourceDatabase(); $lsSurveyTable = $this->_getSurveyTableName($sourceSurveyId); $lsTokenTable = $this->_getTokenTableName($sourceSurveyId); @@ -863,6 +936,9 @@ } } + // Add limit / offset to select and remove from filter + $this->filterLimitOffset($filter, $select); + foreach ($filter as $field => $values) { $field = $lsDb->quoteIdentifier($field); if (is_array($values)) { @@ -876,29 +952,7 @@ MUtil_Echo::r($select->__toString(), 'Select'); } - $rows = $select->query()->fetchAll(Zend_Db::FETCH_ASSOC); - $results = array(); - //@@TODO: check if we really need this, or can just change the 'token' field to have the 'original' - // this way other sources that don't perform changes on the token field don't have to loop - // over this field. The survey(answer)model could possibly perform the translation for this source - if ($rows) { - $map = $this->_getFieldMap($sourceSurveyId); - if (isset($filter[$tokenField])) { - foreach ($rows as $values) { - $token = $originals[$values['token']]; - $results[$token] = $map->mapKeysToTitles($values); - } - return $results; - } else { - //@@TODO If we do the mapping in the select statement, maybe we can gain some performance here - foreach ($rows as $values) { - $results[] = $map->mapKeysToTitles($values); - } - return $results; - } - } - - return array(); + return $select; } /** Modified: trunk/library/classes/Gems/Tracker/Source/SourceAbstract.php =================================================================== --- trunk/library/classes/Gems/Tracker/Source/SourceAbstract.php 2013-04-10 08:51:22 UTC (rev 1217) +++ trunk/library/classes/Gems/Tracker/Source/SourceAbstract.php 2013-04-10 09:59:07 UTC (rev 1218) @@ -228,6 +228,28 @@ $this->_sourceData['gso_ls_table_prefix'] . $tableName; } + + /** + * Extract limit and offset from the filter and add it to a select + * + * @param array $filter + * @param Zend_Db_Select $select + */ + protected function filterLimitOffset(&$filter, $select) + { + $limit = null; + $offset = null; + + if (array_key_exists('limit', $filter)) { + $limit = (int) $filter['limit']; + unset($filter['limit']); + } + if (array_key_exists('offset', $filter)) { + $offset = (int) $filter['offset']; + unset($filter['offset']); + } + $select->limit($limit, $offset); + } /** * @@ -246,6 +268,23 @@ { return $this->_sourceData['gso_id_source']; } + + /** + * Returns the recordcount for a given filter + * + * Abstract implementation is not efficient, sources should handle this as efficient + * as possible. + * + * @param array $filter filter array + * @param int $surveyId Gems Survey Id + * @param string $sourceSurveyId Optional Survey Id used by source + * @return int + */ + public function getRawTokenAnswerRowsCount(array $filter, $surveyId, $sourceSurveyId = null) + { + $answers = $this->getRawTokenAnswerRows($filter, $surveyId, $sourceSurveyId); + return count($answers); + } /** * Get the db adapter for this source Modified: trunk/library/classes/Gems/Tracker/Source/SourceInterface.php =================================================================== --- trunk/library/classes/Gems/Tracker/Source/SourceInterface.php 2013-04-10 08:51:22 UTC (rev 1217) +++ trunk/library/classes/Gems/Tracker/Source/SourceInterface.php 2013-04-10 09:59:07 UTC (rev 1218) @@ -184,6 +184,16 @@ * @return array Of nested Field => Value arrays indexed by tokenId */ public function getRawTokenAnswerRows(array $filter, $surveyId, $sourceSurveyId = null); + + /** + * Returns the recordcount for a given filter + * + * @param array $filter filter array + * @param int $surveyId Gems Survey Id + * @param string $sourceSurveyId Optional Survey Id used by source + * @return int + */ + public function getRawTokenAnswerRowsCount(array $filter, $surveyId, $sourceSurveyId = null); /** * Gets the time the survey was started according to the source. Modified: trunk/library/classes/Gems/Tracker/Survey.php =================================================================== --- trunk/library/classes/Gems/Tracker/Survey.php 2013-04-10 08:51:22 UTC (rev 1217) +++ trunk/library/classes/Gems/Tracker/Survey.php 2013-04-10 09:59:07 UTC (rev 1218) @@ -395,6 +395,18 @@ $source = $this->getSource(); return $source->getRawTokenAnswerRows((array) $filter, $this->_surveyId, $this->_gemsSurvey['gsu_surveyor_id']); } + + /** + * Returns the number of answers of multiple tokens + * + * @param array $filter XXX + * @return array Of nested Field => Value arrays indexed by tokenId + */ + public function getRawTokenAnswerRowsCount($filter = array()) + { + $source = $this->getSource(); + return $source->getRawTokenAnswerRowsCount((array) $filter, $this->_surveyId, $this->_gemsSurvey['gsu_surveyor_id']); + } /** * Retrieve the name of the resultfield This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |