|
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.
|