3namespace Bitrix\Main\DB;
7use Bitrix\Main\ORM\Fields\ScalarField;
39 public function quote($identifier)
41 return pg_escape_identifier($this->connection->getResource(), mb_strtolower($identifier));
49 return 'EXCLUDED.' . $this->
quote($identifier);
63 public function forSql($value, $maxLength = 0)
67 $value = mb_substr($value, 0, $maxLength);
70 return pg_escape_string($this->connection->getResource(), $value);
78 return "'" . pg_escape_bytea($value) .
"'";
88 $fulltextLength = $maxLength ? min($maxLength, static::FULLTEXT_MAXIMUM_LENGTH): static::FULLTEXT_MAXIMUM_LENGTH;
89 return "safe_text_for_tsvector('" . $this->
forSql($value, $fulltextLength) .
"')";
105 return 'current_date';
115 $from = static::getCurrentDateTimeFunction();
119 $from = $from .
"::timestamp";
122 return $from .
" + cast(" . $seconds .
"||' second' as interval)";
132 $from = static::getCurrentDateTimeFunction();
136 $from = $from .
"::timestamp";
139 return '(' . $from .
" + cast(" . $days .
"||' day' as interval))";
147 return 'cast('.$value.
' as date)';
155 static $translation = [
170 foreach (preg_split(
'/(YYYY|MMMM|MM|MI|DD|HH|GG|SS|TT|M|H|G|T|W)/', $format, -1, PREG_SPLIT_DELIM_CAPTURE) as $part)
172 $dbFormat .= $translation[$part] ?? $part;
181 return "to_char(".$field.
", '".$dbFormat.
"')";
190 return $field .
' ~ ' . $regexp;
198 return $field .
' ILIKE ' . $value;
206 return implode(
" || ", func_get_args());
222 return "encode(digest(replace(" . $field .
", '\\', '\\\\')::bytea, 'sha1'), 'hex')";
230 return "COALESCE(".$expression.
", ".
$result.
")";
238 return "OCTET_LENGTH(".$field.
")";
243 return "to_tsvector('english'::regconfig, " . $field .
") @@ to_tsquery('english'::regconfig, " . $value .
")";
250 foreach ($values as
$i => $searchTerm)
252 $values[
$i] = $searchTerm .
':*';
255 return implode(
' & ', $values);
262 foreach ($values as
$i => $searchTerm)
264 $values[
$i] = $searchTerm .
':*';
267 return implode(
' | ', $values);
275 return "timestamp '".$value.
"'";
283 return "TO_CHAR(".$fieldName.
", 'YYYY-MM-DD HH24:MI:SS')";
293 return array($this,
"convertFromDbDateTime");
297 return array($this,
"convertFromDbDate");
301 return parent::getConverter($field);
310 if($value !==
null && $value !=
'0000-00-00 00:00:00')
323 if($value !==
null && $value !=
'0000-00-00')
336 return 'CAST('.$fieldName.
' AS varchar)';
354 switch ($field->getSize())
367 $defaultPrecision = 18;
370 $precision = $field->getPrecision() > 0 ? $field->getPrecision() : $defaultPrecision;
371 $scale = $field->getScale() > 0 ? $field->getScale() : $defaultScale;
376 $scale = $defaultScale;
379 return "decimal($precision, $scale)";
399 $values = $field->getValues();
401 if (preg_match(
'/^[0-9]+$/', $values[0]) && preg_match(
'/^[0-9]+$/', $values[1]))
407 $falseLen = mb_strlen($values[0]);
408 $trueLen = mb_strlen($values[1]);
409 if ($falseLen === 1 && $trueLen === 1)
413 return 'varchar(' . max($falseLen, $trueLen) .
')';
418 return 'varchar('.max(array_map(
'mb_strlen', $field->getValues())).
')';
423 $defaultLength =
false;
428 if ($defaultLength ===
false || $defaultLength > $validator->getMax())
430 $defaultLength = $validator->getMax();
434 return 'varchar('.($defaultLength > 0? $defaultLength: 255).
')';
464 case 'double precision':
473 case 'timestamp without time zone':
475 case 'timestamp with time zone':
488 $field->setConnection($this->connection);
498 $offset = intval($offset);
499 $limit = intval($limit);
501 if ($offset > 0 && $limit <= 0)
503 throw new \Bitrix\Main\ArgumentException(
"Limit must be set if offset is set");
508 $sql .=
"\nLIMIT ".$limit;
513 $sql .=
" OFFSET ".$offset;
526 return 'INSERT INTO ' . $tableName .
$fields . $sql .
' ON CONFLICT DO NOTHING';
534 return 'ASC NULLS FIRST';
542 return 'DESC NULLS LAST';
554 !empty($insert[0]) && !empty($insert[1])
555 && !empty($update[0])
559 $sql =
'INSERT INTO ' . $this->
quote($tableName) .
' ('.$insert[0].
')
560 VALUES (' . $insert[1] .
')
561 ON CONFLICT (' . implode(
',', array_map([$this,
'quote'], $primaryFields)) .
')
562 DO UPDATE SET ' . $update[0];
583 $maxBodySize = 1024*1024;
586 foreach ($insertRows as $insertFields)
588 $insert = $this->
prepareInsert($tableName, $insertFields,
true);
589 if (!$head && $insert && $insert[0])
591 $head =
'INSERT INTO ' . $this->
quote($tableName) .
' (' . implode(
', ', $insert[0]) .
') VALUES ';
592 $tail =
' ON CONFLICT (' . implode(
',', array_map([$this,
'quote'], $primaryFields)) .
') DO UPDATE SET (' . implode(
', ', $insert[0]) .
') = (' . implode(
', ', array_map(
function(
$f){
return 'EXCLUDED.'.$f;}, $insert[0])) .
')';
594 if ($insert && $insert[1])
596 $values =
'(' . implode(
', ', $insert[1]) .
')';
597 $bodySize += mb_strlen($values) + 4;
599 if ($bodySize > $maxBodySize)
601 $result[] = $head.implode(
', ', $body).$tail;
609 $result[] = $head.implode(
', ', $body).$tail;
623 $tableFields = $this->connection->getTableFields($tableName);
625 $tableFields = array_change_key_case($tableFields, CASE_UPPER);
626 $updateFields = array_change_key_case($updateFields, CASE_UPPER);
627 foreach ($updateFields as $columnName => $value)
629 if (isset($tableFields[$columnName]))
631 $updateColumns[] = $this->
quote($columnName);
632 $updateValues[] = $this->
convertToDb($value, $tableFields[$columnName]);
636 trigger_error(
"Column `{$columnName}` is not found in the `{$tableName}` table", E_USER_WARNING);
640 $sql =
'INSERT INTO ' . $this->
quote($tableName) .
' (' . implode(
',', array_map([$this,
'quote'],
$selectFields)) .
') ';
642 $sql .=
' ON CONFLICT (' . implode(
',', array_map([$this,
'quote'], $primaryFields)) .
') DO UPDATE SET ';
643 if (
count($updateColumns) === 1)
645 $sql .= $updateColumns[0] .
' = ' . $updateValues[0];
649 $sql .=
' (' . implode(
', ', $updateColumns) .
') = (' . implode(
', ', $updateValues) .
')';
660 $primaryColumns = [];
661 foreach ($primaryFields as $columnName)
663 $primaryColumns[] = $this->
quote($columnName);
665 $sqlPrimary = implode(
', ', $primaryColumns);
668 foreach (
$order as $columnName => $sort)
670 $orderColumns[] = $this->
quote($columnName) .
' ' . $sort;
672 $sqlOrder = $orderColumns ?
' ORDER BY ' . implode(
', ', $orderColumns) :
'';
673 return 'DELETE FROM ' . $this->
quote($tableName) .
' WHERE (' . $sqlPrimary .
') IN (SELECT ' . $sqlPrimary .
' FROM ' . $this->
quote($tableName) .
' WHERE ' . $where . $sqlOrder .
' LIMIT ' . intval($limit) .
')';
683 return 'row_number() over()';
691 $dml =
"UPDATE " . $tableName .
' AS ' . $tableAlias .
" SET\n";
694 foreach (
$fields as $fieldName => $fieldValue)
696 $set .= ($set ?
',' :
'') . $fieldName .
' = ' .$fieldValue .
"\n";
699 $dml .=
'FROM ' . $from .
"\n";
700 $dml .=
'WHERE ' . $where .
"\n";
705 protected function getOrderByField(
string $field,
array $values, callable $callback,
bool $quote =
true): string
707 $field = $quote ? $this->
quote($field) : $field;
708 $values = implode(
',', array_map($callback, $values));
710 return "array_position(ARRAY[{$values}], {$field})";
softCastTextToChar($fieldName)
getOrderByField(string $field, array $values, callable $callback, bool $quote=true)
prepareMergeMultiple($tableName, array $primaryFields, array $insertRows)
convertToDbBinary($value)
getMatchFunction($field, $value)
getTopSql($sql, $limit, $offset=0)
getIsNullFunction($expression, $result)
getDateToCharFunction($fieldName)
getIlikeOperator($field, $value)
formatDate($format, $field=null)
getRegexpOperator($field, $regexp)
getDatetimeToDateFunction($value)
prepareDeleteLimit($tableName, array $primaryFields, $where, array $order, $limit)
const FULLTEXT_MAXIMUM_LENGTH
addDaysToDateTime($days, $from=null)
getFieldByColumnType($name, $type, array $parameters=null)
getColumnTypeByField(ScalarField $field)
initRowNumber($variableName)
getConverter(ScalarField $field)
prepareCorrelatedUpdate($tableName, $tableAlias, $fields, $from, $where)
getMatchAndExpression($values, $prefixSearch=false)
getLengthFunction($field)
getMatchOrExpression($values, $prefixSearch=false)
forSql($value, $maxLength=0)
getCurrentDateTimeFunction()
convertToFullText($value, $maxLength=0)
convertFromDbDateTime($value)
addSecondsToDateTime($seconds, $from=null)
convertFromDbDate($value)
prepareMergeSelect($tableName, array $primaryFields, array $selectFields, $select, $updateFields)
getCharToDateFunction($value)
getInsertIgnore($tableName, $fields, $sql)
prepareMerge($tableName, array $primaryFields, array $insertFields, array $updateFields)
getRowNumber($variableName)
prepareUpdate($tableName, array $fields)
prepareInsert($tableName, array $fields, $returnAsArray=false)
convertToDb($value, ORM\Fields\IReadable $field=null)
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"