Skip to content

Commit

Permalink
Merge pull request #35757 from nextcloud/backport/31696/stable23
Browse files Browse the repository at this point in the history
[stable23] Use getLengthExpression to measure field length instead of like
  • Loading branch information
come-nc authored Dec 19, 2022
2 parents 2d449ba + 6185e32 commit 658ee56
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ protected function getSelectQuery(string $table): IQueryBuilder {
$qb = $this->dbc->getQueryBuilder();
$qb->select('owncloud_name', 'directory_uuid')
->from($table)
->where($qb->expr()->like('owncloud_name', $qb->createNamedParameter(str_repeat('_', 65) . '%'), Types::STRING));
->where($qb->expr()->gt($qb->func()->octetLength('owncloud_name'), '64', IQueryBuilder::PARAM_INT));
return $qb;
}

Expand Down
12 changes: 12 additions & 0 deletions lib/private/DB/QueryBuilder/FunctionBuilder/FunctionBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,18 @@ public function count($count = '', $alias = ''): IQueryFunction {
return new QueryFunction('COUNT(' . $quotedName . ')' . $alias);
}

public function octetLength($field, $alias = ''): IQueryFunction {
$alias = $alias ? (' AS ' . $this->helper->quoteColumnName($alias)) : '';
$quotedName = $this->helper->quoteColumnName($field);
return new QueryFunction('OCTET_LENGTH(' . $quotedName . ')' . $alias);
}

public function charLength($field, $alias = ''): IQueryFunction {
$alias = $alias ? (' AS ' . $this->helper->quoteColumnName($alias)) : '';
$quotedName = $this->helper->quoteColumnName($field);
return new QueryFunction('CHAR_LENGTH(' . $quotedName . ')' . $alias);
}

public function max($field): IQueryFunction {
return new QueryFunction('MAX(' . $this->helper->quoteColumnName($field) . ')');
}
Expand Down
12 changes: 12 additions & 0 deletions lib/private/DB/QueryBuilder/FunctionBuilder/OCIFunctionBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,16 @@ public function least($x, $y): IQueryFunction {

return parent::least($x, $y);
}

public function octetLength($field, $alias = ''): IQueryFunction {
$alias = $alias ? (' AS ' . $this->helper->quoteColumnName($alias)) : '';
$quotedName = $this->helper->quoteColumnName($field);
return new QueryFunction('LENGTHB(' . $quotedName . ')' . $alias);
}

public function charLength($field, $alias = ''): IQueryFunction {
$alias = $alias ? (' AS ' . $this->helper->quoteColumnName($alias)) : '';
$quotedName = $this->helper->quoteColumnName($field);
return new QueryFunction('LENGTH(' . $quotedName . ')' . $alias);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,16 @@ public function greatest($x, $y): IQueryFunction {
public function least($x, $y): IQueryFunction {
return new QueryFunction('MIN(' . $this->helper->quoteColumnName($x) . ', ' . $this->helper->quoteColumnName($y) . ')');
}

public function octetLength($field, $alias = ''): IQueryFunction {
$alias = $alias ? (' AS ' . $this->helper->quoteColumnName($alias)) : '';
$quotedName = $this->helper->quoteColumnName($field);
return new QueryFunction('LENGTH(CAST(' . $quotedName . ' as BLOB))' . $alias);
}

public function charLength($field, $alias = ''): IQueryFunction {
$alias = $alias ? (' AS ' . $this->helper->quoteColumnName($alias)) : '';
$quotedName = $this->helper->quoteColumnName($field);
return new QueryFunction('LENGTH(' . $quotedName . ')' . $alias);
}
}
18 changes: 18 additions & 0 deletions lib/public/DB/QueryBuilder/IFunctionBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,24 @@ public function subtract($x, $y): IQueryFunction;
*/
public function count($count = '', $alias = ''): IQueryFunction;

/**
* @param string|ILiteral|IParameter|IQueryFunction $field The input to be measured
* @param string $alias Alias for the length
*
* @return IQueryFunction
* @since 24.0.0
*/
public function octetLength($field, $alias = ''): IQueryFunction;

/**
* @param string|ILiteral|IParameter|IQueryFunction $field The input to be measured
* @param string $alias Alias for the length
*
* @return IQueryFunction
* @since 24.0.0
*/
public function charLength($field, $alias = ''): IQueryFunction;

/**
* Takes the maximum of all rows in a column
*
Expand Down
50 changes: 50 additions & 0 deletions tests/lib/DB/QueryBuilder/FunctionBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,56 @@ public function testCount() {
$this->assertGreaterThan(1, $column);
}

public function octetLengthProvider() {
return [
['', 0],
['foobar', 6],
['', 3],
['šđčćž', 10],
];
}

/**
* @dataProvider octetLengthProvider
*/
public function testOctetLength(string $str, int $bytes) {
$query = $this->connection->getQueryBuilder();

$query->select($query->func()->octetLength($query->createNamedParameter($str, IQueryBuilder::PARAM_STR)));
$query->from('appconfig')
->setMaxResults(1);

$result = $query->execute();
$column = $result->fetchOne();
$result->closeCursor();
$this->assertEquals($bytes, $column);
}

public function charLengthProvider() {
return [
['', 0],
['foobar', 6],
['', 2],
['šđčćž', 5],
];
}

/**
* @dataProvider charLengthProvider
*/
public function testCharLength(string $str, int $bytes) {
$query = $this->connection->getQueryBuilder();

$query->select($query->func()->charLength($query->createNamedParameter($str, IQueryBuilder::PARAM_STR)));
$query->from('appconfig')
->setMaxResults(1);

$result = $query->execute();
$column = $result->fetchOne();
$result->closeCursor();
$this->assertEquals($bytes, $column);
}

private function setUpMinMax($value) {
$query = $this->connection->getQueryBuilder();

Expand Down

0 comments on commit 658ee56

Please sign in to comment.