コード例 #1
0
ファイル: SearchDao.class.php プロジェクト: rinodung/tuleap
 /**
  * Monstro query 
  * 
  * @param PFUser $user
  * @param unknown_type $group_id
  * @param Tracker_CrossSearch_Query $query
  * @param array $tracker_ids
  * @param array $shared_fields
  * @param array $semantic_fields
  * @param array $artifact_link_field_ids_for_column_display
  * @param array $excluded_artifact_ids
  */
 public function searchMatchingArtifacts(PFUser $user, $group_id, Tracker_CrossSearch_Query $query, array $tracker_ids, array $shared_fields, array $semantic_fields, array $artifact_link_field_ids_for_column_display, array $excluded_artifact_ids = array())
 {
     $report_dao = new Tracker_ReportDao();
     $is_super_user = $user->isSuperUser();
     $ugroups = $user->getUgroups($group_id, array());
     $quoted_ugroups = $this->da->quoteSmartImplode(',', $ugroups);
     $quoted_tracker_ids = $this->da->quoteSmartImplode(',', $tracker_ids);
     $excluded_artifact_ids = $this->da->quoteSmartImplode(',', $excluded_artifact_ids);
     $shared_fields_constraints = $this->getSharedFieldsSqlFragment($shared_fields);
     $title_constraint = $this->getTitleSqlFragment($this->getSemanticFieldCriteria($semantic_fields, 'title'));
     $status_constraint = $this->getStatusSqlFragment($this->getSemanticFieldCriteria($semantic_fields, 'status'));
     $tracker_constraint = $tracker_ids ? " AND   artifact.tracker_id IN ({$quoted_tracker_ids}) " : "";
     $artifact_ids_list = $query->listArtifactIds();
     $artifact_link_constraints = '';
     if (count($artifact_ids_list)) {
         $artifact_ids_list = $this->da->quoteSmartImplode(',', $artifact_ids_list);
         $artifacts_fields = $this->getArtifactLinkFields($artifact_ids_list, $is_super_user, $quoted_ugroups);
         $artifact_link_constraints = $this->getArtifactLinkSearchSqlFragment($artifacts_fields);
     }
     $artifact_link_columns_select = $this->getArtifactLinkSelects($artifact_link_field_ids_for_column_display);
     $artifact_link_columns_join = $this->getArtifactLinkColumns($artifact_link_field_ids_for_column_display, $is_super_user, $quoted_ugroups);
     $artifact_permissions = $report_dao->getSqlFragmentForArtifactPermissions($user->isSuperUser(), $user->getUgroups($group_id, array()));
     $artifact_permissions_join = $artifact_permissions['from'];
     $artifact_permissions_where = $artifact_permissions['where'];
     $tracker_semantic_title_join = $this->getTrackerSemanticTitleJoin($is_super_user, $quoted_ugroups);
     $tracker_semantic_status_join = $this->getTrackerSemanticStatusJoin($is_super_user, $quoted_ugroups);
     $from = " FROM tracker_artifact AS artifact\n                   INNER JOIN tracker_changeset AS c ON (artifact.last_changeset_id = c.id) \n                   {$shared_fields_constraints} \n                   {$artifact_link_constraints} \n                   {$tracker_semantic_title_join} \n                   {$tracker_semantic_status_join} \n                   {$artifact_permissions_join} ";
     $where = " WHERE 1 {$artifact_permissions_where} {$title_constraint} {$status_constraint} ";
     $permissions_manager = PermissionsManager::instance();
     $tracker_factory = TrackerFactory::instance();
     $sqls = array();
     foreach ($tracker_ids as $tracker_id) {
         // {{{ This is a big copy 'n paste from Tracker_Report::getMatchingIdsInDb.
         //     TODO:
         //          instead of building a big query with plenty of unions,
         //          call getMatchingIdsInDb foreach tracker involved in the
         //          crosssearch query. As getMatchingIdsInDb returns the
         //          tuple (artifact_ids, matching_ids) -- where ids are
         //          comma separated --, we will have to do the join in php
         //          by concatenating strings.
         //          Example:
         //              $artifact_ids = $changeset_ids = '';
         //              foreach ($trackers as $tracker) {
         //                  merge($artifact_ids, $changeset_ids, report->getMatchingIdsInDb(..., $tracker, ...));
         //              }
         //              crosssearch->retrieveColumns($artifact_ids, $changeset_ids)
         //
         //          And if we are feeling lucky, we can also move the
         //              reportdao->searchMatchingIds in searchdao since it make more sense.
         //
         //          Possible caveat:
         //              - 1 big sql query full of unions is really slower
         //                than n small queries?
         $instances = array('artifact_type' => $tracker_id);
         $ugroups = $user->getUgroups($group_id, $instances);
         $static_ugroups = $user->getStaticUgroups($group_id);
         $dynamic_ugroups = $user->getDynamicUgroups($group_id, $instances);
         $permissions = $permissions_manager->getPermissionsAndUgroupsByObjectid($tracker_id, $ugroups);
         $subwhere = " {$where} AND artifact.tracker_id = {$tracker_id} ";
         $tracker = $tracker_factory->getTrackerById($tracker_id);
         $contributor_field = $tracker->getContributorField();
         $contributor_field_id = $contributor_field ? $contributor_field->getId() : null;
         // }}}
         $sqls = array_merge($sqls, $report_dao->getSqlFragmentsAccordinglyToTrackerPermissions($user->isSuperUser(), $from, $subwhere, $group_id, $tracker_id, $permissions, $ugroups, $static_ugroups, $dynamic_ugroups, $contributor_field_id));
     }
     array_filter($sqls);
     if (count($sqls) == 0) {
         $results = new DataAccessResultEmpty();
     } else {
         $union = implode(' UNION ', $sqls);
         $sql = "SET SESSION group_concat_max_len = 134217728";
         $this->retrieve($sql);
         $sql = "\n            SELECT artifact.id,\n                   artifact.last_changeset_id,\n                   CVT.value                                AS title,\n                   artifact.tracker_id,\n                   GROUP_CONCAT(CVAL.artifact_id) AS artifactlinks\n                   {$artifact_link_columns_select}\n                   \n            FROM       tracker_artifact  AS artifact\n            INNER JOIN tracker_artifact_priority ON (tracker_artifact_priority.curr_id = artifact.id)\n            INNER JOIN ( {$union} ) AS R ON (R.id = artifact.id)\n            INNER JOIN tracker_changeset AS c ON (R.last_changeset_id = c.id)\n\n            -- shared_fields_constraints\n            \n            -- artifact_link_constraints\n\n            {$tracker_semantic_title_join}\n\n            LEFT JOIN (\n                           tracker_changeset_value_artifactlink AS CVAL\n                INNER JOIN tracker_changeset_value              AS CV2 ON (CV2.id = CVAL.changeset_value_id) \n            \n            ) ON CV2.changeset_id = artifact.last_changeset_id\n\n            {$artifact_link_columns_join}\n            -- artifact_permissions_join\n        \n            WHERE 1\n            -- artifact_permissions_where\n                    {$tracker_constraint}\n            -- title_constraint\n            -- status_constraint\n            ";
         if ($excluded_artifact_ids != '') {
             $sql .= "\n                  AND artifact.id NOT IN ({$excluded_artifact_ids}) ";
         }
         $sql .= "\n                GROUP BY artifact.id\n                ORDER BY tracker_artifact_priority.rank\n            ";
         $results = $this->retrieve($sql);
     }
     return $results;
 }
コード例 #2
0
 /**
  * Not really report table specific but we have to find a place.
  * Search for matching artifacts of a report.
  *
  * @param int   $group_id         The id of the project
  * @param int   $tracker_id       The id of the tracker
  * @param array $additional_from  If you have to join on some table put them here
  * @param array $additional_where If you have to select the results, help yourself!
  * @param bool  $user_is_admin True if the user is superuser
  * @param array $permissions
  * @param string $ugroups          Ugroups of the current user to check the permissions
  * @param array $static_ugroups
  * @param array $dynamic_ugroups 
  * @param int $contributor_field_id The field id corresponding to the contributor semantic
  * @return DataAccessResult
  */
 public function searchMatchingIds($group_id, $tracker_id, $additional_from, $additional_where, PFUser $user, $permissions, $contributor_field_id)
 {
     $instances = array('artifact_type' => $tracker_id);
     $ugroups = $user->getUgroups($group_id, $instances);
     $static_ugroups = $user->getStaticUgroups($group_id);
     $dynamic_ugroups = $user->getDynamicUgroups($group_id, $instances);
     $user_is_admin = $this->userIsAdmin($user, $group_id, $permissions, $ugroups);
     $tracker_id = $this->da->escapeInt($tracker_id);
     $from = " FROM tracker_artifact AS artifact\n                 INNER JOIN tracker_changeset AS c ON (artifact.last_changeset_id = c.id)";
     $where = " WHERE artifact.tracker_id = {$tracker_id} ";
     $artifact_perms = $this->getSqlFragmentForArtifactPermissions($user_is_admin, $ugroups);
     $from .= $artifact_perms['from'];
     $where .= $artifact_perms['where'];
     if ($this->submitterOnlyApplies($user_is_admin, $permissions, $ugroups)) {
         $where .= ' AND artifact.submitted_by = ' . $user->getId() . ' ';
     }
     if (count($additional_from)) {
         $from .= implode("\n", $additional_from);
     }
     if (count($additional_where)) {
         $where .= ' AND ( ' . implode(' ) AND ( ', $additional_where) . ' ) ';
     }
     // $sqls => SELECT UNION SELECT UNION SELECT ...
     $sqls = $this->getSqlFragmentsAccordinglyToTrackerPermissions($user_is_admin, $from, $where, $group_id, $tracker_id, $permissions, $ugroups, $static_ugroups, $dynamic_ugroups, $contributor_field_id);
     if (count($sqls) == 0) {
         return new DataAccessResultEmpty();
     } else {
         $this->setGroupConcatLimit();
         $sql = " SELECT GROUP_CONCAT(DISTINCT id) AS id, GROUP_CONCAT(DISTINCT last_changeset_id) AS last_changeset_id ";
         $sql .= " FROM (" . implode(' UNION ', $sqls) . ") AS R ";
         //var_dump($sql);
         return $this->retrieve($sql);
     }
 }