mirror of
https://github.com/nextcloud/server.git
synced 2024-08-14 14:10:40 +02:00
caff1023ea
To continue this formatting madness, here's a tiny patch that adds unified formatting for control structures like if and loops as well as classes, their methods and anonymous functions. This basically forces the constructs to start on the same line. This is not exactly what PSR2 wants, but I think we can have a few exceptions with "our" style. The starting of braces on the same line is pracrically standard for our code. This also removes and empty lines from method/function bodies at the beginning and end. Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
351 lines
9.5 KiB
PHP
351 lines
9.5 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
|
|
* This file is licensed under the Affero General Public License version 3 or
|
|
* later.
|
|
* See the COPYING-README file.
|
|
*/
|
|
|
|
namespace Test\DB;
|
|
|
|
use Doctrine\DBAL\Platforms\SqlitePlatform;
|
|
use OC\DB\MDB2SchemaManager;
|
|
use OCP\DB\QueryBuilder\IQueryBuilder;
|
|
|
|
/**
|
|
* Class Connection
|
|
*
|
|
* @group DB
|
|
*
|
|
* @package Test\DB
|
|
*/
|
|
class ConnectionTest extends \Test\TestCase {
|
|
/**
|
|
* @var \OCP\IDBConnection
|
|
*/
|
|
private $connection;
|
|
|
|
public static function setUpBeforeClass(): void {
|
|
self::dropTestTable();
|
|
parent::setUpBeforeClass();
|
|
}
|
|
|
|
public static function tearDownAfterClass(): void {
|
|
self::dropTestTable();
|
|
parent::tearDownAfterClass();
|
|
}
|
|
|
|
protected static function dropTestTable() {
|
|
if (\OC::$server->getConfig()->getSystemValue('dbtype', 'sqlite') !== 'oci') {
|
|
\OC::$server->getDatabaseConnection()->dropTable('table');
|
|
}
|
|
}
|
|
|
|
protected function setUp(): void {
|
|
parent::setUp();
|
|
$this->connection = \OC::$server->getDatabaseConnection();
|
|
}
|
|
|
|
protected function tearDown(): void {
|
|
parent::tearDown();
|
|
$this->connection->dropTable('table');
|
|
}
|
|
|
|
/**
|
|
* @param string $table
|
|
*/
|
|
public function assertTableExist($table) {
|
|
if ($this->connection->getDatabasePlatform() instanceof SqlitePlatform) {
|
|
// sqlite removes the tables after closing the DB
|
|
$this->addToAssertionCount(1);
|
|
} else {
|
|
$this->assertTrue($this->connection->tableExists($table), 'Table ' . $table . ' exists.');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param string $table
|
|
*/
|
|
public function assertTableNotExist($table) {
|
|
if ($this->connection->getDatabasePlatform() instanceof SqlitePlatform) {
|
|
// sqlite removes the tables after closing the DB
|
|
$this->addToAssertionCount(1);
|
|
} else {
|
|
$this->assertFalse($this->connection->tableExists($table), 'Table ' . $table . " doesn't exist.");
|
|
}
|
|
}
|
|
|
|
private function makeTestTable() {
|
|
$schemaManager = new MDB2SchemaManager($this->connection);
|
|
$schemaManager->createDbFromStructure(__DIR__ . '/testschema.xml');
|
|
}
|
|
|
|
public function testTableExists() {
|
|
$this->assertTableNotExist('table');
|
|
$this->makeTestTable();
|
|
$this->assertTableExist('table');
|
|
}
|
|
|
|
/**
|
|
* @depends testTableExists
|
|
*/
|
|
public function testDropTable() {
|
|
$this->makeTestTable();
|
|
$this->assertTableExist('table');
|
|
$this->connection->dropTable('table');
|
|
$this->assertTableNotExist('table');
|
|
}
|
|
|
|
private function getTextValueByIntergerField($integerField) {
|
|
$builder = $this->connection->getQueryBuilder();
|
|
$query = $builder->select('textfield')
|
|
->from('table')
|
|
->where($builder->expr()->eq('integerfield', $builder->createNamedParameter($integerField, IQueryBuilder::PARAM_INT)));
|
|
|
|
$result = $query->execute();
|
|
return $result->fetchColumn();
|
|
}
|
|
|
|
public function testSetValues() {
|
|
$this->makeTestTable();
|
|
$this->connection->setValues('table', [
|
|
'integerfield' => 1
|
|
], [
|
|
'textfield' => 'foo',
|
|
'clobfield' => 'not_null'
|
|
]);
|
|
|
|
$this->assertEquals('foo', $this->getTextValueByIntergerField(1));
|
|
}
|
|
|
|
public function testSetValuesOverWrite() {
|
|
$this->makeTestTable();
|
|
$this->connection->setValues('table', [
|
|
'integerfield' => 1
|
|
], [
|
|
'textfield' => 'foo'
|
|
]);
|
|
|
|
$this->connection->setValues('table', [
|
|
'integerfield' => 1
|
|
], [
|
|
'textfield' => 'bar'
|
|
]);
|
|
|
|
$this->assertEquals('bar', $this->getTextValueByIntergerField(1));
|
|
}
|
|
|
|
public function testSetValuesOverWritePrecondition() {
|
|
$this->makeTestTable();
|
|
$this->connection->setValues('table', [
|
|
'integerfield' => 1
|
|
], [
|
|
'textfield' => 'foo',
|
|
'booleanfield' => true,
|
|
'clobfield' => 'not_null'
|
|
]);
|
|
|
|
$this->connection->setValues('table', [
|
|
'integerfield' => 1
|
|
], [
|
|
'textfield' => 'bar'
|
|
], [
|
|
'booleanfield' => true
|
|
]);
|
|
|
|
$this->assertEquals('bar', $this->getTextValueByIntergerField(1));
|
|
}
|
|
|
|
|
|
public function testSetValuesOverWritePreconditionFailed() {
|
|
$this->expectException(\OCP\PreConditionNotMetException::class);
|
|
|
|
$this->makeTestTable();
|
|
$this->connection->setValues('table', [
|
|
'integerfield' => 1
|
|
], [
|
|
'textfield' => 'foo',
|
|
'booleanfield' => true,
|
|
'clobfield' => 'not_null'
|
|
]);
|
|
|
|
$this->connection->setValues('table', [
|
|
'integerfield' => 1
|
|
], [
|
|
'textfield' => 'bar'
|
|
], [
|
|
'booleanfield' => false
|
|
]);
|
|
}
|
|
|
|
public function testSetValuesSameNoError() {
|
|
$this->makeTestTable();
|
|
$this->connection->setValues('table', [
|
|
'integerfield' => 1
|
|
], [
|
|
'textfield' => 'foo',
|
|
'clobfield' => 'not_null'
|
|
]);
|
|
|
|
// this will result in 'no affected rows' on certain optimizing DBs
|
|
// ensure the PreConditionNotMetException isn't thrown
|
|
$this->connection->setValues('table', [
|
|
'integerfield' => 1
|
|
], [
|
|
'textfield' => 'foo'
|
|
]);
|
|
|
|
$this->addToAssertionCount(1);
|
|
}
|
|
|
|
public function testInsertIfNotExist() {
|
|
$this->makeTestTable();
|
|
$categoryEntries = [
|
|
['user' => 'test', 'category' => 'Family', 'expectedResult' => 1],
|
|
['user' => 'test', 'category' => 'Friends', 'expectedResult' => 1],
|
|
['user' => 'test', 'category' => 'Coworkers', 'expectedResult' => 1],
|
|
['user' => 'test', 'category' => 'Coworkers', 'expectedResult' => 0],
|
|
['user' => 'test', 'category' => 'School', 'expectedResult' => 1],
|
|
['user' => 'test2', 'category' => 'Coworkers2', 'expectedResult' => 1],
|
|
['user' => 'test2', 'category' => 'Coworkers2', 'expectedResult' => 0],
|
|
['user' => 'test2', 'category' => 'School2', 'expectedResult' => 1],
|
|
['user' => 'test2', 'category' => 'Coworkers', 'expectedResult' => 1],
|
|
];
|
|
|
|
foreach ($categoryEntries as $entry) {
|
|
$result = $this->connection->insertIfNotExist('*PREFIX*table',
|
|
[
|
|
'textfield' => $entry['user'],
|
|
'clobfield' => $entry['category'],
|
|
]);
|
|
$this->assertEquals($entry['expectedResult'], $result);
|
|
}
|
|
|
|
$query = $this->connection->prepare('SELECT * FROM `*PREFIX*table`');
|
|
$result = $query->execute();
|
|
$this->assertTrue((bool)$result);
|
|
$this->assertEquals(7, count($query->fetchAll()));
|
|
}
|
|
|
|
public function testInsertIfNotExistNull() {
|
|
$this->makeTestTable();
|
|
$categoryEntries = [
|
|
['addressbookid' => 123, 'fullname' => null, 'expectedResult' => 1],
|
|
['addressbookid' => 123, 'fullname' => null, 'expectedResult' => 0],
|
|
['addressbookid' => 123, 'fullname' => 'test', 'expectedResult' => 1],
|
|
];
|
|
|
|
foreach ($categoryEntries as $entry) {
|
|
$result = $this->connection->insertIfNotExist('*PREFIX*table',
|
|
[
|
|
'integerfield_default' => $entry['addressbookid'],
|
|
'clobfield' => $entry['fullname'],
|
|
]);
|
|
$this->assertEquals($entry['expectedResult'], $result);
|
|
}
|
|
|
|
$query = $this->connection->prepare('SELECT * FROM `*PREFIX*table`');
|
|
$result = $query->execute();
|
|
$this->assertTrue((bool)$result);
|
|
$this->assertEquals(2, count($query->fetchAll()));
|
|
}
|
|
|
|
public function testInsertIfNotExistDonTOverwrite() {
|
|
$this->makeTestTable();
|
|
$fullName = 'fullname test';
|
|
$uri = 'uri_1';
|
|
|
|
// Normal test to have same known data inserted.
|
|
$query = $this->connection->prepare('INSERT INTO `*PREFIX*table` (`textfield`, `clobfield`) VALUES (?, ?)');
|
|
$result = $query->execute([$fullName, $uri]);
|
|
$this->assertEquals(1, $result);
|
|
$query = $this->connection->prepare('SELECT `textfield`, `clobfield` FROM `*PREFIX*table` WHERE `clobfield` = ?');
|
|
$result = $query->execute([$uri]);
|
|
$this->assertTrue($result);
|
|
$rowset = $query->fetchAll();
|
|
$this->assertEquals(1, count($rowset));
|
|
$this->assertArrayHasKey('textfield', $rowset[0]);
|
|
$this->assertEquals($fullName, $rowset[0]['textfield']);
|
|
|
|
// Try to insert a new row
|
|
$result = $this->connection->insertIfNotExist('*PREFIX*table',
|
|
[
|
|
'textfield' => $fullName,
|
|
'clobfield' => $uri,
|
|
]);
|
|
$this->assertEquals(0, $result);
|
|
|
|
$query = $this->connection->prepare('SELECT `textfield`, `clobfield` FROM `*PREFIX*table` WHERE `clobfield` = ?');
|
|
$result = $query->execute([$uri]);
|
|
$this->assertTrue($result);
|
|
// Test that previously inserted data isn't overwritten
|
|
// And that a new row hasn't been inserted.
|
|
$rowset = $query->fetchAll();
|
|
$this->assertEquals(1, count($rowset));
|
|
$this->assertArrayHasKey('textfield', $rowset[0]);
|
|
$this->assertEquals($fullName, $rowset[0]['textfield']);
|
|
}
|
|
|
|
public function testInsertIfNotExistsViolating() {
|
|
$this->makeTestTable();
|
|
$result = $this->connection->insertIfNotExist('*PREFIX*table',
|
|
[
|
|
'textfield' => md5('welcome.txt'),
|
|
'clobfield' => $this->getUniqueID()
|
|
]);
|
|
$this->assertEquals(1, $result);
|
|
|
|
$result = $this->connection->insertIfNotExist('*PREFIX*table',
|
|
[
|
|
'textfield' => md5('welcome.txt'),
|
|
'clobfield' => $this->getUniqueID()
|
|
],['textfield']);
|
|
|
|
$this->assertEquals(0, $result);
|
|
}
|
|
|
|
public function insertIfNotExistsViolatingThrows() {
|
|
return [
|
|
[null],
|
|
[['clobfield']],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @dataProvider insertIfNotExistsViolatingThrows
|
|
*
|
|
* @param array $compareKeys
|
|
*/
|
|
public function testInsertIfNotExistsViolatingUnique($compareKeys) {
|
|
$this->makeTestTable();
|
|
$result = $this->connection->insertIfNotExist('*PREFIX*table',
|
|
[
|
|
'integerfield' => 1,
|
|
'clobfield' => $this->getUniqueID()
|
|
]);
|
|
$this->assertEquals(1, $result);
|
|
|
|
$result = $this->connection->insertIfNotExist('*PREFIX*table',
|
|
[
|
|
'integerfield' => 1,
|
|
'clobfield' => $this->getUniqueID()
|
|
], $compareKeys);
|
|
|
|
$this->assertEquals(0, $result);
|
|
}
|
|
|
|
|
|
public function testUniqueConstraintViolating() {
|
|
$this->expectException(\Doctrine\DBAL\Exception\UniqueConstraintViolationException::class);
|
|
|
|
$this->makeTestTable();
|
|
|
|
$testQuery = 'INSERT INTO `*PREFIX*table` (`integerfield`, `textfield`) VALUES(?, ?)';
|
|
$testParams = [1, 'hello'];
|
|
|
|
$this->connection->executeUpdate($testQuery, $testParams);
|
|
$this->connection->executeUpdate($testQuery, $testParams);
|
|
}
|
|
}
|