Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoeland Jago Douma <rullzer@users.noreply.github.com>2019-12-04 13:49:26 +0300
committerGitHub <noreply@github.com>2019-12-04 13:49:26 +0300
commit76b78edd40fcb5dbe7f0434cbc41d2e291acfec1 (patch)
tree8a9e487e080cbdd001cd2bf5f2fb5feacb69ae25
parentd4f1cc7da6a2d7834099750827a50dcc675c64e5 (diff)
parent74c6beb603f18d51d92730bb631bfe77d8feb400 (diff)
Merge pull request #17833 from nextcloud/propagator-no-negative-sizes
dont set folder size to negative values during propagation
-rw-r--r--lib/private/DB/QueryBuilder/FunctionBuilder/FunctionBuilder.php8
-rw-r--r--lib/private/DB/QueryBuilder/FunctionBuilder/SqliteFunctionBuilder.php9
-rw-r--r--lib/private/Files/Cache/Propagator.php7
-rw-r--r--lib/public/DB/QueryBuilder/IFunctionBuilder.php30
-rw-r--r--tests/lib/DB/QueryBuilder/FunctionBuilderTest.php20
-rw-r--r--tests/lib/Files/Cache/PropagatorTest.php11
6 files changed, 83 insertions, 2 deletions
diff --git a/lib/private/DB/QueryBuilder/FunctionBuilder/FunctionBuilder.php b/lib/private/DB/QueryBuilder/FunctionBuilder/FunctionBuilder.php
index 46bb536dfd2..ffa758e4da7 100644
--- a/lib/private/DB/QueryBuilder/FunctionBuilder/FunctionBuilder.php
+++ b/lib/private/DB/QueryBuilder/FunctionBuilder/FunctionBuilder.php
@@ -85,4 +85,12 @@ class FunctionBuilder implements IFunctionBuilder {
public function min($field) {
return new QueryFunction('MIN(' . $this->helper->quoteColumnName($field) . ')');
}
+
+ public function greatest($x, $y) {
+ return new QueryFunction('GREATEST(' . $this->helper->quoteColumnName($x) . ', ' . $this->helper->quoteColumnName($y) . ')');
+ }
+
+ public function least($x, $y) {
+ return new QueryFunction('LEAST(' . $this->helper->quoteColumnName($x) . ', ' . $this->helper->quoteColumnName($y) . ')');
+ }
}
diff --git a/lib/private/DB/QueryBuilder/FunctionBuilder/SqliteFunctionBuilder.php b/lib/private/DB/QueryBuilder/FunctionBuilder/SqliteFunctionBuilder.php
index 21898cf3f93..f37ac20ecab 100644
--- a/lib/private/DB/QueryBuilder/FunctionBuilder/SqliteFunctionBuilder.php
+++ b/lib/private/DB/QueryBuilder/FunctionBuilder/SqliteFunctionBuilder.php
@@ -30,4 +30,13 @@ class SqliteFunctionBuilder extends FunctionBuilder {
public function concat($x, $y) {
return new QueryFunction('(' . $this->helper->quoteColumnName($x) . ' || ' . $this->helper->quoteColumnName($y) . ')');
}
+
+ public function greatest($x, $y) {
+ return new QueryFunction('MAX(' . $this->helper->quoteColumnName($x) . ', ' . $this->helper->quoteColumnName($y) . ')');
+ }
+
+ public function least($x, $y) {
+ return new QueryFunction('MIN(' . $this->helper->quoteColumnName($x) . ', ' . $this->helper->quoteColumnName($y) . ')');
+ }
+
}
diff --git a/lib/private/Files/Cache/Propagator.php b/lib/private/Files/Cache/Propagator.php
index 989a4d0c7d5..41b4c2bb070 100644
--- a/lib/private/Files/Cache/Propagator.php
+++ b/lib/private/Files/Cache/Propagator.php
@@ -91,7 +91,7 @@ class Propagator implements IPropagator {
}, $parentHashes);
$builder->update('filecache')
- ->set('mtime', $builder->createFunction('GREATEST(' . $builder->getColumnName('mtime') . ', ' . $builder->createNamedParameter((int)$time, IQueryBuilder::PARAM_INT) . ')'))
+ ->set('mtime', $builder->func()->greatest('mtime', $builder->createNamedParameter((int)$time, IQueryBuilder::PARAM_INT)))
->set('etag', $builder->createNamedParameter($etag, IQueryBuilder::PARAM_STR))
->where($builder->expr()->eq('storage', $builder->createNamedParameter($storageId, IQueryBuilder::PARAM_INT)))
->andWhere($builder->expr()->in('path_hash', $hashParams));
@@ -102,7 +102,10 @@ class Propagator implements IPropagator {
// we need to do size separably so we can ignore entries with uncalculated size
$builder = $this->connection->getQueryBuilder();
$builder->update('filecache')
- ->set('size', $builder->func()->add('size', $builder->createNamedParameter($sizeDifference)))
+ ->set('size', $builder->func()->greatest(
+ $builder->createNamedParameter(-1, IQueryBuilder::PARAM_INT),
+ $builder->func()->add('size', $builder->createNamedParameter($sizeDifference)))
+ )
->where($builder->expr()->eq('storage', $builder->createNamedParameter($storageId, IQueryBuilder::PARAM_INT)))
->andWhere($builder->expr()->in('path_hash', $hashParams))
->andWhere($builder->expr()->gt('size', $builder->expr()->literal(-1, IQueryBuilder::PARAM_INT)));
diff --git a/lib/public/DB/QueryBuilder/IFunctionBuilder.php b/lib/public/DB/QueryBuilder/IFunctionBuilder.php
index 861a576914a..d82d3ada8cf 100644
--- a/lib/public/DB/QueryBuilder/IFunctionBuilder.php
+++ b/lib/public/DB/QueryBuilder/IFunctionBuilder.php
@@ -109,6 +109,8 @@ interface IFunctionBuilder {
/**
* Takes the maximum of all rows in a column
*
+ * If you want to get the maximum value of multiple columns in the same row, use `greatest` instead
+ *
* @param mixed $field the column to maximum
*
* @return IQueryFunction
@@ -119,10 +121,38 @@ interface IFunctionBuilder {
/**
* Takes the minimum of all rows in a column
*
+ * If you want to get the minimum value of multiple columns in the same row, use `least` instead
+ *
* @param mixed $field the column to minimum
*
* @return IQueryFunction
* @since 18.0.0
*/
public function min($field);
+
+ /**
+ * Takes the maximum of multiple values
+ *
+ * If you want to get the maximum value of all rows in a column, use `max` instead
+ *
+ * @param mixed $x the first input field or number
+ * @param mixed $y the first input field or number
+ *
+ * @return IQueryFunction
+ * @since 18.0.0
+ */
+ public function greatest($x, $y);
+
+ /**
+ * Takes the minimum of multiple values
+ *
+ * If you want to get the minimum value of all rows in a column, use `min` instead
+ *
+ * @param mixed $x the first input field or number
+ * @param mixed $y the first input field or number
+ *
+ * @return IQueryFunction
+ * @since 18.0.0
+ */
+ public function least($x, $y);
}
diff --git a/tests/lib/DB/QueryBuilder/FunctionBuilderTest.php b/tests/lib/DB/QueryBuilder/FunctionBuilderTest.php
index d7617125faa..3d9baf35b1c 100644
--- a/tests/lib/DB/QueryBuilder/FunctionBuilderTest.php
+++ b/tests/lib/DB/QueryBuilder/FunctionBuilderTest.php
@@ -198,4 +198,24 @@ class FunctionBuilderTest extends TestCase {
$this->assertEquals(10, $query->execute()->fetchColumn());
}
+
+ public function testGreatest() {
+ $query = $this->connection->getQueryBuilder();
+
+ $query->select($query->func()->greatest($query->createNamedParameter(2, IQueryBuilder::PARAM_INT), new Literal(1)));
+ $query->from('appconfig')
+ ->setMaxResults(1);
+
+ $this->assertEquals(2, $query->execute()->fetchColumn());
+ }
+
+ public function testLeast() {
+ $query = $this->connection->getQueryBuilder();
+
+ $query->select($query->func()->least($query->createNamedParameter(2, IQueryBuilder::PARAM_INT), new Literal(1)));
+ $query->from('appconfig')
+ ->setMaxResults(1);
+
+ $this->assertEquals(1, $query->execute()->fetchColumn());
+ }
}
diff --git a/tests/lib/Files/Cache/PropagatorTest.php b/tests/lib/Files/Cache/PropagatorTest.php
index ce6b84ee4d0..c1822c90282 100644
--- a/tests/lib/Files/Cache/PropagatorTest.php
+++ b/tests/lib/Files/Cache/PropagatorTest.php
@@ -81,6 +81,17 @@ class PropagatorTest extends TestCase {
}
}
+ public function testSizePropagationNoNegative() {
+ $paths = ['', 'foo', 'foo/bar'];
+ $oldInfos = $this->getFileInfos($paths);
+ $this->storage->getPropagator()->propagateChange('foo/bar/file.txt', time(), -100);
+ $newInfos = $this->getFileInfos($paths);
+
+ foreach ($oldInfos as $i => $oldInfo) {
+ $this->assertEquals(-1, $newInfos[$i]->getSize());
+ }
+ }
+
public function testBatchedPropagation() {
$this->storage->mkdir('foo/baz');
$this->storage->mkdir('asd');