/** * _get_where_clause 依照 $search 條件以及指定的 $table 回傳 WHERE 的 SQL * * @param Pix_Table_Search $search * @param Pix_Table $table * @access protected * @return string */ protected function _get_where_clause($search) { $terms = array(); $table = $search->getTable(); foreach ($search->getSearchCondictions() as $condiction) { switch ($condiction[0]) { case 'map': $terms[] = "(" . $this->column_quote($condiction[1]) . ' = ' . $this->quoteWithColumn($table, $condiction[2], $condiction[1]) . ")"; break; case 'string': $terms[] = "(" . $condiction[1] . ")"; break; default: throw new Pix_Table_Exception('不知名的狀態'); } } if ($search->after() or $search->before()) { $orders = $search->order() ?: array_fill_keys($table->getPrimaryColumns(), 'asc'); if (!is_array($orders)) { throw new Pix_Table_Exception("指定的 ORDER 無法使用 after 或是 before"); } if (!($row = $search->after())) { // 如果指定 before 的話,順序要調過來 $row = $search->before(); $orders = Pix_Table_Search::reverseOrder($orders); } $equal_orders = array(); $or_terms = array(); foreach ($orders as $order => $way) { $and_terms = array(); foreach ($equal_orders as $equal_order) { $and_terms[] = $this->column_quote($equal_order) . " = " . $this->quoteWithColumn($table, $row->{$equal_order}, $equal_order); } $and_terms[] = $this->column_quote($order) . ('asc' == $way ? '>' : '<') . " " . $this->quoteWithColumn($table, $row->{$order}, $order); $or_terms[] = '(' . implode(' AND ', $and_terms) . ')'; $equal_orders[] = $order; } $terms[] = '(' . implode(' OR ', $or_terms) . ')'; } if (!$terms) { return '1 = 1'; } return implode(' AND ', $terms); }
/** * fetch 取得符合 $search 條件的資料 * * @param Pix_Table $table * @param Pix_Table_Search $search * @param string|array $select_columns * @access public * @return void */ public function fetch($table, $search, $select_columns = '*') { $db = $this->_getDb(); $condictions = $search->getSearchCondictions(); if (count($condictions) == 0) { // 完全沒有條件就是 scan table $options = array(); $options['TableName'] = $table->getTableName(); // 加上指定 column if ('*' != $select_columns) { $options['AttributesToGet'] = $select_columns; } $response = $db->scan($options); } elseif (count($condictions) == 1) { // 只給一個條件的話只能是 HashKey $primary_keys = $table->getPrimaryColumns(); // 只能是 map if ('map' != $condictions[0][0]) { throw new Pix_Table_Exception("不支援的 search 條件"); } // 只能是 Primary Key 的第一個 if ($primary_keys[0] != $condictions[0][1]) { throw new Pix_Table_Exception("不支援的 search 條件"); } $options = array(); $options['TableName'] = $table->getTableName(); $options['HashKeyValue'] = array($this->_getColumnType($table, $primary_keys[0]) => $condictions[0][2]); // 加上 Limit if (!is_null($limit = $search->limit())) { $options['Limit'] = $limit; } // 加上 after or before if ($row = $search->after()) { $options['RangeKeyCondition'] = array('ComparisonOperator' => AmazonDynamoDB::CONDITION_GREATER_THAN, 'AttributeValueList' => array(array($this->_getColumnType($table, $primary_keys[1]) => $row->{$primary_keys[1]}))); } elseif ($row = $search->before()) { $options['RangeKeyCondition'] = array('ComparisonOperator' => AmazonDynamoDB::CONDITION_LESS_THAN, 'AttributeValueList' => array(array($this->_getColumnType($table, $primary_keys[1]) => $row->{$primary_keys[1]}))); $options['ScanIndexForward'] = false; } // 加上指定 column if ('*' != $select_columns) { $options['AttributesToGet'] = $select_columns; } $response = $db->query($options); } else { throw new Pix_Table_Exception("不支援的 search 條件"); } if (200 != $response->status) { throw new Pix_Table_Exception("AmazonDynamoDB: " . $get_response->body->Message); } $ret = array(); foreach ($response->body->Items[0] as $item) { $row = array(); foreach ($table->_columns as $name => $col) { if ($item->{$name}) { $row[$name] = strval($item->{$name}->S); } } $ret[] = $row; } return $ret; }