@@ -18,256 +18,256 @@ |
||
| 18 | 18 | |
| 19 | 19 | #[\PHPUnit\Framework\Attributes\Group('DB')] |
| 20 | 20 | class ExpressionBuilderDBTest extends TestCase { |
| 21 | - /** @var \Doctrine\DBAL\Connection|IDBConnection */ |
|
| 22 | - protected $connection; |
|
| 23 | - protected $schemaSetup = false; |
|
| 24 | - |
|
| 25 | - protected function setUp(): void { |
|
| 26 | - parent::setUp(); |
|
| 27 | - |
|
| 28 | - $this->connection = Server::get(IDBConnection::class); |
|
| 29 | - $this->prepareTestingTable(); |
|
| 30 | - } |
|
| 31 | - |
|
| 32 | - public static function likeProvider(): array { |
|
| 33 | - $connection = Server::get(IDBConnection::class); |
|
| 34 | - |
|
| 35 | - return [ |
|
| 36 | - ['foo', 'bar', false], |
|
| 37 | - ['foo', 'foo', true], |
|
| 38 | - ['foo', 'f%', true], |
|
| 39 | - ['foo', '%o', true], |
|
| 40 | - ['foo', '%', true], |
|
| 41 | - ['foo', 'fo_', true], |
|
| 42 | - ['foo', 'foo_', false], |
|
| 43 | - ['foo', $connection->escapeLikeParameter('fo_'), false], |
|
| 44 | - ['foo', $connection->escapeLikeParameter('f%'), false], |
|
| 45 | - ]; |
|
| 46 | - } |
|
| 47 | - |
|
| 48 | - /** |
|
| 49 | - * |
|
| 50 | - * @param string $param1 |
|
| 51 | - * @param string $param2 |
|
| 52 | - * @param boolean $match |
|
| 53 | - */ |
|
| 54 | - #[\PHPUnit\Framework\Attributes\DataProvider('likeProvider')] |
|
| 55 | - public function testLike($param1, $param2, $match): void { |
|
| 56 | - $query = $this->connection->getQueryBuilder(); |
|
| 57 | - |
|
| 58 | - $query->select(new Literal('1')) |
|
| 59 | - ->from('users') |
|
| 60 | - ->where($query->expr()->like($query->createNamedParameter($param1), $query->createNamedParameter($param2))); |
|
| 61 | - |
|
| 62 | - $result = $query->executeQuery(); |
|
| 63 | - $column = $result->fetchOne(); |
|
| 64 | - $result->closeCursor(); |
|
| 65 | - $this->assertEquals($match, $column); |
|
| 66 | - } |
|
| 67 | - |
|
| 68 | - public static function ilikeProvider(): array { |
|
| 69 | - $connection = Server::get(IDBConnection::class); |
|
| 70 | - |
|
| 71 | - return [ |
|
| 72 | - ['foo', 'bar', false], |
|
| 73 | - ['foo', 'foo', true], |
|
| 74 | - ['foo', 'Foo', true], |
|
| 75 | - ['foo', 'f%', true], |
|
| 76 | - ['foo', '%o', true], |
|
| 77 | - ['foo', '%', true], |
|
| 78 | - ['foo', 'fo_', true], |
|
| 79 | - ['foo', 'foo_', false], |
|
| 80 | - ['foo', $connection->escapeLikeParameter('fo_'), false], |
|
| 81 | - ['foo', $connection->escapeLikeParameter('f%'), false], |
|
| 82 | - ]; |
|
| 83 | - } |
|
| 84 | - |
|
| 85 | - /** |
|
| 86 | - * |
|
| 87 | - * @param string $param1 |
|
| 88 | - * @param string $param2 |
|
| 89 | - * @param boolean $match |
|
| 90 | - */ |
|
| 91 | - #[\PHPUnit\Framework\Attributes\DataProvider('ilikeProvider')] |
|
| 92 | - public function testILike($param1, $param2, $match): void { |
|
| 93 | - $query = $this->connection->getQueryBuilder(); |
|
| 94 | - |
|
| 95 | - $query->select(new Literal('1')) |
|
| 96 | - ->from('users') |
|
| 97 | - ->where($query->expr()->iLike($query->createNamedParameter($param1), $query->createNamedParameter($param2))); |
|
| 98 | - |
|
| 99 | - $result = $query->executeQuery(); |
|
| 100 | - $column = $result->fetchOne(); |
|
| 101 | - $result->closeCursor(); |
|
| 102 | - $this->assertEquals($match, $column); |
|
| 103 | - } |
|
| 104 | - |
|
| 105 | - public function testCastColumn(): void { |
|
| 106 | - $appId = $this->getUniqueID('testing'); |
|
| 107 | - $this->createConfig($appId, '1', '4'); |
|
| 108 | - |
|
| 109 | - $query = $this->connection->getQueryBuilder(); |
|
| 110 | - $query->update('appconfig') |
|
| 111 | - ->set('configvalue', |
|
| 112 | - $query->expr()->castColumn( |
|
| 113 | - $query->createFunction( |
|
| 114 | - '(' . $query->expr()->castColumn('configvalue', IQueryBuilder::PARAM_INT) |
|
| 115 | - . ' + 1)' |
|
| 116 | - ), IQueryBuilder::PARAM_STR |
|
| 117 | - ) |
|
| 118 | - ) |
|
| 119 | - ->where($query->expr()->eq('appid', $query->createNamedParameter($appId))) |
|
| 120 | - ->andWhere($query->expr()->eq('configkey', $query->createNamedParameter('1'))); |
|
| 121 | - |
|
| 122 | - $result = $query->executeStatement(); |
|
| 123 | - $this->assertEquals(1, $result); |
|
| 124 | - } |
|
| 125 | - |
|
| 126 | - public function testLongText(): void { |
|
| 127 | - $appId = $this->getUniqueID('testing'); |
|
| 128 | - $this->createConfig($appId, 'mykey', 'myvalue'); |
|
| 129 | - |
|
| 130 | - $query = $this->connection->getQueryBuilder(); |
|
| 131 | - $query->select('*') |
|
| 132 | - ->from('appconfig') |
|
| 133 | - ->where($query->expr()->eq('appid', $query->createNamedParameter($appId))) |
|
| 134 | - ->andWhere($query->expr()->eq('configkey', $query->createNamedParameter('mykey'))) |
|
| 135 | - ->andWhere($query->expr()->eq('configvalue', $query->createNamedParameter('myvalue', IQueryBuilder::PARAM_STR), IQueryBuilder::PARAM_STR)); |
|
| 136 | - |
|
| 137 | - $result = $query->executeQuery(); |
|
| 138 | - $entries = $result->fetchAllAssociative(); |
|
| 139 | - $result->closeCursor(); |
|
| 140 | - self::assertCount(1, $entries); |
|
| 141 | - self::assertEquals('myvalue', $entries[0]['configvalue']); |
|
| 142 | - } |
|
| 143 | - |
|
| 144 | - public function testJson(): void { |
|
| 145 | - $appId = $this->getUniqueID('testing'); |
|
| 146 | - $query = $this->connection->getQueryBuilder(); |
|
| 147 | - $query->insert('share') |
|
| 148 | - ->values([ |
|
| 149 | - 'uid_owner' => $query->createNamedParameter('uid_owner'), |
|
| 150 | - 'item_type' => $query->createNamedParameter('item_type'), |
|
| 151 | - 'permissions' => $query->createNamedParameter(0), |
|
| 152 | - 'stime' => $query->createNamedParameter(0), |
|
| 153 | - 'accepted' => $query->createNamedParameter(0), |
|
| 154 | - 'mail_send' => $query->createNamedParameter(0), |
|
| 155 | - 'share_type' => $query->createNamedParameter(0), |
|
| 156 | - 'share_with' => $query->createNamedParameter($appId), |
|
| 157 | - 'attributes' => $query->createNamedParameter('[["permissions","before"]]'), |
|
| 158 | - ]) |
|
| 159 | - ->executeStatement(); |
|
| 160 | - |
|
| 161 | - $query = $this->connection->getQueryBuilder(); |
|
| 162 | - $query->update('share') |
|
| 163 | - ->set('attributes', $query->createNamedParameter('[["permissions","after"]]')); |
|
| 164 | - if ($this->connection->getDatabaseProvider(true) === IDBConnection::PLATFORM_MYSQL) { |
|
| 165 | - $query->where($query->expr()->eq('attributes', $query->createFunction("JSON_ARRAY(JSON_ARRAY('permissions','before'))"), IQueryBuilder::PARAM_JSON)); |
|
| 166 | - } else { |
|
| 167 | - $query->where($query->expr()->eq('attributes', $query->createNamedParameter('[["permissions","before"]]'), IQueryBuilder::PARAM_JSON)); |
|
| 168 | - } |
|
| 169 | - $query->executeStatement(); |
|
| 170 | - |
|
| 171 | - $query = $this->connection->getQueryBuilder(); |
|
| 172 | - $query->select('attributes') |
|
| 173 | - ->from('share') |
|
| 174 | - ->where($query->expr()->eq('share_with', $query->createNamedParameter($appId))); |
|
| 175 | - |
|
| 176 | - $result = $query->executeQuery(); |
|
| 177 | - $entries = $result->fetchAll(); |
|
| 178 | - $result->closeCursor(); |
|
| 179 | - self::assertCount(1, $entries); |
|
| 180 | - self::assertEquals([['permissions','after']], json_decode($entries[0]['attributes'], true)); |
|
| 181 | - } |
|
| 182 | - |
|
| 183 | - public function testDateTimeEquals(): void { |
|
| 184 | - $dateTime = new \DateTime('2023-01-01'); |
|
| 185 | - $insert = $this->connection->getQueryBuilder(); |
|
| 186 | - $insert->insert('testing') |
|
| 187 | - ->values(['datetime' => $insert->createNamedParameter($dateTime, IQueryBuilder::PARAM_DATETIME_MUTABLE)]) |
|
| 188 | - ->executeStatement(); |
|
| 189 | - |
|
| 190 | - $query = $this->connection->getQueryBuilder(); |
|
| 191 | - $result = $query->select('*') |
|
| 192 | - ->from('testing') |
|
| 193 | - ->where($query->expr()->eq('datetime', $query->createNamedParameter($dateTime, IQueryBuilder::PARAM_DATETIME_MUTABLE))) |
|
| 194 | - ->executeQuery(); |
|
| 195 | - $entries = $result->fetchAllAssociative(); |
|
| 196 | - $result->closeCursor(); |
|
| 197 | - self::assertCount(1, $entries); |
|
| 198 | - } |
|
| 199 | - |
|
| 200 | - public function testDateTimeLess(): void { |
|
| 201 | - $dateTime = new \DateTime('2022-01-01'); |
|
| 202 | - $dateTimeCompare = new \DateTime('2022-01-02'); |
|
| 203 | - $insert = $this->connection->getQueryBuilder(); |
|
| 204 | - $insert->insert('testing') |
|
| 205 | - ->values(['datetime' => $insert->createNamedParameter($dateTime, IQueryBuilder::PARAM_DATETIME_MUTABLE)]) |
|
| 206 | - ->executeStatement(); |
|
| 207 | - |
|
| 208 | - $query = $this->connection->getQueryBuilder(); |
|
| 209 | - $result = $query->select('*') |
|
| 210 | - ->from('testing') |
|
| 211 | - ->where($query->expr()->lt('datetime', $query->createNamedParameter($dateTimeCompare, IQueryBuilder::PARAM_DATETIME_MUTABLE))) |
|
| 212 | - ->executeQuery(); |
|
| 213 | - $entries = $result->fetchAllAssociative(); |
|
| 214 | - $result->closeCursor(); |
|
| 215 | - self::assertCount(1, $entries); |
|
| 216 | - } |
|
| 217 | - |
|
| 218 | - public function testDateTimeGreater(): void { |
|
| 219 | - $dateTime = new \DateTime('2023-01-02'); |
|
| 220 | - $dateTimeCompare = new \DateTime('2023-01-01'); |
|
| 221 | - $insert = $this->connection->getQueryBuilder(); |
|
| 222 | - $insert->insert('testing') |
|
| 223 | - ->values(['datetime' => $insert->createNamedParameter($dateTime, IQueryBuilder::PARAM_DATETIME_MUTABLE)]) |
|
| 224 | - ->executeStatement(); |
|
| 225 | - |
|
| 226 | - $query = $this->connection->getQueryBuilder(); |
|
| 227 | - $result = $query->select('*') |
|
| 228 | - ->from('testing') |
|
| 229 | - ->where($query->expr()->gt('datetime', $query->createNamedParameter($dateTimeCompare, IQueryBuilder::PARAM_DATETIME_MUTABLE))) |
|
| 230 | - ->executeQuery(); |
|
| 231 | - $entries = $result->fetchAllAssociative(); |
|
| 232 | - $result->closeCursor(); |
|
| 233 | - self::assertCount(1, $entries); |
|
| 234 | - } |
|
| 235 | - |
|
| 236 | - protected function createConfig($appId, $key, $value) { |
|
| 237 | - $query = $this->connection->getQueryBuilder(); |
|
| 238 | - $query->insert('appconfig') |
|
| 239 | - ->values([ |
|
| 240 | - 'appid' => $query->createNamedParameter($appId), |
|
| 241 | - 'configkey' => $query->createNamedParameter((string)$key), |
|
| 242 | - 'configvalue' => $query->createNamedParameter((string)$value), |
|
| 243 | - ]) |
|
| 244 | - ->executeStatement(); |
|
| 245 | - } |
|
| 246 | - |
|
| 247 | - protected function prepareTestingTable(): void { |
|
| 248 | - if ($this->schemaSetup) { |
|
| 249 | - $this->connection->getQueryBuilder()->delete('testing')->executeStatement(); |
|
| 250 | - } |
|
| 251 | - |
|
| 252 | - $prefix = Server::get(IConfig::class)->getSystemValueString('dbtableprefix', 'oc_'); |
|
| 253 | - $schema = $this->connection->createSchema(); |
|
| 254 | - try { |
|
| 255 | - $schema->getTable($prefix . 'testing'); |
|
| 256 | - $this->connection->getQueryBuilder()->delete('testing')->executeStatement(); |
|
| 257 | - } catch (SchemaException $e) { |
|
| 258 | - $this->schemaSetup = true; |
|
| 259 | - $table = $schema->createTable($prefix . 'testing'); |
|
| 260 | - $table->addColumn('id', Types::BIGINT, [ |
|
| 261 | - 'autoincrement' => true, |
|
| 262 | - 'notnull' => true, |
|
| 263 | - ]); |
|
| 264 | - |
|
| 265 | - $table->addColumn('datetime', Types::DATETIME, [ |
|
| 266 | - 'notnull' => false, |
|
| 267 | - ]); |
|
| 268 | - |
|
| 269 | - $table->setPrimaryKey(['id']); |
|
| 270 | - $this->connection->migrateToSchema($schema); |
|
| 271 | - } |
|
| 272 | - } |
|
| 21 | + /** @var \Doctrine\DBAL\Connection|IDBConnection */ |
|
| 22 | + protected $connection; |
|
| 23 | + protected $schemaSetup = false; |
|
| 24 | + |
|
| 25 | + protected function setUp(): void { |
|
| 26 | + parent::setUp(); |
|
| 27 | + |
|
| 28 | + $this->connection = Server::get(IDBConnection::class); |
|
| 29 | + $this->prepareTestingTable(); |
|
| 30 | + } |
|
| 31 | + |
|
| 32 | + public static function likeProvider(): array { |
|
| 33 | + $connection = Server::get(IDBConnection::class); |
|
| 34 | + |
|
| 35 | + return [ |
|
| 36 | + ['foo', 'bar', false], |
|
| 37 | + ['foo', 'foo', true], |
|
| 38 | + ['foo', 'f%', true], |
|
| 39 | + ['foo', '%o', true], |
|
| 40 | + ['foo', '%', true], |
|
| 41 | + ['foo', 'fo_', true], |
|
| 42 | + ['foo', 'foo_', false], |
|
| 43 | + ['foo', $connection->escapeLikeParameter('fo_'), false], |
|
| 44 | + ['foo', $connection->escapeLikeParameter('f%'), false], |
|
| 45 | + ]; |
|
| 46 | + } |
|
| 47 | + |
|
| 48 | + /** |
|
| 49 | + * |
|
| 50 | + * @param string $param1 |
|
| 51 | + * @param string $param2 |
|
| 52 | + * @param boolean $match |
|
| 53 | + */ |
|
| 54 | + #[\PHPUnit\Framework\Attributes\DataProvider('likeProvider')] |
|
| 55 | + public function testLike($param1, $param2, $match): void { |
|
| 56 | + $query = $this->connection->getQueryBuilder(); |
|
| 57 | + |
|
| 58 | + $query->select(new Literal('1')) |
|
| 59 | + ->from('users') |
|
| 60 | + ->where($query->expr()->like($query->createNamedParameter($param1), $query->createNamedParameter($param2))); |
|
| 61 | + |
|
| 62 | + $result = $query->executeQuery(); |
|
| 63 | + $column = $result->fetchOne(); |
|
| 64 | + $result->closeCursor(); |
|
| 65 | + $this->assertEquals($match, $column); |
|
| 66 | + } |
|
| 67 | + |
|
| 68 | + public static function ilikeProvider(): array { |
|
| 69 | + $connection = Server::get(IDBConnection::class); |
|
| 70 | + |
|
| 71 | + return [ |
|
| 72 | + ['foo', 'bar', false], |
|
| 73 | + ['foo', 'foo', true], |
|
| 74 | + ['foo', 'Foo', true], |
|
| 75 | + ['foo', 'f%', true], |
|
| 76 | + ['foo', '%o', true], |
|
| 77 | + ['foo', '%', true], |
|
| 78 | + ['foo', 'fo_', true], |
|
| 79 | + ['foo', 'foo_', false], |
|
| 80 | + ['foo', $connection->escapeLikeParameter('fo_'), false], |
|
| 81 | + ['foo', $connection->escapeLikeParameter('f%'), false], |
|
| 82 | + ]; |
|
| 83 | + } |
|
| 84 | + |
|
| 85 | + /** |
|
| 86 | + * |
|
| 87 | + * @param string $param1 |
|
| 88 | + * @param string $param2 |
|
| 89 | + * @param boolean $match |
|
| 90 | + */ |
|
| 91 | + #[\PHPUnit\Framework\Attributes\DataProvider('ilikeProvider')] |
|
| 92 | + public function testILike($param1, $param2, $match): void { |
|
| 93 | + $query = $this->connection->getQueryBuilder(); |
|
| 94 | + |
|
| 95 | + $query->select(new Literal('1')) |
|
| 96 | + ->from('users') |
|
| 97 | + ->where($query->expr()->iLike($query->createNamedParameter($param1), $query->createNamedParameter($param2))); |
|
| 98 | + |
|
| 99 | + $result = $query->executeQuery(); |
|
| 100 | + $column = $result->fetchOne(); |
|
| 101 | + $result->closeCursor(); |
|
| 102 | + $this->assertEquals($match, $column); |
|
| 103 | + } |
|
| 104 | + |
|
| 105 | + public function testCastColumn(): void { |
|
| 106 | + $appId = $this->getUniqueID('testing'); |
|
| 107 | + $this->createConfig($appId, '1', '4'); |
|
| 108 | + |
|
| 109 | + $query = $this->connection->getQueryBuilder(); |
|
| 110 | + $query->update('appconfig') |
|
| 111 | + ->set('configvalue', |
|
| 112 | + $query->expr()->castColumn( |
|
| 113 | + $query->createFunction( |
|
| 114 | + '(' . $query->expr()->castColumn('configvalue', IQueryBuilder::PARAM_INT) |
|
| 115 | + . ' + 1)' |
|
| 116 | + ), IQueryBuilder::PARAM_STR |
|
| 117 | + ) |
|
| 118 | + ) |
|
| 119 | + ->where($query->expr()->eq('appid', $query->createNamedParameter($appId))) |
|
| 120 | + ->andWhere($query->expr()->eq('configkey', $query->createNamedParameter('1'))); |
|
| 121 | + |
|
| 122 | + $result = $query->executeStatement(); |
|
| 123 | + $this->assertEquals(1, $result); |
|
| 124 | + } |
|
| 125 | + |
|
| 126 | + public function testLongText(): void { |
|
| 127 | + $appId = $this->getUniqueID('testing'); |
|
| 128 | + $this->createConfig($appId, 'mykey', 'myvalue'); |
|
| 129 | + |
|
| 130 | + $query = $this->connection->getQueryBuilder(); |
|
| 131 | + $query->select('*') |
|
| 132 | + ->from('appconfig') |
|
| 133 | + ->where($query->expr()->eq('appid', $query->createNamedParameter($appId))) |
|
| 134 | + ->andWhere($query->expr()->eq('configkey', $query->createNamedParameter('mykey'))) |
|
| 135 | + ->andWhere($query->expr()->eq('configvalue', $query->createNamedParameter('myvalue', IQueryBuilder::PARAM_STR), IQueryBuilder::PARAM_STR)); |
|
| 136 | + |
|
| 137 | + $result = $query->executeQuery(); |
|
| 138 | + $entries = $result->fetchAllAssociative(); |
|
| 139 | + $result->closeCursor(); |
|
| 140 | + self::assertCount(1, $entries); |
|
| 141 | + self::assertEquals('myvalue', $entries[0]['configvalue']); |
|
| 142 | + } |
|
| 143 | + |
|
| 144 | + public function testJson(): void { |
|
| 145 | + $appId = $this->getUniqueID('testing'); |
|
| 146 | + $query = $this->connection->getQueryBuilder(); |
|
| 147 | + $query->insert('share') |
|
| 148 | + ->values([ |
|
| 149 | + 'uid_owner' => $query->createNamedParameter('uid_owner'), |
|
| 150 | + 'item_type' => $query->createNamedParameter('item_type'), |
|
| 151 | + 'permissions' => $query->createNamedParameter(0), |
|
| 152 | + 'stime' => $query->createNamedParameter(0), |
|
| 153 | + 'accepted' => $query->createNamedParameter(0), |
|
| 154 | + 'mail_send' => $query->createNamedParameter(0), |
|
| 155 | + 'share_type' => $query->createNamedParameter(0), |
|
| 156 | + 'share_with' => $query->createNamedParameter($appId), |
|
| 157 | + 'attributes' => $query->createNamedParameter('[["permissions","before"]]'), |
|
| 158 | + ]) |
|
| 159 | + ->executeStatement(); |
|
| 160 | + |
|
| 161 | + $query = $this->connection->getQueryBuilder(); |
|
| 162 | + $query->update('share') |
|
| 163 | + ->set('attributes', $query->createNamedParameter('[["permissions","after"]]')); |
|
| 164 | + if ($this->connection->getDatabaseProvider(true) === IDBConnection::PLATFORM_MYSQL) { |
|
| 165 | + $query->where($query->expr()->eq('attributes', $query->createFunction("JSON_ARRAY(JSON_ARRAY('permissions','before'))"), IQueryBuilder::PARAM_JSON)); |
|
| 166 | + } else { |
|
| 167 | + $query->where($query->expr()->eq('attributes', $query->createNamedParameter('[["permissions","before"]]'), IQueryBuilder::PARAM_JSON)); |
|
| 168 | + } |
|
| 169 | + $query->executeStatement(); |
|
| 170 | + |
|
| 171 | + $query = $this->connection->getQueryBuilder(); |
|
| 172 | + $query->select('attributes') |
|
| 173 | + ->from('share') |
|
| 174 | + ->where($query->expr()->eq('share_with', $query->createNamedParameter($appId))); |
|
| 175 | + |
|
| 176 | + $result = $query->executeQuery(); |
|
| 177 | + $entries = $result->fetchAll(); |
|
| 178 | + $result->closeCursor(); |
|
| 179 | + self::assertCount(1, $entries); |
|
| 180 | + self::assertEquals([['permissions','after']], json_decode($entries[0]['attributes'], true)); |
|
| 181 | + } |
|
| 182 | + |
|
| 183 | + public function testDateTimeEquals(): void { |
|
| 184 | + $dateTime = new \DateTime('2023-01-01'); |
|
| 185 | + $insert = $this->connection->getQueryBuilder(); |
|
| 186 | + $insert->insert('testing') |
|
| 187 | + ->values(['datetime' => $insert->createNamedParameter($dateTime, IQueryBuilder::PARAM_DATETIME_MUTABLE)]) |
|
| 188 | + ->executeStatement(); |
|
| 189 | + |
|
| 190 | + $query = $this->connection->getQueryBuilder(); |
|
| 191 | + $result = $query->select('*') |
|
| 192 | + ->from('testing') |
|
| 193 | + ->where($query->expr()->eq('datetime', $query->createNamedParameter($dateTime, IQueryBuilder::PARAM_DATETIME_MUTABLE))) |
|
| 194 | + ->executeQuery(); |
|
| 195 | + $entries = $result->fetchAllAssociative(); |
|
| 196 | + $result->closeCursor(); |
|
| 197 | + self::assertCount(1, $entries); |
|
| 198 | + } |
|
| 199 | + |
|
| 200 | + public function testDateTimeLess(): void { |
|
| 201 | + $dateTime = new \DateTime('2022-01-01'); |
|
| 202 | + $dateTimeCompare = new \DateTime('2022-01-02'); |
|
| 203 | + $insert = $this->connection->getQueryBuilder(); |
|
| 204 | + $insert->insert('testing') |
|
| 205 | + ->values(['datetime' => $insert->createNamedParameter($dateTime, IQueryBuilder::PARAM_DATETIME_MUTABLE)]) |
|
| 206 | + ->executeStatement(); |
|
| 207 | + |
|
| 208 | + $query = $this->connection->getQueryBuilder(); |
|
| 209 | + $result = $query->select('*') |
|
| 210 | + ->from('testing') |
|
| 211 | + ->where($query->expr()->lt('datetime', $query->createNamedParameter($dateTimeCompare, IQueryBuilder::PARAM_DATETIME_MUTABLE))) |
|
| 212 | + ->executeQuery(); |
|
| 213 | + $entries = $result->fetchAllAssociative(); |
|
| 214 | + $result->closeCursor(); |
|
| 215 | + self::assertCount(1, $entries); |
|
| 216 | + } |
|
| 217 | + |
|
| 218 | + public function testDateTimeGreater(): void { |
|
| 219 | + $dateTime = new \DateTime('2023-01-02'); |
|
| 220 | + $dateTimeCompare = new \DateTime('2023-01-01'); |
|
| 221 | + $insert = $this->connection->getQueryBuilder(); |
|
| 222 | + $insert->insert('testing') |
|
| 223 | + ->values(['datetime' => $insert->createNamedParameter($dateTime, IQueryBuilder::PARAM_DATETIME_MUTABLE)]) |
|
| 224 | + ->executeStatement(); |
|
| 225 | + |
|
| 226 | + $query = $this->connection->getQueryBuilder(); |
|
| 227 | + $result = $query->select('*') |
|
| 228 | + ->from('testing') |
|
| 229 | + ->where($query->expr()->gt('datetime', $query->createNamedParameter($dateTimeCompare, IQueryBuilder::PARAM_DATETIME_MUTABLE))) |
|
| 230 | + ->executeQuery(); |
|
| 231 | + $entries = $result->fetchAllAssociative(); |
|
| 232 | + $result->closeCursor(); |
|
| 233 | + self::assertCount(1, $entries); |
|
| 234 | + } |
|
| 235 | + |
|
| 236 | + protected function createConfig($appId, $key, $value) { |
|
| 237 | + $query = $this->connection->getQueryBuilder(); |
|
| 238 | + $query->insert('appconfig') |
|
| 239 | + ->values([ |
|
| 240 | + 'appid' => $query->createNamedParameter($appId), |
|
| 241 | + 'configkey' => $query->createNamedParameter((string)$key), |
|
| 242 | + 'configvalue' => $query->createNamedParameter((string)$value), |
|
| 243 | + ]) |
|
| 244 | + ->executeStatement(); |
|
| 245 | + } |
|
| 246 | + |
|
| 247 | + protected function prepareTestingTable(): void { |
|
| 248 | + if ($this->schemaSetup) { |
|
| 249 | + $this->connection->getQueryBuilder()->delete('testing')->executeStatement(); |
|
| 250 | + } |
|
| 251 | + |
|
| 252 | + $prefix = Server::get(IConfig::class)->getSystemValueString('dbtableprefix', 'oc_'); |
|
| 253 | + $schema = $this->connection->createSchema(); |
|
| 254 | + try { |
|
| 255 | + $schema->getTable($prefix . 'testing'); |
|
| 256 | + $this->connection->getQueryBuilder()->delete('testing')->executeStatement(); |
|
| 257 | + } catch (SchemaException $e) { |
|
| 258 | + $this->schemaSetup = true; |
|
| 259 | + $table = $schema->createTable($prefix . 'testing'); |
|
| 260 | + $table->addColumn('id', Types::BIGINT, [ |
|
| 261 | + 'autoincrement' => true, |
|
| 262 | + 'notnull' => true, |
|
| 263 | + ]); |
|
| 264 | + |
|
| 265 | + $table->addColumn('datetime', Types::DATETIME, [ |
|
| 266 | + 'notnull' => false, |
|
| 267 | + ]); |
|
| 268 | + |
|
| 269 | + $table->setPrimaryKey(['id']); |
|
| 270 | + $this->connection->migrateToSchema($schema); |
|
| 271 | + } |
|
| 272 | + } |
|
| 273 | 273 | } |
@@ -111,7 +111,7 @@ discard block |
||
| 111 | 111 | ->set('configvalue', |
| 112 | 112 | $query->expr()->castColumn( |
| 113 | 113 | $query->createFunction( |
| 114 | - '(' . $query->expr()->castColumn('configvalue', IQueryBuilder::PARAM_INT) |
|
| 114 | + '('.$query->expr()->castColumn('configvalue', IQueryBuilder::PARAM_INT) |
|
| 115 | 115 | . ' + 1)' |
| 116 | 116 | ), IQueryBuilder::PARAM_STR |
| 117 | 117 | ) |
@@ -177,7 +177,7 @@ discard block |
||
| 177 | 177 | $entries = $result->fetchAll(); |
| 178 | 178 | $result->closeCursor(); |
| 179 | 179 | self::assertCount(1, $entries); |
| 180 | - self::assertEquals([['permissions','after']], json_decode($entries[0]['attributes'], true)); |
|
| 180 | + self::assertEquals([['permissions', 'after']], json_decode($entries[0]['attributes'], true)); |
|
| 181 | 181 | } |
| 182 | 182 | |
| 183 | 183 | public function testDateTimeEquals(): void { |
@@ -238,8 +238,8 @@ discard block |
||
| 238 | 238 | $query->insert('appconfig') |
| 239 | 239 | ->values([ |
| 240 | 240 | 'appid' => $query->createNamedParameter($appId), |
| 241 | - 'configkey' => $query->createNamedParameter((string)$key), |
|
| 242 | - 'configvalue' => $query->createNamedParameter((string)$value), |
|
| 241 | + 'configkey' => $query->createNamedParameter((string) $key), |
|
| 242 | + 'configvalue' => $query->createNamedParameter((string) $value), |
|
| 243 | 243 | ]) |
| 244 | 244 | ->executeStatement(); |
| 245 | 245 | } |
@@ -252,11 +252,11 @@ discard block |
||
| 252 | 252 | $prefix = Server::get(IConfig::class)->getSystemValueString('dbtableprefix', 'oc_'); |
| 253 | 253 | $schema = $this->connection->createSchema(); |
| 254 | 254 | try { |
| 255 | - $schema->getTable($prefix . 'testing'); |
|
| 255 | + $schema->getTable($prefix.'testing'); |
|
| 256 | 256 | $this->connection->getQueryBuilder()->delete('testing')->executeStatement(); |
| 257 | 257 | } catch (SchemaException $e) { |
| 258 | 258 | $this->schemaSetup = true; |
| 259 | - $table = $schema->createTable($prefix . 'testing'); |
|
| 259 | + $table = $schema->createTable($prefix.'testing'); |
|
| 260 | 260 | $table->addColumn('id', Types::BIGINT, [ |
| 261 | 261 | 'autoincrement' => true, |
| 262 | 262 | 'notnull' => true, |
@@ -16,130 +16,130 @@ |
||
| 16 | 16 | |
| 17 | 17 | class SupportedDatabase implements ISetupCheck { |
| 18 | 18 | |
| 19 | - private const MIN_MARIADB = '10.6'; |
|
| 20 | - private const MAX_MARIADB = '11.8'; |
|
| 21 | - private const MIN_MYSQL = '8.0'; |
|
| 22 | - private const MAX_MYSQL = '8.4'; |
|
| 23 | - private const MIN_POSTGRES = '14'; |
|
| 24 | - private const MAX_POSTGRES = '18'; |
|
| 25 | - private const MIN_ORACLE = '12.2'; |
|
| 26 | - private const MAX_ORACLE = '26'; |
|
| 19 | + private const MIN_MARIADB = '10.6'; |
|
| 20 | + private const MAX_MARIADB = '11.8'; |
|
| 21 | + private const MIN_MYSQL = '8.0'; |
|
| 22 | + private const MAX_MYSQL = '8.4'; |
|
| 23 | + private const MIN_POSTGRES = '14'; |
|
| 24 | + private const MAX_POSTGRES = '18'; |
|
| 25 | + private const MIN_ORACLE = '12.2'; |
|
| 26 | + private const MAX_ORACLE = '26'; |
|
| 27 | 27 | |
| 28 | - public function __construct( |
|
| 29 | - private IL10N $l10n, |
|
| 30 | - private IURLGenerator $urlGenerator, |
|
| 31 | - private IDBConnection $connection, |
|
| 32 | - ) { |
|
| 33 | - } |
|
| 28 | + public function __construct( |
|
| 29 | + private IL10N $l10n, |
|
| 30 | + private IURLGenerator $urlGenerator, |
|
| 31 | + private IDBConnection $connection, |
|
| 32 | + ) { |
|
| 33 | + } |
|
| 34 | 34 | |
| 35 | - public function getCategory(): string { |
|
| 36 | - return 'database'; |
|
| 37 | - } |
|
| 35 | + public function getCategory(): string { |
|
| 36 | + return 'database'; |
|
| 37 | + } |
|
| 38 | 38 | |
| 39 | - public function getName(): string { |
|
| 40 | - return $this->l10n->t('Database version'); |
|
| 41 | - } |
|
| 39 | + public function getName(): string { |
|
| 40 | + return $this->l10n->t('Database version'); |
|
| 41 | + } |
|
| 42 | 42 | |
| 43 | - public function run(): SetupResult { |
|
| 44 | - $databasePlatform = $this->connection->getDatabaseProvider(); |
|
| 45 | - if ($databasePlatform === IDBConnection::PLATFORM_MYSQL || $databasePlatform === IDBConnection::PLATFORM_MARIADB) { |
|
| 46 | - $statement = $this->connection->prepare("SHOW VARIABLES LIKE 'version';"); |
|
| 47 | - $result = $statement->execute(); |
|
| 48 | - $row = $result->fetchAssociative(); |
|
| 49 | - $version = $row['Value']; |
|
| 50 | - $versionlc = strtolower($version); |
|
| 51 | - // we only care about X.Y not X.Y.Z differences |
|
| 52 | - [$major, $minor, ] = explode('.', $versionlc); |
|
| 53 | - $versionConcern = $major . '.' . $minor; |
|
| 54 | - if (str_contains($versionlc, 'mariadb')) { |
|
| 55 | - if (version_compare($versionConcern, '10.3', '=')) { |
|
| 56 | - return SetupResult::info( |
|
| 57 | - $this->l10n->t( |
|
| 58 | - 'MariaDB version 10.3 detected, this version is end-of-life and only supported as part of Ubuntu 20.04. MariaDB >=%1$s and <=%2$s is suggested for best performance, stability and functionality with this version of Nextcloud.', |
|
| 59 | - [ |
|
| 60 | - self::MIN_MARIADB, |
|
| 61 | - self::MAX_MARIADB, |
|
| 62 | - ] |
|
| 63 | - ), |
|
| 64 | - ); |
|
| 65 | - } elseif (version_compare($versionConcern, self::MIN_MARIADB, '<') || version_compare($versionConcern, self::MAX_MARIADB, '>')) { |
|
| 66 | - return SetupResult::warning( |
|
| 67 | - $this->l10n->t( |
|
| 68 | - 'MariaDB version "%1$s" detected. MariaDB >=%2$s and <=%3$s is suggested for best performance, stability and functionality with this version of Nextcloud.', |
|
| 69 | - [ |
|
| 70 | - $version, |
|
| 71 | - self::MIN_MARIADB, |
|
| 72 | - self::MAX_MARIADB, |
|
| 73 | - ], |
|
| 74 | - ), |
|
| 75 | - ); |
|
| 76 | - } |
|
| 77 | - } else { |
|
| 78 | - if (version_compare($versionConcern, self::MIN_MYSQL, '<') || version_compare($versionConcern, self::MAX_MYSQL, '>')) { |
|
| 79 | - return SetupResult::warning( |
|
| 80 | - $this->l10n->t( |
|
| 81 | - 'MySQL version "%1$s" detected. MySQL >=%2$s and <=%3$s is suggested for best performance, stability and functionality with this version of Nextcloud.', |
|
| 82 | - [ |
|
| 83 | - $version, |
|
| 84 | - self::MIN_MYSQL, |
|
| 85 | - self::MAX_MYSQL, |
|
| 86 | - ], |
|
| 87 | - ), |
|
| 88 | - ); |
|
| 89 | - } |
|
| 90 | - } |
|
| 91 | - } elseif ($databasePlatform === IDBConnection::PLATFORM_POSTGRES) { |
|
| 92 | - $statement = $this->connection->prepare('SHOW server_version;'); |
|
| 93 | - $result = $statement->execute(); |
|
| 94 | - $row = $result->fetchAssociative(); |
|
| 95 | - $version = $row['server_version']; |
|
| 96 | - $versionlc = strtolower($version); |
|
| 97 | - // we only care about X not X.Y or X.Y.Z differences |
|
| 98 | - [$major, ] = explode('.', $versionlc); |
|
| 99 | - $versionConcern = $major; |
|
| 100 | - if (version_compare($versionConcern, self::MIN_POSTGRES, '<') || version_compare($versionConcern, self::MAX_POSTGRES, '>')) { |
|
| 101 | - return SetupResult::warning( |
|
| 102 | - $this->l10n->t( |
|
| 103 | - 'PostgreSQL version "%1$s" detected. PostgreSQL >=%2$s and <=%3$s is suggested for best performance, stability and functionality with this version of Nextcloud.', |
|
| 104 | - [ |
|
| 105 | - $version, |
|
| 106 | - self::MIN_POSTGRES, |
|
| 107 | - self::MAX_POSTGRES, |
|
| 108 | - ]) |
|
| 109 | - ); |
|
| 110 | - } |
|
| 111 | - } elseif ($databasePlatform === IDBConnection::PLATFORM_ORACLE) { |
|
| 112 | - $result = $this->connection->executeQuery('SELECT VERSION FROM PRODUCT_COMPONENT_VERSION'); |
|
| 113 | - $version = $result->fetchOne(); |
|
| 114 | - $result->closeCursor(); |
|
| 115 | - $versionLower = strtolower($version); |
|
| 116 | - // we only care about X.Y not X.Y.Z differences |
|
| 117 | - [$major, $minor, ] = explode('.', $versionLower); |
|
| 118 | - $versionConcern = $major . '.' . $minor; |
|
| 119 | - if (version_compare($versionConcern, self::MIN_ORACLE, '<') || version_compare($versionConcern, self::MAX_ORACLE, '>')) { |
|
| 120 | - $extendedWarning = ''; |
|
| 121 | - if (version_compare($versionConcern, self::MIN_ORACLE, '<')) { |
|
| 122 | - $extendedWarning = "\n" . $this->l10n->t('Nextcloud %d does not support your current version, so be sure to update the database before updating your Nextcloud Server.', [33]); |
|
| 123 | - } |
|
| 124 | - return SetupResult::warning( |
|
| 125 | - $this->l10n->t( |
|
| 126 | - 'Oracle version "%1$s" detected. Oracle >=%2$s and <=%3$s is suggested for best performance, stability and functionality with this version of Nextcloud.', |
|
| 127 | - [ |
|
| 128 | - $version, |
|
| 129 | - self::MIN_ORACLE, |
|
| 130 | - self::MAX_ORACLE, |
|
| 131 | - ]) |
|
| 132 | - . $extendedWarning |
|
| 133 | - ); |
|
| 134 | - } |
|
| 135 | - } elseif ($databasePlatform === IDBConnection::PLATFORM_SQLITE) { |
|
| 136 | - return SetupResult::warning( |
|
| 137 | - $this->l10n->t('SQLite is currently being used as the backend database. For larger installations we recommend that you switch to a different database backend. This is particularly recommended when using the desktop client for file synchronisation. To migrate to another database use the command line tool: "occ db:convert-type".'), |
|
| 138 | - $this->urlGenerator->linkToDocs('admin-db-conversion') |
|
| 139 | - ); |
|
| 140 | - } else { |
|
| 141 | - return SetupResult::error($this->l10n->t('Unknown database platform')); |
|
| 142 | - } |
|
| 143 | - return SetupResult::success($version); |
|
| 144 | - } |
|
| 43 | + public function run(): SetupResult { |
|
| 44 | + $databasePlatform = $this->connection->getDatabaseProvider(); |
|
| 45 | + if ($databasePlatform === IDBConnection::PLATFORM_MYSQL || $databasePlatform === IDBConnection::PLATFORM_MARIADB) { |
|
| 46 | + $statement = $this->connection->prepare("SHOW VARIABLES LIKE 'version';"); |
|
| 47 | + $result = $statement->execute(); |
|
| 48 | + $row = $result->fetchAssociative(); |
|
| 49 | + $version = $row['Value']; |
|
| 50 | + $versionlc = strtolower($version); |
|
| 51 | + // we only care about X.Y not X.Y.Z differences |
|
| 52 | + [$major, $minor, ] = explode('.', $versionlc); |
|
| 53 | + $versionConcern = $major . '.' . $minor; |
|
| 54 | + if (str_contains($versionlc, 'mariadb')) { |
|
| 55 | + if (version_compare($versionConcern, '10.3', '=')) { |
|
| 56 | + return SetupResult::info( |
|
| 57 | + $this->l10n->t( |
|
| 58 | + 'MariaDB version 10.3 detected, this version is end-of-life and only supported as part of Ubuntu 20.04. MariaDB >=%1$s and <=%2$s is suggested for best performance, stability and functionality with this version of Nextcloud.', |
|
| 59 | + [ |
|
| 60 | + self::MIN_MARIADB, |
|
| 61 | + self::MAX_MARIADB, |
|
| 62 | + ] |
|
| 63 | + ), |
|
| 64 | + ); |
|
| 65 | + } elseif (version_compare($versionConcern, self::MIN_MARIADB, '<') || version_compare($versionConcern, self::MAX_MARIADB, '>')) { |
|
| 66 | + return SetupResult::warning( |
|
| 67 | + $this->l10n->t( |
|
| 68 | + 'MariaDB version "%1$s" detected. MariaDB >=%2$s and <=%3$s is suggested for best performance, stability and functionality with this version of Nextcloud.', |
|
| 69 | + [ |
|
| 70 | + $version, |
|
| 71 | + self::MIN_MARIADB, |
|
| 72 | + self::MAX_MARIADB, |
|
| 73 | + ], |
|
| 74 | + ), |
|
| 75 | + ); |
|
| 76 | + } |
|
| 77 | + } else { |
|
| 78 | + if (version_compare($versionConcern, self::MIN_MYSQL, '<') || version_compare($versionConcern, self::MAX_MYSQL, '>')) { |
|
| 79 | + return SetupResult::warning( |
|
| 80 | + $this->l10n->t( |
|
| 81 | + 'MySQL version "%1$s" detected. MySQL >=%2$s and <=%3$s is suggested for best performance, stability and functionality with this version of Nextcloud.', |
|
| 82 | + [ |
|
| 83 | + $version, |
|
| 84 | + self::MIN_MYSQL, |
|
| 85 | + self::MAX_MYSQL, |
|
| 86 | + ], |
|
| 87 | + ), |
|
| 88 | + ); |
|
| 89 | + } |
|
| 90 | + } |
|
| 91 | + } elseif ($databasePlatform === IDBConnection::PLATFORM_POSTGRES) { |
|
| 92 | + $statement = $this->connection->prepare('SHOW server_version;'); |
|
| 93 | + $result = $statement->execute(); |
|
| 94 | + $row = $result->fetchAssociative(); |
|
| 95 | + $version = $row['server_version']; |
|
| 96 | + $versionlc = strtolower($version); |
|
| 97 | + // we only care about X not X.Y or X.Y.Z differences |
|
| 98 | + [$major, ] = explode('.', $versionlc); |
|
| 99 | + $versionConcern = $major; |
|
| 100 | + if (version_compare($versionConcern, self::MIN_POSTGRES, '<') || version_compare($versionConcern, self::MAX_POSTGRES, '>')) { |
|
| 101 | + return SetupResult::warning( |
|
| 102 | + $this->l10n->t( |
|
| 103 | + 'PostgreSQL version "%1$s" detected. PostgreSQL >=%2$s and <=%3$s is suggested for best performance, stability and functionality with this version of Nextcloud.', |
|
| 104 | + [ |
|
| 105 | + $version, |
|
| 106 | + self::MIN_POSTGRES, |
|
| 107 | + self::MAX_POSTGRES, |
|
| 108 | + ]) |
|
| 109 | + ); |
|
| 110 | + } |
|
| 111 | + } elseif ($databasePlatform === IDBConnection::PLATFORM_ORACLE) { |
|
| 112 | + $result = $this->connection->executeQuery('SELECT VERSION FROM PRODUCT_COMPONENT_VERSION'); |
|
| 113 | + $version = $result->fetchOne(); |
|
| 114 | + $result->closeCursor(); |
|
| 115 | + $versionLower = strtolower($version); |
|
| 116 | + // we only care about X.Y not X.Y.Z differences |
|
| 117 | + [$major, $minor, ] = explode('.', $versionLower); |
|
| 118 | + $versionConcern = $major . '.' . $minor; |
|
| 119 | + if (version_compare($versionConcern, self::MIN_ORACLE, '<') || version_compare($versionConcern, self::MAX_ORACLE, '>')) { |
|
| 120 | + $extendedWarning = ''; |
|
| 121 | + if (version_compare($versionConcern, self::MIN_ORACLE, '<')) { |
|
| 122 | + $extendedWarning = "\n" . $this->l10n->t('Nextcloud %d does not support your current version, so be sure to update the database before updating your Nextcloud Server.', [33]); |
|
| 123 | + } |
|
| 124 | + return SetupResult::warning( |
|
| 125 | + $this->l10n->t( |
|
| 126 | + 'Oracle version "%1$s" detected. Oracle >=%2$s and <=%3$s is suggested for best performance, stability and functionality with this version of Nextcloud.', |
|
| 127 | + [ |
|
| 128 | + $version, |
|
| 129 | + self::MIN_ORACLE, |
|
| 130 | + self::MAX_ORACLE, |
|
| 131 | + ]) |
|
| 132 | + . $extendedWarning |
|
| 133 | + ); |
|
| 134 | + } |
|
| 135 | + } elseif ($databasePlatform === IDBConnection::PLATFORM_SQLITE) { |
|
| 136 | + return SetupResult::warning( |
|
| 137 | + $this->l10n->t('SQLite is currently being used as the backend database. For larger installations we recommend that you switch to a different database backend. This is particularly recommended when using the desktop client for file synchronisation. To migrate to another database use the command line tool: "occ db:convert-type".'), |
|
| 138 | + $this->urlGenerator->linkToDocs('admin-db-conversion') |
|
| 139 | + ); |
|
| 140 | + } else { |
|
| 141 | + return SetupResult::error($this->l10n->t('Unknown database platform')); |
|
| 142 | + } |
|
| 143 | + return SetupResult::success($version); |
|
| 144 | + } |
|
| 145 | 145 | } |
@@ -50,7 +50,7 @@ discard block |
||
| 50 | 50 | $versionlc = strtolower($version); |
| 51 | 51 | // we only care about X.Y not X.Y.Z differences |
| 52 | 52 | [$major, $minor, ] = explode('.', $versionlc); |
| 53 | - $versionConcern = $major . '.' . $minor; |
|
| 53 | + $versionConcern = $major.'.'.$minor; |
|
| 54 | 54 | if (str_contains($versionlc, 'mariadb')) { |
| 55 | 55 | if (version_compare($versionConcern, '10.3', '=')) { |
| 56 | 56 | return SetupResult::info( |
@@ -115,11 +115,11 @@ discard block |
||
| 115 | 115 | $versionLower = strtolower($version); |
| 116 | 116 | // we only care about X.Y not X.Y.Z differences |
| 117 | 117 | [$major, $minor, ] = explode('.', $versionLower); |
| 118 | - $versionConcern = $major . '.' . $minor; |
|
| 118 | + $versionConcern = $major.'.'.$minor; |
|
| 119 | 119 | if (version_compare($versionConcern, self::MIN_ORACLE, '<') || version_compare($versionConcern, self::MAX_ORACLE, '>')) { |
| 120 | 120 | $extendedWarning = ''; |
| 121 | 121 | if (version_compare($versionConcern, self::MIN_ORACLE, '<')) { |
| 122 | - $extendedWarning = "\n" . $this->l10n->t('Nextcloud %d does not support your current version, so be sure to update the database before updating your Nextcloud Server.', [33]); |
|
| 122 | + $extendedWarning = "\n".$this->l10n->t('Nextcloud %d does not support your current version, so be sure to update the database before updating your Nextcloud Server.', [33]); |
|
| 123 | 123 | } |
| 124 | 124 | return SetupResult::warning( |
| 125 | 125 | $this->l10n->t( |