/** * Push values to the DBPreparedQuery SQL query field end. * * @param array $values List of pairs key => value or SQL query parts with * parameters. * @param string $separator Join separator. */ public function sqlPushValues($values, $separator = ", ") { $chunks = array(); foreach ($values as $fieldName => $fieldValue) { if (!is_array($fieldValue)) { if (!is_null($fieldValue)) { $chunks[] = $fieldName . " = ?"; $this->types .= DBField::getType($fieldValue); $this->params[] = $fieldValue; } else { $chunks[] = $fieldName; } } else { $condition = $fieldName; $localParams = $fieldValue; $chunks[] = $condition; foreach ($localParams as $param) { $this->types .= DBField::getType($param); $this->params[] = $param; } } } $this->query .= implode($separator, $chunks); }
/** * Inits DBQueryCondition object. * * @param DBField $field Field to compare. * @param string $conditionType Type of the comparison operator or condition. * @param mixed $value May be other DBField object or value to compare with. * * @throws DBQueryConditionException If some parameters invalid. */ public function __construct(DBField $field, $conditionType, $value) { $this->type = self::sqlConditionType($conditionType); if (!Tools::isInstanceOf($value, "DBField")) { $this->field = $field; switch ($this->type) { case "=": case "<": case ">": case "!=": $this->value = DBField::castValue($this->field->type, $value); $this->sqlCondition = "`" . $field->name . "` " . $this->type . " " . DBField::sqlValue($this->field->type, $value); $this->preparedCondition = "`" . $field->name . "` " . $this->type . " ?"; $this->preparedTypes = $this->field->type; $this->preparedData = [DBField::sqlValue($this->field->type, $value)]; break; case "LIKE": case "NOT LIKE": $this->value = DBField::castValue($this->field->type, $value); if ($this->field->type != "s") { throw new DBQueryConditionException("Field type is not a string"); } $this->sqlCondition = "`" . $field->name . "` " . $this->type . " " . DBField::sqlValue($this->field->type, $value); $this->preparedCondition = "`" . $field->name . "` " . $this->type . " ?"; $this->preparedTypes = $this->field->type; $this->preparedData = [DBField::sqlValue($this->field->type, $value)]; break; case "IN": case "NOT IN": if (is_array($value) && !empty($value)) { $dataList = []; foreach ($value as $dataItem) { $dataList[] = DBField::sqlValue($this->field->type, $dataItem); } $dataList = array_unique($dataList); $count = count($dataList); if ($count > 0) { $qmStr = "?"; $tStr = $this->field->type; for ($i = 1; $i < $count; $i++) { $qmStr .= ", ?"; $tStr .= $this->field->type; } } else { $this->sqlCondition = "1"; return; } $this->sqlCondition = "`" . $field->name . "` " . $this->type . " (" . implode(", ", $dataList) . ")"; $this->preparedCondition = "`" . $field->name . "` " . $this->type . " (" . $qmStr . ")"; $this->preparedTypes = $tStr; $this->preparedData = $dataList; } else { throw new DBQueryConditionException("Invalid data for 'IN'/'NOT IN' condition"); } break; case "BETWEEN": if (is_array($value) && count($value) == 2 && isset($value[0]) && isset($value[1])) { $from = DBField::sqlValue($this->field->type, $value[0]); $to = DBField::sqlValue($this->field->type, $value[1]); $this->sqlCondition = "`" . $field->name . "` BETWEEN " . $from . " AND " . $to; $this->preparedCondition = "`" . $field->name . "` BETWEEN ? AND ?"; $this->preparedTypes = $this->field->type . $this->field->type; $this->preparedData = [$from, $to]; } else { throw new DBQueryConditionException("Invalid data for 'BETWEEN' condition"); } break; } } else { $field1 = $field; $field2 = $value; switch ($this->type) { case "=": case "<": case ">": case "!=": case "LIKE": case "NOT LIKE": $this->sqlCondition = "`" . $field1->name . "` " . $this->type . " `" . $field2->name . "`"; break; case "IN": case "NOT IN": // impossible, use array instead of DBField break; case "BETWEEN": // impossible, use array instead of DBField break; } } }
/** * Outputs DB query debug information to the stream. * * @param string $query SQL query. * @param string $types SQL types string. * @param array $params List of SQL query parameters. */ public static function showQueryDebugInfo($query = "", $types = "", array $params = array()) { OutputStream::start(); if (!empty($query)) { if (empty($types) && empty($params)) { OutputStream::message(OutputStream::MSG_INFO, "Q: " . $query); } else { if (strlen($types) === count($params)) { $query = preg_replace('/\\s+/', ' ', $query); $preparedQuery = $query; $paramsStr = array(); for ($i = 0; $i < strlen($types); $i++) { $query = preg_replace("/\\?/", DBField::sqlValue($types[$i], $params[$i]), $query, 1); $paramsStr[] = $types[$i] . ": " . DBField::sqlValue($types[$i], $params[$i]); } OutputStream::message(OutputStream::MSG_INFO, "Q: " . $query); OutputStream::message(OutputStream::MSG_INFO, "P: " . $preparedQuery); OutputStream::message(OutputStream::MSG_INFO, "A: [" . implode(", ", $paramsStr) . "]"); } else { OutputStream::message(OutputStream::MSG_ERROR, "Number of types is not equal parameters number."); OutputStream::message(OutputStream::MSG_INFO, "T: " . $types); OutputStream::message(OutputStream::MSG_INFO, "A: [" . implode(", ", $params) . "]"); } } } else { OutputStream::message(OutputStream::MSG_WARNING, "DB query is empty."); } OutputStream::close(); }