From d3b79e594f92f1f4733548364606f125a1ab286c Mon Sep 17 00:00:00 2001 From: Alexander Demidov Date: Fri, 14 Mar 2014 18:50:51 +0400 Subject: [PATCH] Use placeholders for table names in join operations. Correct use count with use join connections. --- model/SqlCriteria.php | 67 +++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 57 insertions(+), 10 deletions(-) diff --git a/model/SqlCriteria.php b/model/SqlCriteria.php index b5b9a4c..9328f7b 100644 --- a/model/SqlCriteria.php +++ b/model/SqlCriteria.php @@ -8,7 +8,7 @@ class SqlCriteria const JOIN_TYPE_INNER = 103; const JOIN_TYPE_OUTER = 104; - private static $join_type_to_reserved_keyword = array( + private static $join_reserved_keyword = array( self::JOIN_TYPE_DEFAULT => 'JOIN', self::JOIN_TYPE_LEFT => 'LEFT JOIN', self::JOIN_TYPE_RIGHT => 'RIGHT JOIN', @@ -39,6 +39,8 @@ class SqlCriteria private $sql_join_expressions = array(); + private $join_table_placeholder = array(); + /** * @param $model SqlModel * @param $sql_expression string|null Sql expression with SELECT and FROM operators. If fetched, then SqlCriteria::select(), SqlCriteria::distinct() disabled for use. @@ -56,7 +58,12 @@ class SqlCriteria */ public function find() { - // preparing link expressions (if exists) + $this->defineJoinExpressions(); + return $this->model->find($this->select, $this->distinct, $this->where, $this->order, $this->limit, null, $this->group_by, $this->sql_expression, $this->sql_expression_params); + } + + private function defineJoinExpressions() + { if ($this->sql_join_expressions) { if (!$this->sql_expression) { $select = $this->model->getDb()->selectExpr($this->select, $this->distinct); @@ -64,7 +71,6 @@ class SqlCriteria } $this->sql_expression .= ' ' . implode(' ', $this->sql_join_expressions); } - return $this->model->find($this->select, $this->distinct, $this->where, $this->order, $this->limit, null, $this->group_by, $this->sql_expression, $this->sql_expression_params); } public function delete() @@ -74,18 +80,37 @@ class SqlCriteria public function count() { - return $this->model->find(new DbExpr('COUNT(*) as count'), '', $this->where, null, null, null, null, $this->sql_expression, $this->sql_expression_params)->fetchField('count'); + $this->sql_expression = 'SELECT COUNT(*) as count FROM :table'; + $this->defineJoinExpressions(); + return $this->model->find(array(), '', $this->where, null, null, null, null, $this->sql_expression, $this->sql_expression_params)->fetchField('count'); + } + + private function defineJoinTablePlaceholder($table_name) + { + if (!isset($this->join_table_placeholder[$table_name])) { + $this->join_table_placeholder[$table_name] = ':table' . (count($this->join_table_placeholder) + 1); + } + } + + public function getTablePh($table_name) + { + $this->defineJoinTablePlaceholder($table_name); + return $this->join_table_placeholder[$table_name]; } public function join($join_table_name, $join_field_name, $donor_table_name = null, $donor_field_name = null, $join_type = self::JOIN_TYPE_DEFAULT) { $donor_field_name = $donor_field_name ? : $join_field_name; - $donor_table_name = $donor_table_name ? : 'table'; - $this->sql_join_expressions[] = self::$join_type_to_reserved_keyword[$join_type] - . ' :' . $join_table_name - . ' ON :' . $donor_table_name . '.' . $donor_field_name . '=' - . ':' . $join_table_name . '.' . $join_field_name; - $this->sql_expression_params[$join_table_name] = new DbExpr($this->model->identify($join_table_name)); + $donor_table_placeholder = $donor_table_name ? $this->getTablePh($donor_table_name) : ':table'; + $join_table_placeholder = $this->getTablePh($join_table_name); + $this->sql_join_expressions[] = self::$join_reserved_keyword[$join_type] + . ' ' . $join_table_placeholder + . ' ON ' . $donor_table_placeholder . '.' . $donor_field_name . '=' + . ' ' . $join_table_placeholder . '.' . $join_field_name; + if ($donor_table_name) { + $this->sql_expression_params[substr($donor_table_placeholder, 1)] = new DbExpr($this->model->identify($donor_table_name)); + } + $this->sql_expression_params[substr($join_table_placeholder, 1)] = new DbExpr($this->model->identify($join_table_name)); return $this; } @@ -109,6 +134,28 @@ class SqlCriteria return $this; } + public function whereJoin($join_table_name, $cond, $value) + { + $join_table_placeholder = $this->getTablePh($join_table_name); + if (is_array($cond)) { + $cond_replace = array(); + foreach ($cond as $key => $value) { + $cond_replace[$this->getCondWithTablePlaceholderIfNeed($join_table_placeholder, $key)] = $value; + } + } else { + $cond = $this->getCondWithTablePlaceholderIfNeed($join_table_placeholder, $cond); + } + return $this->where($cond, $value); + } + + private function getCondWithTablePlaceholderIfNeed($table_placeholder, $cond) + { + if (!strstr('.', $cond)) { + $cond = $table_placeholder . '.' . $cond; + } + return $cond; + } + /** * @param $field string * @param $value array