diff --git a/.travis.yml b/.travis.yml index c4db11eb4..3c2fc667e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -89,7 +89,7 @@ script: # Run server's app code checker # TODO: enable once table renames are possible - # - php ../../occ app:check-code mail + - php ../../occ app:check-code mail # Run JS tests - sh -c "if [ '$TEST_JS' = 'TRUE' ]; then grunt; fi" diff --git a/appinfo/database.xml b/appinfo/database.xml deleted file mode 100644 index 44c1e1444..000000000 --- a/appinfo/database.xml +++ /dev/null @@ -1,241 +0,0 @@ - - - *dbname* - true - false - utf8 - - *dbprefix*mail_accounts - - - id - integer - 1 - 0 - true - 4 - - - user_id - text - - true - 64 - - - name - text - - false - 64 - - - email - text - - true - 255 - - - inbound_host - text - - true - 64 - - - inbound_port - text - - true - 6 - - - inbound_ssl_mode - text - - true - 10 - - - inbound_user - text - - true - 64 - - - inbound_password - text - - true - 2048 - - - outbound_host - text - - false - 64 - - - outbound_port - text - - false - 6 - - - outbound_ssl_mode - text - - false - 10 - - - outbound_user - text - - false - 64 - - - outbound_password - text - - false - 2048 - - - - mail_userid_index - - user_id - ascending - - - -
- - *dbprefix*mail_collected_addresses - - - id - integer - 1 - 0 - true - 4 - - - user_id - text - - true - 64 - - - email - text - true - 255 - - - display_name - text - false - 255 - - - mail_collected_addr_userid_index - - user_id - ascending - - - - mail_collected_addr_email_index - - email - ascending - - - -
- - *dbprefix*mail_aliases - - - id - integer - 1 - 0 - true - 4 - - - account_id - integer - - true - 4 - - - name - text - - false - 64 - - - alias - text - true - 255 - - -
- - - *dbprefix*mail_attachments - - - id - integer - 1 - 0 - true - 4 - - - user_id - text - - true - 64 - - - file_name - text - - true - 255 - - - created_at - integer - 0 - true - 4 - - - mail_attachments_userid_index - - user_id - ascending - - - -
- -
diff --git a/appinfo/info.xml b/appinfo/info.xml index 39ec04144..2dec8e2b9 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -5,7 +5,7 @@ Mail IMAP web client Easy to use email client which connects to your mail server via IMAP and SMTP. - 0.10.0 + 0.11.0 agpl Christoph Wurst Jan-Christoph Borchardt diff --git a/doc/developer.md b/doc/developer.md index d5b5944c0..1fc7c9869 100644 --- a/doc/developer.md +++ b/doc/developer.md @@ -14,8 +14,9 @@ The nightly builds are provided by [Portknox.net](https://portknox.net) Connect to your database and run the following commands (`oc_` is the default table prefix): ```sql DELETE FROM oc_appconfig WHERE appid = 'mail'; +DELETE FROM oc_migrations WHERE app = 'mail'; DROP TABLE oc_mail_accounts; DROP TABLE oc_mail_aliases; -DROP TABLE oc_mail_collected_addresses; +DROP TABLE oc_mail_coll_addresses; DROP TABLE oc_mail_attachments; ``` \ No newline at end of file diff --git a/lib/Db/CollectedAddressMapper.php b/lib/Db/CollectedAddressMapper.php index f7e396c76..270f1cb5f 100644 --- a/lib/Db/CollectedAddressMapper.php +++ b/lib/Db/CollectedAddressMapper.php @@ -32,7 +32,7 @@ class CollectedAddressMapper extends QBMapper { * @param IDBConnection $db */ public function __construct(IDBConnection $db) { - parent::__construct($db, 'mail_collected_addresses'); + parent::__construct($db, 'mail_coll_addresses'); } /** @@ -90,7 +90,7 @@ class CollectedAddressMapper extends QBMapper { ->from($this->getTableName()) ->orderBy('id') ->setMaxResults(100); - if (!is_null($minId)) { + if ($minId !== null) { $query = $query->where($qb->expr()->gte('id', $qb->createNamedParameter($minId))); } diff --git a/lib/Migration/Version0100Date20180825194217.php b/lib/Migration/Version0100Date20180825194217.php new file mode 100644 index 000000000..33f09b3b3 --- /dev/null +++ b/lib/Migration/Version0100Date20180825194217.php @@ -0,0 +1,212 @@ + + * + * Mail + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ + +namespace OCA\Mail\Migration; + +use OCP\DB\ISchemaWrapper; +use OCP\Migration\SimpleMigrationStep; +use OCP\Migration\IOutput; + +/** + * Auto-generated migration step: Please modify to your needs! + */ +class Version0100Date20180825194217 extends SimpleMigrationStep { + + /** + * @param IOutput $output + * @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` + * @param array $options + */ + public function preSchemaChange(IOutput $output, \Closure $schemaClosure, array $options) { + } + + /** + * @param IOutput $output + * @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` + * @param array $options + * @return null|ISchemaWrapper + */ + public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options) { + /** @var ISchemaWrapper $schema */ + $schema = $schemaClosure(); + + /* + * Schema generated from database.xml but required changes for + * https://github.com/nextcloud/mail/issues/784 already applied. + */ + + if (!$schema->hasTable('mail_accounts')) { + $table = $schema->createTable('mail_accounts'); + $table->addColumn('id', 'integer', [ + 'autoincrement' => true, + 'notnull' => true, + 'length' => 4, + ]); + $table->addColumn('user_id', 'string', [ + 'notnull' => true, + 'length' => 64, + 'default' => '', + ]); + $table->addColumn('name', 'string', [ + 'notnull' => false, + 'length' => 64, + ]); + $table->addColumn('email', 'string', [ + 'notnull' => true, + 'length' => 255, + 'default' => '', + ]); + $table->addColumn('inbound_host', 'string', [ + 'notnull' => true, + 'length' => 64, + 'default' => '', + ]); + $table->addColumn('inbound_port', 'string', [ + 'notnull' => true, + 'length' => 6, + 'default' => '', + ]); + $table->addColumn('inbound_ssl_mode', 'string', [ + 'notnull' => true, + 'length' => 10, + 'default' => '', + ]); + $table->addColumn('inbound_user', 'string', [ + 'notnull' => true, + 'length' => 64, + 'default' => '', + ]); + $table->addColumn('inbound_password', 'string', [ + 'notnull' => true, + 'length' => 2048, + 'default' => '', + ]); + $table->addColumn('outbound_host', 'string', [ + 'notnull' => false, + 'length' => 64, + ]); + $table->addColumn('outbound_port', 'string', [ + 'notnull' => false, + 'length' => 6, + ]); + $table->addColumn('outbound_ssl_mode', 'string', [ + 'notnull' => false, + 'length' => 10, + ]); + $table->addColumn('outbound_user', 'string', [ + 'notnull' => false, + 'length' => 64, + ]); + $table->addColumn('outbound_password', 'string', [ + 'notnull' => false, + 'length' => 2048, + ]); + $table->setPrimaryKey(['id']); + $table->addIndex(['user_id'], 'mail_userid_index'); + } + + if (!$schema->hasTable('mail_coll_addresses')) { + $table = $schema->createTable('mail_coll_addresses'); + $table->addColumn('id', 'integer', [ + 'autoincrement' => true, + 'notnull' => true, + 'length' => 4, + ]); + $table->addColumn('user_id', 'string', [ + 'notnull' => true, + 'length' => 64, + 'default' => '', + ]); + $table->addColumn('email', 'string', [ + 'notnull' => true, + 'length' => 255, + ]); + $table->addColumn('display_name', 'string', [ + 'notnull' => false, + 'length' => 255, + ]); + $table->setPrimaryKey(['id']); + $table->addIndex(['user_id'], 'mail_coll_addr_userid_index'); + $table->addIndex(['email'], 'mail_coll_addr_email_index'); + } + + if (!$schema->hasTable('mail_aliases')) { + $table = $schema->createTable('mail_aliases'); + $table->addColumn('id', 'integer', [ + 'autoincrement' => true, + 'notnull' => true, + 'length' => 4, + ]); + $table->addColumn('account_id', 'integer', [ + 'notnull' => true, + 'length' => 4, + 'default' => 0, + ]); + $table->addColumn('name', 'string', [ + 'notnull' => false, + 'length' => 64, + ]); + $table->addColumn('alias', 'string', [ + 'notnull' => true, + 'length' => 255, + ]); + $table->setPrimaryKey(['id']); + } + + if (!$schema->hasTable('mail_attachments')) { + $table = $schema->createTable('mail_attachments'); + $table->addColumn('id', 'integer', [ + 'autoincrement' => true, + 'notnull' => true, + 'length' => 4, + ]); + $table->addColumn('user_id', 'string', [ + 'notnull' => true, + 'length' => 64, + 'default' => '', + ]); + $table->addColumn('file_name', 'string', [ + 'notnull' => true, + 'length' => 255, + 'default' => '', + ]); + $table->addColumn('created_at', 'integer', [ + 'notnull' => true, + 'length' => 4, + 'default' => 0, + ]); + $table->setPrimaryKey(['id']); + $table->addIndex(['user_id'], 'mail_attach_userid_index'); + } + + return $schema; + } + + /** + * @param IOutput $output + * @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` + * @param array $options + */ + public function postSchemaChange(IOutput $output, \Closure $schemaClosure, array $options) { + } +} diff --git a/lib/Migration/Version0110Date20180825195812.php b/lib/Migration/Version0110Date20180825195812.php new file mode 100644 index 000000000..816bff4d1 --- /dev/null +++ b/lib/Migration/Version0110Date20180825195812.php @@ -0,0 +1,74 @@ + + * + * Mail + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ + +namespace OCA\Mail\Migration; + +use OCP\DB\ISchemaWrapper; +use OCP\Migration\SimpleMigrationStep; +use OCP\Migration\IOutput; + +/** + * Auto-generated migration step: Please modify to your needs! + */ +class Version0110Date20180825195812 extends SimpleMigrationStep { + + /** + * @param IOutput $output + * @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` + * @param array $options + */ + public function preSchemaChange(IOutput $output, \Closure $schemaClosure, array $options) { + } + + /** + * @param IOutput $output + * @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` + * @param array $options + * @return null|ISchemaWrapper + * @throws \Doctrine\DBAL\Schema\SchemaException + */ + public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options) { + /** @var ISchemaWrapper $schema */ + $schema = $schemaClosure(); + + $table = $schema->getTable('mail_attachments'); + + if ($table->hasIndex('mail_attachments_userid_index')) { + $table->dropIndex('mail_attachments_userid_index'); + } + + if (!$table->hasIndex('mail_attach_userid_index')) { + $table->addIndex(['user_id'], 'mail_attach_userid_index'); + } + + return $schema; + } + + /** + * @param IOutput $output + * @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` + * @param array $options + */ + public function postSchemaChange(IOutput $output, \Closure $schemaClosure, array $options) { + } +} diff --git a/lib/Migration/Version0110Date20180825201241.php b/lib/Migration/Version0110Date20180825201241.php new file mode 100644 index 000000000..1cbb89a25 --- /dev/null +++ b/lib/Migration/Version0110Date20180825201241.php @@ -0,0 +1,110 @@ + + * + * Mail + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ + +namespace OCA\Mail\Migration; + +use OCP\DB\ISchemaWrapper; +use OCP\IDBConnection; +use OCP\Migration\SimpleMigrationStep; +use OCP\Migration\IOutput; + +/** + * Auto-generated migration step: Please modify to your needs! + */ +class Version0110Date20180825201241 extends SimpleMigrationStep { + + /** @var IDBConnection */ + protected $connection; + + /** + * @param IDBConnection $connection + */ + public function __construct(IDBConnection $connection) { + $this->connection = $connection; + } + + /** + * @param IOutput $output + * @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` + * @param array $options + */ + public function preSchemaChange(IOutput $output, \Closure $schemaClosure, array $options) { + /** @var ISchemaWrapper $schema */ + $schema = $schemaClosure(); + + if ($schema->hasTable('mail_collected_addresses')) { + $this->copyCollectedAddresses(); + } + } + + /** + * @param IOutput $output + * @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` + * @param array $options + * @return null|ISchemaWrapper + */ + public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options) { + /** @var ISchemaWrapper $schema */ + $schema = $schemaClosure(); + + if ($schema->hasTable('mail_collected_addresses')) { + $schema->dropTable('mail_collected_addresses'); + } + + return $schema; + } + + /** + * @param IOutput $output + * @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` + * @param array $options + */ + public function postSchemaChange(IOutput $output, \Closure $schemaClosure, array $options) { + } + + /** + * Copy collected addresses to new table + */ + private function copyCollectedAddresses(): void { + $query = $this->connection->getQueryBuilder(); + $query->select('*') + ->from('mail_collected_addresses'); + + $insert = $this->connection->getQueryBuilder(); + $insert->insert('mail_coll_addresses') + ->values(['id' => '?', 'user_id' => '?', 'email' => '?', 'display_name' => '?']); + + $result = $query->execute(); + + while ($row = $result->fetch()) { + $insert->setParameters([ + $row['id'], + $row['user_id'], + $row['email'], + $row['display_name'] + ])->execute(); + } + + $result->closeCursor(); + } +} diff --git a/tests/Db/CollectedAddressMapperTest.php b/tests/Db/CollectedAddressMapperTest.php index 66a06c21d..00253975d 100644 --- a/tests/Db/CollectedAddressMapperTest.php +++ b/tests/Db/CollectedAddressMapperTest.php @@ -79,8 +79,7 @@ class CollectedAddressMapperTest extends TestCase { $this->address3->setDisplayName('User 3'); $this->address3->setUserId($this->userId); - $qb = $this->db->getQueryBuilder(); - $sql = 'INSERT INTO *PREFIX*mail_collected_addresses (`email`, `display_name`, `user_id`) VALUES (?, ?, ?)'; + $sql = 'INSERT INTO *PREFIX*mail_coll_addresses (`email`, `display_name`, `user_id`) VALUES (?, ?, ?)'; $stmt = $this->db->prepare($sql); // Empty DB @@ -93,19 +92,19 @@ class CollectedAddressMapperTest extends TestCase { $this->address1->getDisplayName(), $this->address1->getUserId(), ]); - $this->address1->setId($this->db->lastInsertId('PREFIX*mail_collected_addresses')); + $this->address1->setId($this->db->lastInsertId('PREFIX*mail_coll_addresses')); $stmt->execute([ $this->address2->getEmail(), $this->address2->getDisplayName(), $this->address2->getUserId(), ]); - $this->address2->setId($this->db->lastInsertId('PREFIX*mail_collected_addresses')); + $this->address2->setId($this->db->lastInsertId('PREFIX*mail_coll_addresses')); $stmt->execute([ $this->address3->getEmail(), $this->address3->getDisplayName(), $this->address3->getUserId(), ]); - $this->address3->setId($this->db->lastInsertId('PREFIX*mail_collected_addresses')); + $this->address3->setId($this->db->lastInsertId('PREFIX*mail_coll_addresses')); } public function matchingData() { @@ -121,11 +120,11 @@ class CollectedAddressMapperTest extends TestCase { public function testFindMatching($query, $result) { $matches = $this->mapper->findMatching($this->userId, $query); - $this->assertCount(count($result), $matches); + $this->assertCount(\count($result), $matches); $i = 0; foreach ($matches as $match) { $this->assertInstanceOf('\OCA\Mail\Db\CollectedAddress', $match); - $this->assertTrue(in_array($match->getEmail(), $result)); + $this->assertContains($match->getEmail(), $result); $this->assertEquals($this->userId, $match->getUserId()); $i++; }