/** * * Modifies the native fetch with eager joins so that the through table * and the foreign table are joined properly. * * @param Solar_Sql_Model_Params_Eager $eager The eager params. * * @param Solar_Sql_Model_Params_Fetch $fetch The native fetch params. * * @return void * */ protected function _modEagerFetchJoin($eager, $fetch) { // first, join the native table to the through table $join = array('type' => 'inner', 'name' => "{$this->through_table} AS {$this->through_alias}", 'cond' => "{$fetch['alias']}.{$this->native_col} = " . "{$this->through_alias}.{$this->through_native_col}", 'cols' => null); $fetch->join($join); // then join to the through table to the foreign table $join = array('type' => $eager['join_type'], 'name' => "{$this->foreign_table} AS {$eager['alias']}", 'cond' => "{$eager['alias']}.{$this->foreign_col} = " . "{$this->through_alias}.{$this->through_foreign_col}", 'cols' => null); // extra conditions for the parent fetch if ($eager['join_cond']) { // what type of join? if ($join['type'] == 'left') { // convert the eager conditions to a WHERE clause foreach ((array) $eager['join_cond'] as $cond => $val) { $fetch->where($cond, $val); } } else { // merge join conditions $join['cond'] = array_merge((array) $join['cond'], (array) $eager['join_cond']); } } // done! $fetch->join($join); }
/** * * Modifies the native fetch with an eager join so that the foreign table * is joined properly. * * @param Solar_Sql_Model_Params_Eager $eager The eager params. * * @param Solar_Sql_Model_Params_Fetch $fetch The native fetch params. * * @return void * */ protected function _modEagerFetchJoin($eager, $fetch) { $join = array('type' => $eager['join_type'], 'name' => "{$this->foreign_table} AS {$eager['alias']}", 'cond' => array(), 'cols' => null); // primary-key join condition on foreign table $join['cond'][] = "{$fetch['alias']}.{$this->native_col} = " . "{$eager['alias']}.{$this->foreign_col}"; // extra conditions for the parent fetch if ($eager['join_cond']) { // what type of join? if ($join['type'] == 'left') { // convert the eager conditions to a WHERE clause foreach ((array) $eager['join_cond'] as $cond => $val) { $fetch->where($cond, $val); } } else { // merge join conditions $join['cond'] = array_merge($join['cond'], (array) $eager['join_cond']); } } // done! $fetch->join($join); // always DISTINCT so we don't get multiple duplicate native rows $fetch->distinct(true); }
/** * * Modifies a params object **in place** to add joins for a tag list. * * The methodology is taken and modified from * <http://forge.mysql.com/wiki/TagSchema#Items_Having_All_of_A_Set_of_Tags>. * * @param Solar_Sql_Model_Params_Fetch $params The fetch params. * * @param array $tags A list of unique tags. * * @return void * */ protected function _modParamsJoinTags(Solar_Sql_Model_Params_Fetch $params, $tags) { // normalize the tag list $tags = $this->_fixTagList($tags); // if no tags, no need to modify if (!$tags) { return; } // since this model uses single-table inheritance, we need the model // alias, not just the table name. $alias = $this->_model_name; // for each tag, add a join to tags and taggings, chaining each // subsequent join to the previous one. // the first tag join-pair is special; we connect it to the nodes // table directly, since we don't have a previous join to chain from. $params->join(array('type' => "inner", 'name' => "taggings AS taggings1", 'cond' => "taggings1.node_id = {$alias}.id")); $params->join(array('type' => "inner", 'name' => "tags AS tags1", 'cond' => "taggings1.tag_id = tags1.id")); // take the first tag off the top of the list $val = array_shift($tags); $params->where("tags1.name = ?", $val); // now deal with all remaining tags, chaining each current join to the // previous one. foreach ($tags as $key => $val) { $curr = $key + 2; // because keys are zero-based, and we already shifted one $prev = $key + 1; // the "through" table $params->join(array('type' => "inner", 'name' => "taggings AS taggings{$curr}", 'cond' => "taggings{$curr}.node_id = taggings{$prev}.node_id")); // the "tags" table $params->join(array('type' => "inner", 'name' => "tags AS tags{$curr}", 'cond' => "taggings{$curr}.tag_id = tags{$curr}.id")); // the WHERE condition for the tag name $params->where("tags{$curr}.name = ?", $val); } }
/** * * Modifies the native fetch with an eager join so that columns are * selected from the foreign table. * * @param Solar_Sql_Model_Params_Eager $eager The eager params. * * @param Solar_Sql_Model_Params_Fetch $fetch The native fetch params. * * @return void * */ protected function _modEagerFetchJoin($eager, $fetch) { // the basic join array $join = array('type' => strtolower($eager['join_type']), 'name' => "{$this->foreign_table} AS {$eager['alias']}", 'cond' => array(), 'cols' => null); // standard to-one condition (works for both has-one and belongs-to) $join['cond'][] = "{$fetch['alias']}.{$this->native_col} = " . "{$eager['alias']}.{$this->foreign_col}"; // extra conditions for the parent fetch if ($eager['join_cond']) { // what type of join? if ($join['type'] == 'left') { // convert the eager conditions to a WHERE clause foreach ((array) $eager['join_cond'] as $cond => $val) { $fetch->where($cond, $val); } } else { // merge join conditions $join['cond'] = array_merge($join['cond'], (array) $eager['join_cond']); } } // what columns to fetch? if (!$eager['cols']) { $cols = null; } else { $cols = array(); foreach ($eager['cols'] as $col) { $cols[] = "{$col} AS {$eager['cols_prefix']}__{$col}"; } } // add the columns $join['cols'] = $cols; // add the join to the parent fetch $fetch->join($join); }