/** * Searching Many To Many on a custom field (dropdown) */ public function testManyManyCustomFieldSearch() { $quote = DatabaseCompatibilityUtil::getQuote(); $searchAttributeData = array(); $searchAttributeData['clauses'] = array(1 => array('attributeName' => 'opportunities', 'relatedModelData' => array('attributeName' => 'stage', 'relatedAttributeName' => 'value', 'operatorType' => 'oneOf', 'value' => array(0 => 'something')))); $searchAttributeData['structure'] = '1'; //Build the query 'where' and 'joins'. Confirm they are as expected $joinTablesAdapter = new RedBeanModelJoinTablesQueryAdapter('Contact'); $where = ModelDataProviderUtil::makeWhere('Contact', $searchAttributeData, $joinTablesAdapter); $compareWhere = "({$quote}customfield{$quote}.{$quote}value{$quote} IN('something'))"; $this->assertEquals($compareWhere, $where); $this->assertEquals(0, $joinTablesAdapter->getFromTableJoinCount()); $this->assertEquals(3, $joinTablesAdapter->getLeftTableJoinCount()); $leftTables = $joinTablesAdapter->getLeftTablesAndAliases(); $this->assertEquals('contact_opportunity', $leftTables[0]['tableName']); $this->assertEquals('opportunity', $leftTables[1]['tableName']); $this->assertEquals('customfield', $leftTables[2]['tableName']); $this->assertTrue($joinTablesAdapter->getSelectDistinct()); //Now test that the subsetSQL query produced is correct. $subsetSql = Contact::makeSubsetOrCountSqlQuery('contact', $joinTablesAdapter, 1, 5, $where, null, false, $joinTablesAdapter->getSelectDistinct()); $compareSubsetSql = "select distinct {$quote}contact{$quote}.{$quote}id{$quote} id "; $compareSubsetSql .= "from {$quote}contact{$quote} "; $compareSubsetSql .= "left join {$quote}contact_opportunity{$quote} on "; $compareSubsetSql .= "{$quote}contact_opportunity{$quote}.{$quote}contact_id{$quote} = {$quote}contact{$quote}.{$quote}id{$quote} "; $compareSubsetSql .= "left join {$quote}opportunity{$quote} on "; $compareSubsetSql .= "{$quote}opportunity{$quote}.{$quote}id{$quote} = {$quote}contact_opportunity{$quote}.{$quote}opportunity_id{$quote} "; $compareSubsetSql .= "left join {$quote}customfield{$quote} on "; $compareSubsetSql .= "{$quote}customfield{$quote}.{$quote}id{$quote} = {$quote}opportunity{$quote}.{$quote}stage_customfield_id{$quote} "; $compareSubsetSql .= "where " . $compareWhere . ' '; $compareSubsetSql .= 'limit 5 offset 1'; $this->assertEquals($compareSubsetSql, $subsetSql); //Make sure the sql runs properly. $data = Contact::getSubset($joinTablesAdapter, 0, 5, $where, null, null, $joinTablesAdapter->getSelectDistinct()); }
public function resolveJoinsAndBuildWhere($operatorType, $value, &$clausePosition, &$where, $onTableAliasName = null, $resolveAsSubquery = false) { assert('$operatorType == null'); assert('$value == null'); assert('is_array($where)'); assert('is_string($onTableAliasName) || $onTableAliasName == null'); $tableAliasName = $this->resolveJoins($onTableAliasName, ModelDataProviderUtil::resolveCanUseFromJoins($onTableAliasName)); $this->addReadOptimizationWhereClause($where, $clausePosition, $tableAliasName); }
/** * Gets the date of all meetings as defined by the searchAttributeData */ public function makeSqlQuery() { assert('get_class($this->model) == "Meeting"'); $modelClassName = 'Meeting'; $quote = DatabaseCompatibilityUtil::getQuote(); $joinTablesAdapter = new RedBeanModelJoinTablesQueryAdapter($modelClassName); $where = ModelDataProviderUtil::makeWhere($modelClassName, $this->searchAttributeData, $joinTablesAdapter); $selectDistinct = false; $modelClassName::resolveReadPermissionsOptimizationToSqlQuery(Yii::app()->user->userModel, $joinTablesAdapter, $where, $selectDistinct); $selectQueryAdapter = new RedBeanModelSelectQueryAdapter($selectDistinct); $selectQueryAdapter->addClause('meeting', 'startdatetime'); $sql = SQLQueryUtil::makeQuery('meeting', $selectQueryAdapter, $joinTablesAdapter, null, null, $where); return $sql; }
public function testResolveSortAttributeColumnName() { $quote = DatabaseCompatibilityUtil::getQuote(); //Test a standard non-relation attribute on I $joinTablesAdapter = new RedBeanModelJoinTablesQueryAdapter('I'); $modelAttributeToDataProviderAdapter = new RedBeanModelAttributeToDataProviderAdapter('I', 'iMember'); $sort = ModelDataProviderUtil::resolveSortAttributeColumnName($modelAttributeToDataProviderAdapter, $joinTablesAdapter); $this->assertEquals("{$quote}i{$quote}.{$quote}imember{$quote}", $sort); $this->assertEquals(0, $joinTablesAdapter->getFromTableJoinCount()); $this->assertEquals(0, $joinTablesAdapter->getLeftTableJoinCount()); //Test a standard casted up attribute on H from I $joinTablesAdapter = new RedBeanModelJoinTablesQueryAdapter('I'); $modelAttributeToDataProviderAdapter = new RedBeanModelAttributeToDataProviderAdapter('I', 'name'); $sort = ModelDataProviderUtil::resolveSortAttributeColumnName($modelAttributeToDataProviderAdapter, $joinTablesAdapter); $this->assertEquals("{$quote}h{$quote}.{$quote}name{$quote}", $sort); $this->assertEquals(1, $joinTablesAdapter->getFromTableJoinCount()); $this->assertEquals(0, $joinTablesAdapter->getLeftTableJoinCount()); //Test a relation attribute G->g from H $joinTablesAdapter = new RedBeanModelJoinTablesQueryAdapter('H'); $modelAttributeToDataProviderAdapter = new RedBeanModelAttributeToDataProviderAdapter('H', 'castUpHasOne', 'g'); $sort = ModelDataProviderUtil::resolveSortAttributeColumnName($modelAttributeToDataProviderAdapter, $joinTablesAdapter); $this->assertEquals("{$quote}g{$quote}.{$quote}g{$quote}", $sort); $this->assertEquals(0, $joinTablesAdapter->getFromTableJoinCount()); $this->assertEquals(1, $joinTablesAdapter->getLeftTableJoinCount()); $leftTables = $joinTablesAdapter->getLeftTablesAndAliases(); $this->assertEquals('g', $leftTables[0]['tableName']); //Test a relation attribute G->g where casted up from I $joinTablesAdapter = new RedBeanModelJoinTablesQueryAdapter('I'); $modelAttributeToDataProviderAdapter = new RedBeanModelAttributeToDataProviderAdapter('I', 'castUpHasOne', 'g'); $sort = ModelDataProviderUtil::resolveSortAttributeColumnName($modelAttributeToDataProviderAdapter, $joinTablesAdapter); $this->assertEquals("{$quote}g{$quote}.{$quote}g{$quote}", $sort); $this->assertEquals(1, $joinTablesAdapter->getFromTableJoinCount()); $this->assertEquals(1, $joinTablesAdapter->getLeftTableJoinCount()); $fromTables = $joinTablesAdapter->getFromTablesAndAliases(); $this->assertEquals('h', $fromTables[0]['tableName']); $leftTables = $joinTablesAdapter->getLeftTablesAndAliases(); $this->assertEquals('g', $leftTables[0]['tableName']); //Test a customField like TestCustomFieldsModel->industry $joinTablesAdapter = new RedBeanModelJoinTablesQueryAdapter('TestCustomFieldsModel'); $modelAttributeToDataProviderAdapter = new RedBeanModelAttributeToDataProviderAdapter('TestCustomFieldsModel', 'industry', 'value'); $sort = ModelDataProviderUtil::resolveSortAttributeColumnName($modelAttributeToDataProviderAdapter, $joinTablesAdapter); $this->assertEquals("{$quote}customfield{$quote}.{$quote}value{$quote}", $sort); $this->assertEquals(0, $joinTablesAdapter->getFromTableJoinCount()); $this->assertEquals(1, $joinTablesAdapter->getLeftTableJoinCount()); $leftTables = $joinTablesAdapter->getLeftTablesAndAliases(); $this->assertEquals('customfield', $leftTables[0]['tableName']); }
/** * @param $modelAttributeToDataProviderAdapter * @param null | string $onTableAliasName * @return string */ protected function resolveFinalContent($modelAttributeToDataProviderAdapter, $onTableAliasName = null) { if ($modelAttributeToDataProviderAdapter instanceof ReadOptimizationDerivedAttributeToDataProviderAdapter) { $builder = new ReadOptimizationModelWhereAndJoinBuilder($modelAttributeToDataProviderAdapter, $this->joinTablesAdapter); $clausePosition = 1; $where = array(); $builder->resolveJoinsAndBuildWhere(null, null, $clausePosition, $where, $onTableAliasName); return $where[1]; } else { $modelClassName = $modelAttributeToDataProviderAdapter->getResolvedModelClassName(); $metadataAdapter = new FilterForReportFormToDataProviderMetadataAdapter($this->componentForm); $attributeData = $metadataAdapter->getAdaptedMetadata(); //todo: right now in makeWhere we always set setDistinct to true when instantiating new ModelWhereAndJoinBuilder //todo: but when we are calling makeWhere from here we should not set that to true. or should it? TBD return ModelDataProviderUtil::makeWhere($modelClassName, $attributeData, $this->joinTablesAdapter, $onTableAliasName); } }
/** * Add where clause for searching for related models * @param $modelClassName * @param array $metadata * @param $joinTablesAdapter * @return string * @throws NotSupportedException */ public static function makeWhere($modelClassName, array $metadata, &$joinTablesAdapter) { $data = GetUtil::getData(); if (!isset($data['relationAttributeName']) || !$modelClassName::isRelation($data['relationAttributeName']) || intval($data['id']) <= 0) { throw new NotSupportedException(); } $relationAttributeName = $data['relationAttributeName']; $additionalMetaData = static::getAdditionalSearchMetadata($relationAttributeName, $data); $clausesCount = 0; if (isset($metadata['clauses'])) { $clausesCount = count($metadata['clauses']); $metadata['clauses'][count($metadata['clauses']) + 1] = $additionalMetaData; } else { $metadata['clauses'][1] = $additionalMetaData; } if ($clausesCount == 0) { $metadata['structure'] = '(1)'; } else { $count = $clausesCount + 1; $metadata['structure'] = $metadata['structure'] . ' and (' . $count . ')'; } return ModelDataProviderUtil::makeWhere($modelClassName, $metadata, $joinTablesAdapter); }
/** * @return string * @throws NotSupportedException */ protected function resolveComponentAttributeStringContentForNestedAttribute() { $attributeAndRelationData = $this->componentForm->getAttributeAndRelationData(); $count = 0; $moduleClassName = $this->componentForm->getModuleClassName(); $modelClassName = $this->componentForm->getModelClassName(); $onTableAliasName = null; $startingModelClassName = null; foreach ($attributeAndRelationData as $key => $relationOrAttribute) { $modelToReportAdapter = ModelRelationsAndAttributesToReportAdapter::make($moduleClassName, $modelClassName, $this->componentForm->getReportType()); $modelAttributeToDataProviderAdapter = $this->makeModelAttributeToDataProviderAdapter($modelToReportAdapter, $relationOrAttribute); if ($this->shouldPrematurelyStopBuildingJoinsForAttribute($modelToReportAdapter, $modelAttributeToDataProviderAdapter)) { $attribute = 'id'; $modelAttributeToDataProviderAdapter = $this->makeModelAttributeToDataProviderAdapter($modelToReportAdapter, $attribute); break; } elseif ($modelToReportAdapter->isReportedOnAsARelation($relationOrAttribute)) { $modelClassName = $modelToReportAdapter->getRelationModelClassName($relationOrAttribute); $moduleClassName = $modelToReportAdapter->getRelationModuleClassName($relationOrAttribute); if ($modelToReportAdapter->isInferredRelation($relationOrAttribute) || $modelToReportAdapter->isDerivedRelationsViaCastedUpModelRelation($relationOrAttribute)) { static::resolveCastingHintForAttribute($modelToReportAdapter, $modelAttributeToDataProviderAdapter, $modelClassName, $modelToReportAdapter->resolveRealAttributeName($attributeAndRelationData[$key + 1])); } $modelAttributeToDataProviderAdapter->setCastingHintStartingModelClassName($startingModelClassName); $builder = new ModelJoinBuilder($modelAttributeToDataProviderAdapter, $this->joinTablesAdapter); $onTableAliasName = $builder->resolveJoins($onTableAliasName, ModelDataProviderUtil::resolveCanUseFromJoins($onTableAliasName)); $startingModelClassName = $modelAttributeToDataProviderAdapter->getCastingHintModelClassNameForAttribute(); } else { if ($count + 1 != count($attributeAndRelationData)) { throw new NotSupportedException('The final element in array must be an attribute, not a relation'); } } $count++; } $modelAttributeToDataProviderAdapter->setCastingHintStartingModelClassName($startingModelClassName); return $this->resolveFinalContent($modelAttributeToDataProviderAdapter, $onTableAliasName); }
/** * @param $modelAttributeToDataProviderAdapter * @param null |string $onTableAliasName * @return string */ protected function resolveFinalContent($modelAttributeToDataProviderAdapter, $onTableAliasName = null) { $columnContent = ModelDataProviderUtil::resolveGroupByAttributeColumnName($modelAttributeToDataProviderAdapter, $this->joinTablesAdapter, $onTableAliasName); return $this->resolveColumnContentForCalculatedModifier($columnContent); }
/** * Not for use by applications. Public for unit tests only. * Override from RedBeanModelDataProvider to support multiple * where clauses for the same attribute and operatorTypes * @param metadata - array expected to have clauses and structure elements * @param $joinTablesAdapter * @see DataProviderMetadataAdapter * @return string */ public static function makeWhere($modelClassName, array $metadata, &$joinTablesAdapter) { return ModelDataProviderUtil::makeWhere($modelClassName, $metadata, $joinTablesAdapter); }
/** * HHH -> hasOneBelongsTo -> AAA -> hasOne -> BBB -> hasOne GGG (gggMember and gggMember2) * @depends testHasOneBelongsToHasOneToHasOne */ public function testHasOneBelongsToHasOneToHasOneWithMultipleClauses() { $quote = DatabaseCompatibilityUtil::getQuote(); $searchAttributeData = array(); $searchAttributeData['clauses'] = array(1 => array('attributeName' => 'aaa', 'relatedModelData' => array('attributeName' => 'bbb', 'relatedModelData' => array('attributeName' => 'ggg', 'relatedModelData' => array('attributeName' => 'gggMember', 'operatorType' => 'equals', 'value' => 'somevalue')))), 2 => array('attributeName' => 'aaa', 'relatedModelData' => array('attributeName' => 'bbb', 'relatedModelData' => array('attributeName' => 'ggg', 'relatedModelData' => array('attributeName' => 'gggMember2', 'operatorType' => 'equals', 'value' => 'somevalue'))))); //Build the query 'where' and 'joins'. Confirm they are as expected $searchAttributeData['structure'] = '1 and 2'; //Build the query 'where' and 'joins'. Confirm they are as expected $joinTablesAdapter = new RedBeanModelJoinTablesQueryAdapter('HHH'); $where = ModelDataProviderUtil::makeWhere('HHH', $searchAttributeData, $joinTablesAdapter); $compareWhere = "({$quote}ggg{$quote}.{$quote}gggmember{$quote} = 'somevalue') and "; $compareWhere .= "({$quote}ggg{$quote}.{$quote}gggmember2{$quote} = 'somevalue')"; $this->assertEquals($compareWhere, $where); $this->assertEquals(0, $joinTablesAdapter->getFromTableJoinCount()); $this->assertEquals(3, $joinTablesAdapter->getLeftTableJoinCount()); $leftTables = $joinTablesAdapter->getLeftTablesAndAliases(); $this->assertEquals('aaa', $leftTables[0]['tableName']); $this->assertEquals('bbb', $leftTables[1]['tableName']); $this->assertEquals('ggg', $leftTables[2]['tableName']); //Stringing together some hasMany relations, so we need to select distinct. $this->assertFalse($joinTablesAdapter->getSelectDistinct()); //Now test that the subsetSQL query produced is correct. $subsetSql = CCC::makeSubsetOrCountSqlQuery('hhh', $joinTablesAdapter, 1, 5, $where, null, false, $joinTablesAdapter->getSelectDistinct()); $compareSubsetSql = "select {$quote}hhh{$quote}.{$quote}id{$quote} id "; $compareSubsetSql .= "from {$quote}hhh{$quote} "; $compareSubsetSql .= "left join {$quote}aaa{$quote} on "; $compareSubsetSql .= "{$quote}aaa{$quote}.{$quote}hhh_id{$quote} = {$quote}hhh{$quote}.{$quote}id{$quote} "; $compareSubsetSql .= "left join {$quote}bbb{$quote} on "; $compareSubsetSql .= "{$quote}bbb{$quote}.{$quote}id{$quote} = {$quote}aaa{$quote}.{$quote}bbb_id{$quote} "; $compareSubsetSql .= "left join {$quote}ggg{$quote} on "; $compareSubsetSql .= "{$quote}ggg{$quote}.{$quote}id{$quote} = {$quote}bbb{$quote}.{$quote}ggg_id{$quote} "; $compareSubsetSql .= "where " . $compareWhere . ' '; $compareSubsetSql .= 'limit 5 offset 1'; $this->assertEquals($compareSubsetSql, $subsetSql); //Make sure the sql runs properly. $data = HHH::getSubset($joinTablesAdapter, 0, 5, $where, null, null, $joinTablesAdapter->getSelectDistinct()); }
protected function resolveRelationAttributeTableAliasNameForResolveSubquery($onTableAliasName, $resolveAsSubquery = false) { assert('is_string($onTableAliasName) || $onTableAliasName == null'); assert('is_bool($resolveAsSubquery)'); if ($resolveAsSubquery) { return $this->resolveRelationAttributeTableAliasNameForResolveSubqueryAsTrue($onTableAliasName); } else { return $this->resolveOnlyAttributeJoins($onTableAliasName, ModelDataProviderUtil::resolveCanUseFromJoins($onTableAliasName)); } }
/** * @depends testResolveGroupByAttributeColumnName */ public function testResolveGroupByWhenThereAreTableAliases() { $quote = DatabaseCompatibilityUtil::getQuote(); //Test a customField like TestCustomFieldsModel->industry $joinTablesAdapter = new RedBeanModelJoinTablesQueryAdapter('TestCustomFieldsModel'); $modelAttributeToDataProviderAdapter = new RedBeanModelAttributeToDataProviderAdapter('TestCustomFieldsModel', 'industry', 'value'); $groupBy = ModelDataProviderUtil::resolveGroupByAttributeColumnName($modelAttributeToDataProviderAdapter, $joinTablesAdapter); $this->assertEquals("{$quote}customfield{$quote}.{$quote}value{$quote}", $groupBy); $this->assertEquals(0, $joinTablesAdapter->getFromTableJoinCount()); $this->assertEquals(1, $joinTablesAdapter->getLeftTableJoinCount()); $leftTables = $joinTablesAdapter->getLeftTablesAndAliases(); $this->assertEquals('customfield', $leftTables[0]['tableName']); //Now add a second sort on a different CustomField $modelAttributeToDataProviderAdapter = new RedBeanModelAttributeToDataProviderAdapter('TestCustomFieldsModel', 'market', 'value'); $groupBy = ModelDataProviderUtil::resolveGroupByAttributeColumnName($modelAttributeToDataProviderAdapter, $joinTablesAdapter); $this->assertEquals("{$quote}customfield1{$quote}.{$quote}value{$quote}", $groupBy); $this->assertEquals(0, $joinTablesAdapter->getFromTableJoinCount()); $this->assertEquals(2, $joinTablesAdapter->getLeftTableJoinCount()); $leftTables = $joinTablesAdapter->getLeftTablesAndAliases(); $this->assertEquals('customfield', $leftTables[1]['tableName']); $this->assertEquals('customfield1', $leftTables[1]['tableAliasName']); }
/** * @param ModelJoinBuilder $builder * @param $modelAttributeToDataProviderAdapter * @param null | string $onTableAliasName * @throws NotSupportedException if the display attribute is made via select like SUM(integer) but the * adapter being used is not a summation adapter */ protected function resolveDisplayAttributeForProcessingAllJoins(ModelJoinBuilder $builder, $modelAttributeToDataProviderAdapter, $onTableAliasName = null) { assert('$modelAttributeToDataProviderAdapter instanceof RedBeanModelAttributeToDataProviderAdapter'); assert('is_string($onTableAliasName) || $onTableAliasName == null'); $tableAliasName = $builder->resolveJoins($onTableAliasName, ModelDataProviderUtil::resolveCanUseFromJoins($onTableAliasName)); if ($this->isDisplayAttributeMadeViaSelect()) { if (!$this->modelToReportAdapter instanceof ModelRelationsAndAttributesToSummableReportAdapter) { throw new NotSupportedException(); } $this->modelToReportAdapter->resolveDisplayAttributeTypeAndAddSelectClause($this->selectQueryAdapter, $this->componentForm->getResolvedAttribute(), $tableAliasName, $this->resolveColumnName($modelAttributeToDataProviderAdapter), $this->componentForm->columnAliasName, $this->getAttributeClauseQueryStringExtraPart($tableAliasName)); } else { $tableAliasName = $this->resolvedTableAliasName($modelAttributeToDataProviderAdapter, $builder); $this->selectQueryAdapter->resolveIdClause($this->resolvedModelClassName($modelAttributeToDataProviderAdapter), $tableAliasName); $this->componentForm->setModelAliasUsingTableAliasName($tableAliasName); } }
public static function getCountByModelClassName($modelClassName, $relationItemIds, $ownedByFilter) { assert('is_string($modelClassName)'); assert('is_array($relationItemIds)'); assert('$ownedByFilter == LatestActivitiesConfigurationForm::OWNED_BY_FILTER_ALL || $ownedByFilter == LatestActivitiesConfigurationForm::OWNED_BY_FILTER_USER || is_int($ownedByFilter)'); $searchAttributeDataArray = static::getSearchAttributesDataByModelClassNamesAndRelatedItemIds(array($modelClassName), $relationItemIds, $ownedByFilter); $joinTablesAdapter = new RedBeanModelJoinTablesQueryAdapter($modelClassName); $where = ModelDataProviderUtil::makeWhere($modelClassName, $searchAttributeDataArray[0][$modelClassName], $joinTablesAdapter); $count = RedBeanModel::getCount($joinTablesAdapter, $where, $modelClassName, true); if (isset($searchAttributeDataArray[1][$modelClassName])) { $where = ModelDataProviderUtil::makeWhere($modelClassName, $searchAttributeDataArray[1][$modelClassName], $joinTablesAdapter); return $count + RedBeanModel::getCount($joinTablesAdapter, $where, $modelClassName, true); } return $count; }
/** * @param RedBeanModelAttributeToDataProviderAdapter $modelAttributeToDataProviderAdapter * @param null | string $onTableAliasName * @return string */ protected function resolveSortAttributeContent(RedBeanModelAttributeToDataProviderAdapter $modelAttributeToDataProviderAdapter, $onTableAliasName = null) { assert('is_string($onTableAliasName) || $onTableAliasName == null'); $builder = new ModelJoinBuilder($modelAttributeToDataProviderAdapter, $this->joinTablesAdapter); $tableAliasName = $builder->resolveJoins($onTableAliasName, ModelDataProviderUtil::resolveCanUseFromJoins($onTableAliasName)); $resolvedSortColumnName = self::resolveSortColumnName($modelAttributeToDataProviderAdapter); $queryStringExtraPart = $this->getAttributeClauseQueryStringExtraPart($tableAliasName); return $this->resolveOrderByString($tableAliasName, $resolvedSortColumnName, $queryStringExtraPart); }
/** * This function is made public for unit testing. Calculates the total for each of the select statements * and adds them up. Setting $selectDistinct to true when calling getCount since this is always true * when counting ids. * @return integer - total count across select statements. */ public function calculateTotalItemCount() { $totalCount = 0; foreach ($this->modelClassNamesAndSearchAttributeData as $identifier => $modelClassNameAndSearchAttributeData) { foreach ($modelClassNameAndSearchAttributeData as $modelClassName => $searchAttributeData) { $joinTablesAdapter = new RedBeanModelJoinTablesQueryAdapter($modelClassName); $where = ModelDataProviderUtil::makeWhere($modelClassName, $searchAttributeData, $joinTablesAdapter); $totalCount = $totalCount + RedBeanModel::getCount($joinTablesAdapter, $where, $modelClassName, true); } } return $totalCount; }
public function testMultipleManyManysToTheSameModelSearchQueryFormsCorrectly() { $quote = DatabaseCompatibilityUtil::getQuote(); $searchAttributeData = array(); $searchAttributeData['clauses'] = array(1 => array('attributeName' => 'ppManyAssumptive', 'relatedModelData' => array('attributeName' => 'name', 'operatorType' => 'equals', 'value' => 'somevalue')), 2 => array('attributeName' => 'ppManySpecific', 'relatedModelData' => array('attributeName' => 'name', 'operatorType' => 'equals', 'value' => 'somevalue2'))); $searchAttributeData['structure'] = '1 and 2'; //Build the query 'where' and 'joins'. Confirm they are as expected $joinTablesAdapter = new RedBeanModelJoinTablesQueryAdapter('P'); $where = ModelDataProviderUtil::makeWhere('P', $searchAttributeData, $joinTablesAdapter); $compareWhere = "({$quote}pp{$quote}.{$quote}name{$quote} = 'somevalue') and "; $compareWhere .= "({$quote}pp1{$quote}.{$quote}name{$quote} = 'somevalue2')"; $this->assertEquals($compareWhere, $where); $this->assertEquals(0, $joinTablesAdapter->getFromTableJoinCount()); $this->assertEquals(4, $joinTablesAdapter->getLeftTableJoinCount()); $leftTables = $joinTablesAdapter->getLeftTablesAndAliases(); $this->assertEquals('p_pp', $leftTables[0]['tableName']); $this->assertEquals('pp', $leftTables[1]['tableName']); $this->assertEquals('ppmanyspecificlink_p_pp', $leftTables[2]['tableName']); $this->assertEquals('pp', $leftTables[3]['tableName']); //Distinct because MANY_MANY relationships $this->assertTrue($joinTablesAdapter->getSelectDistinct()); //Now test that the subsetSQL query produced is correct. $subsetSql = AAA::makeSubsetOrCountSqlQuery('p', $joinTablesAdapter, 1, 5, $where, null, false, $joinTablesAdapter->getSelectDistinct()); $compareSubsetSql = "select distinct {$quote}p{$quote}.{$quote}id{$quote} id "; $compareSubsetSql .= "from {$quote}p{$quote} "; $compareSubsetSql .= "left join {$quote}p_pp{$quote} on "; $compareSubsetSql .= "{$quote}p_pp{$quote}.{$quote}p_id{$quote} = {$quote}p{$quote}.{$quote}id{$quote} "; $compareSubsetSql .= "left join {$quote}pp{$quote} on "; $compareSubsetSql .= "{$quote}pp{$quote}.{$quote}id{$quote} = {$quote}p_pp{$quote}.{$quote}pp_id{$quote} "; $compareSubsetSql .= "left join {$quote}ppmanyspecificlink_p_pp{$quote} on "; $compareSubsetSql .= "{$quote}ppmanyspecificlink_p_pp{$quote}.{$quote}p_id{$quote} = {$quote}p{$quote}.{$quote}id{$quote} "; $compareSubsetSql .= "left join {$quote}pp{$quote} pp1 on "; $compareSubsetSql .= "{$quote}pp1{$quote}.{$quote}id{$quote} = {$quote}ppmanyspecificlink_p_pp{$quote}.{$quote}pp_id{$quote} "; $compareSubsetSql .= "where " . $compareWhere . ' '; $compareSubsetSql .= 'limit 5 offset 1'; $this->assertEquals($compareSubsetSql, $subsetSql); //Make sure the sql runs properly. $data = P::getSubset($joinTablesAdapter, 0, 5, $where, null, null, $joinTablesAdapter->getSelectDistinct()); }