Final
Signed-off-by: dartcafe <github@dartcafe.de>
This commit is contained in:
Родитель
b2294b7aa7
Коммит
e33c15c41c
|
@ -37,9 +37,6 @@ class LogMapper extends QBMapper {
|
|||
parent::__construct($db, 'polls_log', Log::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Log
|
||||
*/
|
||||
public function find(int $id): Log {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
|
||||
|
@ -97,9 +94,6 @@ class LogMapper extends QBMapper {
|
|||
return $this->findEntities($qb);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Log
|
||||
*/
|
||||
public function getLastRecord(int $pollId): Log {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
|
||||
|
@ -112,10 +106,8 @@ class LogMapper extends QBMapper {
|
|||
return $this->findEntity($qb);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function removeDuplicates() {
|
||||
public function removeDuplicates($output = null): int {
|
||||
$count = 0;
|
||||
try {
|
||||
// remove duplicates from oc_polls_log
|
||||
// preserve the first entry
|
||||
|
@ -140,6 +132,7 @@ class LogMapper extends QBMapper {
|
|||
if (in_array($currentRecord, $entries2Keep)) {
|
||||
$delete->setParameter('id', $row['id']);
|
||||
$delete->execute();
|
||||
$count++;
|
||||
} else {
|
||||
$entries2Keep[] = $currentRecord;
|
||||
}
|
||||
|
@ -150,10 +143,14 @@ class LogMapper extends QBMapper {
|
|||
}
|
||||
throw $e;
|
||||
}
|
||||
|
||||
if ($output && $count) {
|
||||
$output->info('Removed ' . $count . ' duplicate records from ' . $this->getTableName());
|
||||
}
|
||||
|
||||
return $count;
|
||||
}
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
|
||||
public function deleteByUserId(string $userId): void {
|
||||
$query = $this->db->getQueryBuilder();
|
||||
$query->delete($this->getTableName())
|
||||
|
@ -164,7 +161,6 @@ class LogMapper extends QBMapper {
|
|||
|
||||
/**
|
||||
* Delete entries per timestamp
|
||||
* @return void
|
||||
*/
|
||||
public function deleteOldEntries(int $offset): void {
|
||||
$query = $this->db->getQueryBuilder();
|
||||
|
@ -177,7 +173,6 @@ class LogMapper extends QBMapper {
|
|||
|
||||
/**
|
||||
* Delete processed entries
|
||||
* @return void
|
||||
*/
|
||||
public function deleteProcessedEntries(): void {
|
||||
$query = $this->db->getQueryBuilder();
|
||||
|
|
|
@ -39,7 +39,6 @@ class OptionMapper extends QBMapper {
|
|||
|
||||
/**
|
||||
* @throws \OCP\AppFramework\Db\DoesNotExistException if not found
|
||||
* @return Option
|
||||
*/
|
||||
public function find(int $id): Option {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
|
@ -56,6 +55,7 @@ class OptionMapper extends QBMapper {
|
|||
/**
|
||||
* @throws \OCP\AppFramework\Db\DoesNotExistException if not found
|
||||
* @return Option[]
|
||||
* @psalm-return array<array-key, Option>
|
||||
*/
|
||||
public function findByPoll(int $pollId): array {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
|
@ -72,7 +72,6 @@ class OptionMapper extends QBMapper {
|
|||
|
||||
/**
|
||||
* @throws \OCP\AppFramework\Db\DoesNotExistException if not found
|
||||
* @return Option
|
||||
*/
|
||||
public function findByPollAndText(int $pollId, string $pollOptionText): Option {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
|
@ -115,7 +114,8 @@ class OptionMapper extends QBMapper {
|
|||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function removeDuplicates() {
|
||||
public function removeDuplicates($output = null): int {
|
||||
$count = 0;
|
||||
try {
|
||||
// remove duplicates from oc_polls_options
|
||||
// preserve the first entry
|
||||
|
@ -139,6 +139,7 @@ class OptionMapper extends QBMapper {
|
|||
if (in_array($currentRecord, $entries2Keep)) {
|
||||
$delete->setParameter('id', $row['id']);
|
||||
$delete->execute();
|
||||
$count++;
|
||||
} else {
|
||||
$entries2Keep[] = $currentRecord;
|
||||
}
|
||||
|
@ -149,11 +150,14 @@ class OptionMapper extends QBMapper {
|
|||
}
|
||||
throw $e;
|
||||
}
|
||||
|
||||
if ($output && $count) {
|
||||
$output->info('Removed ' . $count . ' duplicate records from ' . $this->getTableName());
|
||||
}
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function renameUserId(string $userId, string $replacementName): void {
|
||||
$query = $this->db->getQueryBuilder();
|
||||
$query->update($this->getTableName())
|
||||
|
|
|
@ -54,10 +54,8 @@ class PreferencesMapper extends QBMapper {
|
|||
return $this->findEntity($qb);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function removeDuplicates() {
|
||||
public function removeDuplicates($output = null): int {
|
||||
$count = 0;
|
||||
try {
|
||||
$query = $this->db->getQueryBuilder();
|
||||
$query->delete($this->getTableName())
|
||||
|
@ -82,6 +80,7 @@ class PreferencesMapper extends QBMapper {
|
|||
if (in_array($row['user_id'], $userskeep)) {
|
||||
$delete->setParameter('id', $row['id']);
|
||||
$delete->execute();
|
||||
$count++;
|
||||
} else {
|
||||
$userskeep[] = $row['user_id'];
|
||||
}
|
||||
|
@ -92,6 +91,12 @@ class PreferencesMapper extends QBMapper {
|
|||
}
|
||||
throw $e;
|
||||
}
|
||||
|
||||
if ($output && $count) {
|
||||
$output->info('Removed ' . $count . ' duplicate records from ' . $this->getTableName());
|
||||
}
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -40,8 +40,9 @@ class ShareMapper extends QBMapper {
|
|||
/**
|
||||
* @throws \OCP\AppFramework\Db\DoesNotExistException if not found
|
||||
* @return Share[]
|
||||
* @psalm-return array<array-key, Share>
|
||||
*/
|
||||
public function findAll() {
|
||||
public function findAll(): array {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
|
||||
$qb->select('*')
|
||||
|
@ -54,8 +55,9 @@ class ShareMapper extends QBMapper {
|
|||
/**
|
||||
* @throws \OCP\AppFramework\Db\DoesNotExistException if not found
|
||||
* @return Share[]
|
||||
* @psalm-return array<array-key, Share>
|
||||
*/
|
||||
public function findByPoll(int $pollId) {
|
||||
public function findByPoll(int $pollId): array {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
|
||||
$qb->select('*')
|
||||
|
@ -69,7 +71,6 @@ class ShareMapper extends QBMapper {
|
|||
|
||||
/**
|
||||
* @throws \OCP\AppFramework\Db\DoesNotExistException if not found
|
||||
* @return Share
|
||||
*/
|
||||
public function findByPollAndUser(int $pollId, string $userId): Share {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
|
@ -88,9 +89,8 @@ class ShareMapper extends QBMapper {
|
|||
|
||||
/**
|
||||
* @throws \OCP\AppFramework\Db\DoesNotExistException if not found
|
||||
* @return Share
|
||||
*/
|
||||
public function findByToken(string $token) {
|
||||
public function findByToken(string $token): Share {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
|
||||
$qb->select('*')
|
||||
|
@ -102,9 +102,6 @@ class ShareMapper extends QBMapper {
|
|||
return $this->findEntity($qb);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function deleteByPoll(int $pollId): void {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
|
||||
|
@ -116,9 +113,6 @@ class ShareMapper extends QBMapper {
|
|||
$qb->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function deleteByUserId(string $userId): void {
|
||||
$query = $this->db->getQueryBuilder();
|
||||
$query->delete($this->getTableName())
|
||||
|
@ -141,10 +135,8 @@ class ShareMapper extends QBMapper {
|
|||
$qb->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function removeDuplicates() {
|
||||
public function removeDuplicates($output = null): int {
|
||||
$count = 0;
|
||||
try {
|
||||
$query = $this->db->getQueryBuilder();
|
||||
// make sure, all public shares fit to the unique index added in schemaChange(),
|
||||
|
@ -177,6 +169,7 @@ class ShareMapper extends QBMapper {
|
|||
if (in_array($currentRecord, $entries2Keep) || $row['user_id'] === null || $row['type'] === '') {
|
||||
$delete->setParameter('id', $row['id']);
|
||||
$delete->execute();
|
||||
$count++;
|
||||
} else {
|
||||
$entries2Keep[] = $currentRecord;
|
||||
}
|
||||
|
@ -187,5 +180,11 @@ class ShareMapper extends QBMapper {
|
|||
}
|
||||
throw $e;
|
||||
}
|
||||
|
||||
if ($output && $count) {
|
||||
$output->info('Removed ' . $count . ' duplicate records from ' . $this->getTableName());
|
||||
}
|
||||
|
||||
return $count;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,8 +41,9 @@ class SubscriptionMapper extends QBMapper {
|
|||
* @throws \OCP\AppFramework\Db\DoesNotExistException if not found
|
||||
* @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException if more than one result
|
||||
* @return Subscription[]
|
||||
* @psalm-return array<array-key, Subscription>
|
||||
*/
|
||||
public function findAll() {
|
||||
public function findAll(): array {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
|
||||
$qb->select('*')
|
||||
|
@ -55,8 +56,9 @@ class SubscriptionMapper extends QBMapper {
|
|||
* @throws \OCP\AppFramework\Db\DoesNotExistException if not found
|
||||
* @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException if more than one result
|
||||
* @return Subscription[]
|
||||
* @psalm-return array<array-key, Subscription>
|
||||
*/
|
||||
public function findAllByPoll(int $pollId) {
|
||||
public function findAllByPoll(int $pollId): array {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
|
||||
$qb->select('*')
|
||||
|
@ -71,9 +73,8 @@ class SubscriptionMapper extends QBMapper {
|
|||
/**
|
||||
* @throws \OCP\AppFramework\Db\DoesNotExistException if not found
|
||||
* @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException if more than one result
|
||||
* @return Subscription
|
||||
*/
|
||||
public function findByPollAndUser(int $pollId, string $userId) {
|
||||
public function findByPollAndUser(int $pollId, string $userId): Subscription {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
|
||||
$qb->select('*')
|
||||
|
@ -102,10 +103,8 @@ class SubscriptionMapper extends QBMapper {
|
|||
$qb->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function removeDuplicates() {
|
||||
public function removeDuplicates($output = null): int {
|
||||
$count = 0;
|
||||
try {
|
||||
// remove duplicates from oc_polls_share
|
||||
// preserve the first entry
|
||||
|
@ -128,6 +127,7 @@ class SubscriptionMapper extends QBMapper {
|
|||
if (in_array($currentRecord, $entries2Keep)) {
|
||||
$delete->setParameter('id', $row['id']);
|
||||
$delete->execute();
|
||||
$count++;
|
||||
} else {
|
||||
$entries2Keep[] = $currentRecord;
|
||||
}
|
||||
|
@ -138,11 +138,14 @@ class SubscriptionMapper extends QBMapper {
|
|||
}
|
||||
throw $e;
|
||||
}
|
||||
|
||||
if ($output && $count) {
|
||||
$output->info('Removed ' . $count . ' duplicate records from ' . $this->getTableName());
|
||||
}
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function deleteByUserId(string $userId): void {
|
||||
$query = $this->db->getQueryBuilder();
|
||||
$query->delete($this->getTableName())
|
||||
|
|
|
@ -40,8 +40,9 @@ class VoteMapper extends QBMapper {
|
|||
/**
|
||||
* @throws \OCP\AppFramework\Db\DoesNotExistException if not found
|
||||
* @return Vote[]
|
||||
* @psalm-return array<array-key, Vote>
|
||||
*/
|
||||
public function findByPoll(int $pollId) {
|
||||
public function findByPoll(int $pollId): array {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
|
||||
$qb->select('*')
|
||||
|
@ -53,8 +54,9 @@ class VoteMapper extends QBMapper {
|
|||
/**
|
||||
* @throws \OCP\AppFramework\Db\DoesNotExistException if not found
|
||||
* @return Vote[]
|
||||
* @psalm-return array<array-key, Vote>
|
||||
*/
|
||||
public function findByPollAndUser(int $pollId, string $userId) {
|
||||
public function findByPollAndUser(int $pollId, string $userId): array {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
|
||||
$qb->select('*')
|
||||
|
@ -66,9 +68,8 @@ class VoteMapper extends QBMapper {
|
|||
|
||||
/**
|
||||
* @throws \OCP\AppFramework\Db\DoesNotExistException if not found
|
||||
* @return Vote
|
||||
*/
|
||||
public function findSingleVote(int $pollId, string $optionText, string $userId) {
|
||||
public function findSingleVote(int $pollId, string $optionText, string $userId): Vote {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
|
||||
$qb->select('*')
|
||||
|
@ -82,8 +83,9 @@ class VoteMapper extends QBMapper {
|
|||
/**
|
||||
* @throws \OCP\AppFramework\Db\DoesNotExistException if not found
|
||||
* @return Vote[]
|
||||
* @psalm-return array<array-key, Vote>
|
||||
*/
|
||||
public function findParticipantsByPoll(int $pollId) {
|
||||
public function findParticipantsByPoll(int $pollId): array {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
|
||||
$qb->selectDistinct('user_id')
|
||||
|
@ -97,9 +99,7 @@ class VoteMapper extends QBMapper {
|
|||
|
||||
/**
|
||||
* @throws \OCP\AppFramework\Db\DoesNotExistException if not found
|
||||
*
|
||||
* @return Vote[]
|
||||
*
|
||||
* @psalm-return array<array-key, Vote>
|
||||
*/
|
||||
public function findParticipantsVotes(int $pollId, string $userId): array {
|
||||
|
@ -133,6 +133,11 @@ class VoteMapper extends QBMapper {
|
|||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \OCP\AppFramework\Db\DoesNotExistException if not found
|
||||
* @return Vote[]
|
||||
* @psalm-return array<array-key, Vote>
|
||||
*/
|
||||
public function getYesVotesByParticipant(int $pollId, string $userId): array {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->select('*')
|
||||
|
@ -143,6 +148,11 @@ class VoteMapper extends QBMapper {
|
|||
return $this->findEntities($qb);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \OCP\AppFramework\Db\DoesNotExistException if not found
|
||||
* @return Vote[]
|
||||
* @psalm-return array<array-key, Vote>
|
||||
*/
|
||||
public function getYesVotesByOption(int $pollId, string $pollOptionText): array {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
|
||||
|
@ -155,10 +165,8 @@ class VoteMapper extends QBMapper {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function removeDuplicates() {
|
||||
public function removeDuplicates($output = null): int {
|
||||
$count = 0;
|
||||
try {
|
||||
$query = $this->db->getQueryBuilder();
|
||||
$query->select('id', 'poll_id', 'user_id', 'vote_option_text')
|
||||
|
@ -180,6 +188,7 @@ class VoteMapper extends QBMapper {
|
|||
if (in_array($currentRecord, $entries2Keep)) {
|
||||
$delete->setParameter('id', $row['id']);
|
||||
$delete->execute();
|
||||
$count++;
|
||||
} else {
|
||||
$entries2Keep[] = $currentRecord;
|
||||
}
|
||||
|
@ -190,11 +199,14 @@ class VoteMapper extends QBMapper {
|
|||
}
|
||||
throw $e;
|
||||
}
|
||||
|
||||
if ($output && $count) {
|
||||
$output->info('Removed ' . $count . ' duplicate records from ' . $this->getTableName());
|
||||
}
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function renameUserId(string $userId, string $replacementName): void {
|
||||
$query = $this->db->getQueryBuilder();
|
||||
$query->update($this->getTableName())
|
||||
|
|
|
@ -31,53 +31,56 @@ use OCP\Migration\IOutput;
|
|||
|
||||
class CreateIndices implements IRepairStep {
|
||||
|
||||
// private const INDICES = [
|
||||
// 'polls_options' => ['name' => 'UNIQ_options', 'unique' => true, 'columns' => ['poll_id', 'poll_option_text', 'timestamp']],
|
||||
// 'polls_log' => ['name' => 'UNIQ_unprocessed', 'unique' => true, 'columns' => ['processed', 'poll_id', 'user_id', 'message_id']],
|
||||
// 'polls_notif' => ['name' => 'UNIQ_subscription', 'unique' => true, 'columns' => ['poll_id', 'user_id']],
|
||||
// 'polls_share' => ['name' => 'UNIQ_shares', 'unique' => true, 'columns' => ['poll_id', 'user_id']],
|
||||
// 'polls_votes' => ['name' => 'UNIQ_votes', 'unique' => true, 'columns' => ['poll_id', 'user_id', 'vote_option_text']],
|
||||
// 'polls_preferences' => ['name' => 'UNIQ_preferences', 'unique' => true, 'columns' => ['user_id']],
|
||||
// 'polls_watch' => ['name' => 'UNIQ_watch', 'unique' => true, 'columns' => ['poll_id', 'table']],
|
||||
// ];
|
||||
//
|
||||
// private const PARENT_TABLE = 'polls_polls';
|
||||
//
|
||||
// private const CHILD_TABLES = [
|
||||
// 'polls_comments',
|
||||
// 'polls_log',
|
||||
// 'polls_notif',
|
||||
// 'polls_options',
|
||||
// 'polls_share',
|
||||
// 'polls_votes',
|
||||
// ];
|
||||
|
||||
/** @var Connection */
|
||||
private $connection;
|
||||
|
||||
/** @var string */
|
||||
protected $parentTable = 'polls_polls';
|
||||
|
||||
/** @var array */
|
||||
protected $childTables = [
|
||||
'polls_comments',
|
||||
'polls_log',
|
||||
'polls_notif',
|
||||
'polls_options',
|
||||
'polls_share',
|
||||
'polls_votes',
|
||||
];
|
||||
|
||||
public function __construct(Connection $connection) {
|
||||
$this->connection = $connection;
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
return 'Create polls table indices';
|
||||
return 'Polls - Create indices and foreign key constraints';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function run(IOutput $output) {
|
||||
$this->createIndex('polls_options', 'UNIQ_options', ['poll_id', 'poll_option_text', 'timestamp'], true);
|
||||
$this->createIndex('polls_log', 'UNIQ_unprocessed', ['processed', 'poll_id', 'user_id', 'message_id'], true);
|
||||
$this->createIndex('polls_notif', 'UNIQ_subscription', ['poll_id', 'user_id'], true);
|
||||
$this->createIndex('polls_share', 'UNIQ_shares', ['poll_id', 'user_id'], true);
|
||||
$this->createIndex('polls_votes', 'UNIQ_votes', ['poll_id', 'user_id', 'vote_option_text'], true);
|
||||
$this->createIndex('polls_preferences', 'UNIQ_preferences', ['user_id'], true);
|
||||
$this->createIndex('polls_watch', 'UNIQ_watch', ['poll_id', 'table'], true);
|
||||
public function run(IOutput $output): void {
|
||||
|
||||
foreach (TableSchema::UNIQUE_INDICES as $tableName => $values) {
|
||||
$this->createIndex($tableName, $values['name'], $values['columns'], $values['unique']);
|
||||
}
|
||||
$output->info('Polls - Indices created.');
|
||||
|
||||
$this->createForeignKeyConstraints();
|
||||
$output->info('Polls - Foreign key contraints created.');
|
||||
}
|
||||
|
||||
/**
|
||||
* add an on delete fk contraint to all tables referencing the main polls table
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function createForeignKeyConstraints(): void {
|
||||
$schema = new SchemaWrapper($this->connection);
|
||||
$eventTable = $schema->getTable($this->parentTable);
|
||||
foreach ($this->childTables as $tbl) {
|
||||
$eventTable = $schema->getTable(TableSchema::FK_PARENT_TABLE);
|
||||
foreach (TableSchema::FK_CHILD_TABLES as $tbl) {
|
||||
$table = $schema->getTable($tbl);
|
||||
$table->addForeignKeyConstraint($eventTable, ['poll_id'], ['id'], ['onDelete' => 'CASCADE']);
|
||||
}
|
||||
|
@ -86,8 +89,6 @@ class CreateIndices implements IRepairStep {
|
|||
|
||||
/**
|
||||
* Create index for $table
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function createIndex(string $tableName, string $indexName, array $columns, bool $unique = false): void {
|
||||
$schema = new SchemaWrapper($this->connection);
|
||||
|
|
|
@ -37,6 +37,10 @@ use OCA\Polls\Db\ShareMapper;
|
|||
use OCA\Polls\Db\SubscriptionMapper;
|
||||
use OCA\Polls\Db\VoteMapper;
|
||||
|
||||
/**
|
||||
* Preparation before migration
|
||||
* Remove all invalid records to avoid erros while adding indices ans constraints
|
||||
*/
|
||||
class DeleteInvalidRecords implements IRepairStep {
|
||||
/** @var IConfig */
|
||||
protected $config;
|
||||
|
@ -91,26 +95,18 @@ class DeleteInvalidRecords implements IRepairStep {
|
|||
$this->voteMapper = $voteMapper;
|
||||
}
|
||||
|
||||
/*
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getName() {
|
||||
return 'Delete duplicates';
|
||||
public function getName():string {
|
||||
return 'Polls - Delete duplicates and orphaned records';
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function run(IOutput $output) {
|
||||
public function run(IOutput $output):void {
|
||||
$this->removeOrphaned();
|
||||
$this->logMapper->removeDuplicates();
|
||||
$this->optionMapper->removeDuplicates();
|
||||
$this->preferencesMapper->removeDuplicates();
|
||||
$this->shareMapper->removeDuplicates();
|
||||
$this->subscriptionMapper->removeDuplicates();
|
||||
$this->voteMapper->removeDuplicates();
|
||||
$this->logMapper->removeDuplicates($output);
|
||||
$this->optionMapper->removeDuplicates($output);
|
||||
$this->preferencesMapper->removeDuplicates($output);
|
||||
$this->shareMapper->removeDuplicates($output);
|
||||
$this->subscriptionMapper->removeDuplicates($output);
|
||||
$this->voteMapper->removeDuplicates($output);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -119,10 +115,8 @@ class DeleteInvalidRecords implements IRepairStep {
|
|||
*
|
||||
* we have to use a raw query, because NOT EXISTS is not
|
||||
* part of doctrine's expression builder
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function removeOrphaned() {
|
||||
private function removeOrphaned():void {
|
||||
// polls 1.4 -> introduced contraints
|
||||
// Version0104Date20200205104800
|
||||
// get table prefix, as we are running a raw query
|
||||
|
|
|
@ -28,54 +28,40 @@ use OC\DB\SchemaWrapper;
|
|||
use OCP\Migration\IRepairStep;
|
||||
use OCP\Migration\IOutput;
|
||||
|
||||
/**
|
||||
* Preparation before migration
|
||||
* Remove all indices and foreign key constraints to avoid errors
|
||||
* while changing the schema
|
||||
*/
|
||||
class RemoveIndices implements IRepairStep {
|
||||
|
||||
/** @var Connection */
|
||||
private $connection;
|
||||
|
||||
protected $childTables = [
|
||||
'polls_comments',
|
||||
'polls_log',
|
||||
'polls_notif',
|
||||
'polls_options',
|
||||
'polls_share',
|
||||
'polls_votes',
|
||||
];
|
||||
|
||||
protected $uniqueTables = [
|
||||
'polls_log',
|
||||
'polls_notif',
|
||||
'polls_options',
|
||||
'polls_preferences',
|
||||
'polls_share',
|
||||
'polls_votes',
|
||||
];
|
||||
|
||||
public function __construct(Connection $connection) {
|
||||
$this->connection = $connection;
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
return 'Remove polls table indices';
|
||||
return 'Polls - Remove indices and foreign key constraints';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function run(IOutput $output) {
|
||||
foreach ($this->childTables as $tableName) {
|
||||
public function run(IOutput $output): void {
|
||||
foreach (TableSchema::FK_CHILD_TABLES as $tableName) {
|
||||
// $output->info('"polls" - Removing foreign keys from '. $tableName);
|
||||
$this->removeForeignKeys($tableName);
|
||||
// $output->info('"polls" - Removing indices in '. $tableName);
|
||||
$this->removeGenericIndices($tableName);
|
||||
}
|
||||
|
||||
foreach ($this->uniqueTables as $tableName) {
|
||||
foreach (TableSchema::UNIQUE_INDICES as $tableName => $value) {
|
||||
// $output->info('"polls" - Removing unique indices in '. $tableName);
|
||||
$this->removeUniqueIndices($tableName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* remove a foreign key with $foreignKeyName from $tableName
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function removeForeignKey(string $tableName, string $foreignKeyName): void {
|
||||
$schema = new SchemaWrapper($this->connection);
|
||||
|
@ -88,8 +74,6 @@ class RemoveIndices implements IRepairStep {
|
|||
|
||||
/**
|
||||
* remove an index with $indexName from $tableName
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function removeIndex(string $tableName, string $indexName): void {
|
||||
$schema = new SchemaWrapper($this->connection);
|
||||
|
@ -104,8 +88,6 @@ class RemoveIndices implements IRepairStep {
|
|||
|
||||
/**
|
||||
* remove all UNIQUE indices from $table
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function removeUniqueIndices(string $tableName): void {
|
||||
$schema = new SchemaWrapper($this->connection);
|
||||
|
@ -121,8 +103,6 @@ class RemoveIndices implements IRepairStep {
|
|||
|
||||
/**
|
||||
* remove all UNIQUE indices from $table
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function removeGenericIndices(string $tableName): void {
|
||||
$schema = new SchemaWrapper($this->connection);
|
||||
|
@ -138,8 +118,6 @@ class RemoveIndices implements IRepairStep {
|
|||
|
||||
/**
|
||||
* remove all foreign keys from $tableName
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function removeForeignKeys(string $tableName): void {
|
||||
$schema = new SchemaWrapper($this->connection);
|
||||
|
|
|
@ -0,0 +1,363 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2017 René Gieling <github@dartcafe.de>
|
||||
*
|
||||
* @author René Gieling <github@dartcafe.de>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Polls\Migration;
|
||||
|
||||
use OCP\IDBConnection;
|
||||
use OCP\DB\Types;
|
||||
use OCP\DB\ISchemaWrapper;
|
||||
use OCP\Migration\IOutput;
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
|
||||
|
||||
/**
|
||||
* Database definition for installing and migrations
|
||||
*
|
||||
* These definitions contain the base database layout
|
||||
*
|
||||
* used for initial migration to version 3.x from all prior versoins
|
||||
*/
|
||||
|
||||
Abstract class TableSchema {
|
||||
|
||||
public const FK_PARENT_TABLE = 'polls_polls';
|
||||
|
||||
public const FK_CHILD_TABLES = [
|
||||
'polls_comments',
|
||||
'polls_log',
|
||||
'polls_notif',
|
||||
'polls_options',
|
||||
'polls_share',
|
||||
'polls_votes',
|
||||
];
|
||||
|
||||
public const UNIQUE_TABLES = [
|
||||
'polls_log',
|
||||
'polls_notif',
|
||||
'polls_options',
|
||||
'polls_preferences',
|
||||
'polls_share',
|
||||
'polls_votes',
|
||||
];
|
||||
|
||||
public const UNIQUE_INDICES = [
|
||||
'polls_options' => ['name' => 'UNIQ_options', 'unique' => true, 'columns' => ['poll_id', 'poll_option_text', 'timestamp']],
|
||||
'polls_log' => ['name' => 'UNIQ_unprocessed', 'unique' => true, 'columns' => ['processed', 'poll_id', 'user_id', 'message_id']],
|
||||
'polls_notif' => ['name' => 'UNIQ_subscription', 'unique' => true, 'columns' => ['poll_id', 'user_id']],
|
||||
'polls_share' => ['name' => 'UNIQ_shares', 'unique' => true, 'columns' => ['poll_id', 'user_id']],
|
||||
'polls_votes' => ['name' => 'UNIQ_votes', 'unique' => true, 'columns' => ['poll_id', 'user_id', 'vote_option_text']],
|
||||
'polls_preferences' => ['name' => 'UNIQ_preferences', 'unique' => true, 'columns' => ['user_id']],
|
||||
'polls_watch' => ['name' => 'UNIQ_watch', 'unique' => true, 'columns' => ['poll_id', 'table']],
|
||||
];
|
||||
|
||||
/**
|
||||
* obsolete migration entries, which can be deleted
|
||||
*/
|
||||
public const GONE_MIGRATIONS = [
|
||||
'0001Date20000101120000',
|
||||
'0001Date20000101120001',
|
||||
'0009Date20181125051900',
|
||||
'0009Date20181125061900',
|
||||
'0009Date20181125062101',
|
||||
'0010Date20191227063812',
|
||||
'0010Date20200119101800',
|
||||
'0101Date20200122194300',
|
||||
'0103Date20200130171244',
|
||||
'0104Date20200205104800',
|
||||
'0104Date20200314074611',
|
||||
'0105Date20200508211943',
|
||||
'0105Date20200523142076',
|
||||
'0105Date20200704084037',
|
||||
'0105Date20200903172733',
|
||||
'0106Date20201031080745',
|
||||
'0106Date20201031080946',
|
||||
'0107Date20201210204702',
|
||||
'0107Date20201210213303',
|
||||
'0107Date20201217071304',
|
||||
'0107Date20210101161105',
|
||||
'0107Date20210104135506',
|
||||
'0107Date20210121220707',
|
||||
'0108Date20210117010101',
|
||||
'0108Date20210127135802',
|
||||
'0108Date20210207134703',
|
||||
'0108Date20210307130001',
|
||||
'0108Date20210307130003',
|
||||
'0108Date20210307130009',
|
||||
'0109Date20210323120002',
|
||||
];
|
||||
|
||||
/**
|
||||
* define obsolete tables, which do get migrated as an array of table names
|
||||
*/
|
||||
public const GONE_TABLES = [
|
||||
'polls_events',
|
||||
'polls_dts',
|
||||
'polls_txts',
|
||||
'polls_particip',
|
||||
'polls_particip_text',
|
||||
'polls_test',
|
||||
];
|
||||
|
||||
/** define obsolete columns, which do get migrated
|
||||
* Format:
|
||||
* public const GONE_COLUMNS = [
|
||||
* 'tableName1' => [
|
||||
* 'columnName1',
|
||||
* 'columnName2',
|
||||
* ...,
|
||||
* ],
|
||||
* 'tableName2' => [
|
||||
* 'columnName1',
|
||||
* 'columnName2',
|
||||
* ...,
|
||||
* ],
|
||||
* ...,
|
||||
* ];
|
||||
*/
|
||||
public const GONE_COLUMNS = [
|
||||
'polls_notif' => [
|
||||
'test_text_notnull',
|
||||
'test_text_null',
|
||||
'test_string_null_64',
|
||||
'test_string_notnull_128',
|
||||
'test_integer_null_11',
|
||||
'test_integer_notnull_11',
|
||||
'test_bigint_null_21',
|
||||
'test_bigint_notnull_21',
|
||||
]
|
||||
];
|
||||
|
||||
/**
|
||||
* define primary keys (only set on table creation)
|
||||
* Format:
|
||||
* public const PRIMARYKEY = [
|
||||
* 'polls_polls' => [
|
||||
* 'id' => [
|
||||
* 'type' => Types::INTEGER,
|
||||
* 'options' => ['autoincrement' => true, 'notnull' => true]
|
||||
* ],
|
||||
* 'type' => [
|
||||
* 'type' => Types::STRING,
|
||||
* 'options' => ['notnull' => true, 'default' => 'datePoll', 'length' => 64]],
|
||||
* ],
|
||||
* ...,
|
||||
* ],
|
||||
* 'polls_options' => [
|
||||
* 'id' => [
|
||||
* 'type' => Types::INTEGER,
|
||||
* 'options' => ['autoincrement' => true, 'notnull' => true]
|
||||
* ],
|
||||
* 'poll_id' => [
|
||||
* 'type' => Types::INTEGER,
|
||||
* 'options' => ['notnull' => true, 'default' => 0]
|
||||
* ],
|
||||
* ...,
|
||||
* ],
|
||||
* ...,
|
||||
* ];
|
||||
*/
|
||||
|
||||
public const TABLES = [
|
||||
'polls_polls' => [
|
||||
'id' => ['type' => Types::INTEGER, 'options' => ['autoincrement' => true, 'notnull' => true]],
|
||||
'type' => ['type' => Types::STRING, 'options' => ['notnull' => true, 'default' => 'datePoll', 'length' => 64]],
|
||||
'title' => ['type' => Types::STRING, 'options' => ['notnull' => false, 'default' => '', 'length' => 128]],
|
||||
'description' => ['type' => Types::TEXT, 'options' => ['notnull' => false, 'default' => '', 'length' => 65535]],
|
||||
'owner' => ['type' => Types::STRING, 'options' => ['notnull' => false, 'default' => '', 'length' => 64]],
|
||||
'created' => ['type' => Types::INTEGER, 'options' => ['notnull' => true, 'default' => 0]],
|
||||
'expire' => ['type' => Types::INTEGER, 'options' => ['notnull' => true, 'default' => 0]],
|
||||
'deleted' => ['type' => Types::INTEGER, 'options' => ['notnull' => true, 'default' => 0]],
|
||||
'access' => ['type' => Types::STRING, 'options' => ['notnull' => true, 'default' => 'hidden', 'length' => 1024]],
|
||||
'anonymous' => ['type' => Types::INTEGER, 'options' => ['notnull' => true, 'default' => 0]],
|
||||
'allow_maybe' => ['type' => Types::INTEGER, 'options' => ['notnull' => true, 'default' => 1]],
|
||||
'vote_limit' => ['type' => Types::INTEGER, 'options' => ['notnull' => true, 'default' => 0]],
|
||||
'option_limit' => ['type' => Types::INTEGER, 'options' => ['notnull' => true, 'default' => 0]],
|
||||
'show_results' => ['type' => Types::STRING, 'options' => ['notnull' => true, 'default' => 'always', 'length' => 64]],
|
||||
'admin_access' => ['type' => Types::INTEGER, 'options' => ['notnull' => true, 'default' => 0]],
|
||||
'important' => ['type' => Types::INTEGER, 'options' => ['notnull' => true, 'default' => 0]],
|
||||
'allow_comment' => ['type' => Types::INTEGER, 'options' => ['notnull' => true, 'default' => 1]],
|
||||
'hide_booked_up' => ['type' => Types::INTEGER, 'options' => ['notnull' => true, 'default' => 1]],
|
||||
'allow_proposals' => ['type' => Types::STRING, 'options' => ['notnull' => true, 'default' => 'disallow', 'length' => 64]],
|
||||
'use_no' => ['type' => Types::INTEGER, 'options' => ['notnull' => true, 'default' => 1]],
|
||||
'proposals_expire' => ['type' => Types::INTEGER, 'options' => ['notnull' => true, 'default' => 0]],
|
||||
],
|
||||
'polls_options' => [
|
||||
'id' => ['type' => Types::INTEGER, 'options' => ['autoincrement' => true, 'notnull' => true]],
|
||||
'poll_id' => ['type' => Types::INTEGER, 'options' => ['notnull' => true, 'default' => 0]],
|
||||
'poll_option_text' => ['type' => Types::STRING, 'options' => ['notnull' => false, 'default' => '', 'length' => 256]],
|
||||
'timestamp' => ['type' => Types::INTEGER, 'options' => ['notnull' => true, 'default' => 0]],
|
||||
'duration' => ['type' => Types::INTEGER, 'options' => ['notnull' => true, 'default' => 0]],
|
||||
'order' => ['type' => Types::INTEGER, 'options' => ['notnull' => true, 'default' => 0]],
|
||||
'confirmed' => ['type' => Types::INTEGER, 'options' => ['notnull' => true, 'default' => 0]],
|
||||
'owner' => ['type' => Types::STRING, 'options' => ['notnull' => false, 'default' => '', 'length' => 64]],
|
||||
'released' => ['type' => Types::INTEGER, 'options' => ['notnull' => true, 'default' => 0]],
|
||||
],
|
||||
'polls_votes' => [
|
||||
'id' => ['type' => Types::INTEGER, 'options' => ['autoincrement' => true, 'notnull' => true]],
|
||||
'poll_id' => ['type' => Types::INTEGER, 'options' => ['notnull' => true, 'default' => 0]],
|
||||
'user_id' => ['type' => Types::STRING, 'options' => ['notnull' => false, 'default' => '', 'length' => 64]],
|
||||
'vote_option_id' => ['type' => Types::INTEGER, 'options' => ['notnull' => true, 'default' => 0]],
|
||||
'vote_option_text' => ['type' => Types::STRING, 'options' => ['notnull' => false, 'default' => '', 'length' => 256]],
|
||||
'vote_answer' => ['type' => Types::STRING, 'options' => ['notnull' => false, 'default' => '', 'length' => 64]],
|
||||
],
|
||||
'polls_comments' => [
|
||||
'id' => ['type' => Types::INTEGER, 'options' => ['autoincrement' => true, 'notnull' => true]],
|
||||
'poll_id' => ['type' => Types::INTEGER, 'options' => ['notnull' => true, 'default' => 0]],
|
||||
'user_id' => ['type' => Types::STRING, 'options' => ['notnull' => false, 'default' => '', 'length' => 64]],
|
||||
'comment' => ['type' => Types::STRING, 'options' => ['notnull' => false, 'default' => '', 'length' => 1024]],
|
||||
'timestamp' => ['type' => Types::INTEGER, 'options' => ['notnull' => true, 'default' => 0]],
|
||||
|
||||
],
|
||||
'polls_shares' => [
|
||||
'id' => ['type' => Types::INTEGER, 'options' => ['autoincrement' => true, 'notnull' => true]],
|
||||
'token' => ['type' => Types::STRING, 'options' => ['notnull' => false, 'default' => '', 'length' => 64]],
|
||||
'type' => ['type' => Types::STRING, 'options' => ['notnull' => false, 'default' => '', 'length' => 64]],
|
||||
'poll_id' => ['type' => Types::INTEGER, 'options' => ['notnull' => true, 'default' => 0]],
|
||||
'user_id' => ['type' => Types::STRING, 'options' => ['notnull' => false, 'default' => '', 'length' => 64]],
|
||||
'display_name' => ['type' => Types::STRING, 'options' => ['notnull' => false, 'default' => '', 'length' => 64]],
|
||||
'email_address' => ['type' => Types::STRING, 'options' => ['notnull' => false, 'default' => '', 'length' => 254]],
|
||||
'invitation_sent' => ['type' => Types::INTEGER, 'options' => ['notnull' => true, 'default' => 0]],
|
||||
],
|
||||
'polls_notif' => [
|
||||
'id' => ['type' => Types::INTEGER, 'options' => ['autoincrement' => true, 'notnull' => true]],
|
||||
'poll_id' => ['type' => Types::INTEGER, 'options' => ['notnull' => true, 'default' => 0]],
|
||||
'user_id' => ['type' => Types::STRING, 'options' => ['notnull' => false, 'default' => '', 'length' => 64]],
|
||||
],
|
||||
'polls_log' => [
|
||||
'id' => ['type' => Types::INTEGER, 'options' => ['autoincrement' => true, 'notnull' => true]],
|
||||
'poll_id' => ['type' => Types::INTEGER, 'options' => ['notnull' => true, 'default' => 0]],
|
||||
'user_id' => ['type' => Types::STRING, 'options' => ['notnull' => false, 'default' => '', 'length' => 64]],
|
||||
'display_name' => ['type' => Types::STRING, 'options' => ['notnull' => false, 'default' => '', 'length' => 64]],
|
||||
'message_id' => ['type' => Types::STRING, 'options' => ['notnull' => false, 'default' => '', 'length' => 64]],
|
||||
'created' => ['type' => Types::INTEGER, 'options' => ['notnull' => true, 'default' => 0]],
|
||||
'processed' => ['type' => Types::INTEGER, 'options' => ['notnull' => true, 'default' => 0]],
|
||||
],
|
||||
'polls_watch' => [
|
||||
'id' => ['type' => Types::INTEGER, 'options' => ['autoincrement' => true, 'notnull' => true]],
|
||||
'poll_id' => ['type' => Types::INTEGER, 'options' => ['notnull' => true, 'default' => 0]],
|
||||
'table' => ['type' => Types::STRING, 'options' => ['notnull' => false, 'default' => '', 'length' => 64]],
|
||||
'updated' => ['type' => Types::INTEGER, 'options' => ['notnull' => true, 'default' => 0]],
|
||||
],
|
||||
'polls_preferences' => [
|
||||
'id' => ['type' => Types::INTEGER, 'options' => ['autoincrement' => true, 'notnull' => true]],
|
||||
'user_id' => ['type' => Types::STRING, 'options' => ['notnull' => false, 'default' => '', 'length' => 64]],
|
||||
'timestamp' => ['type' => Types::INTEGER, 'options' => ['notnull' => true, 'default' => 0]],
|
||||
'preferences' => ['type' => Types::TEXT, 'options' => ['notnull' => false, 'default' => '', 'length' => 65535]],
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* Iterate over tables and make sure, the are created or updated
|
||||
* according to the schema
|
||||
*/
|
||||
public static function CreateOrUpdateSchema(ISchemaWrapper &$schema, IOutput &$output) {
|
||||
foreach (self::TABLES as $tableName => $columns) {
|
||||
$tableCreated = false;
|
||||
|
||||
if ($schema->hasTable($tableName)) {
|
||||
$output->info('Validating table ' . $tableName);
|
||||
$table = $schema->getTable($tableName);
|
||||
} else {
|
||||
$output->info('Creating table ' . $tableName);
|
||||
$table = $schema->createTable($tableName);
|
||||
$tableCreated = true;
|
||||
}
|
||||
|
||||
foreach ($columns as $columnName => $columnDefinition) {
|
||||
|
||||
if ($table->hasColumn($columnName)) {
|
||||
$column = $table->getColumn($columnName);
|
||||
$column->setOptions($columnDefinition['options']);
|
||||
if ($column->getType()->getName() !== $columnDefinition['type']) {
|
||||
$output->info('Migrating ' . $tableName . ', ' . $columnName . ' to ' . $columnDefinition['type']);
|
||||
$column->setType(Type::getType($columnDefinition['type']));
|
||||
}
|
||||
|
||||
$table->changeColumn($columnName, $columnDefinition['options']);
|
||||
|
||||
} else {
|
||||
$table->addColumn($columnName, $columnDefinition['type'], $columnDefinition['options']);
|
||||
}
|
||||
}
|
||||
|
||||
if ($tableCreated) {
|
||||
$table->setPrimaryKey(['id']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove obsolete tables if they still exist
|
||||
*/
|
||||
public static function removeObsoleteTables(ISchemaWrapper &$schema, IOutput &$output) {
|
||||
$droppedTables = [];
|
||||
foreach (self::GONE_TABLES as $tableName) {
|
||||
if ($schema->hasTable($tableName)) {
|
||||
$schema->dropTable($tableName);
|
||||
$droppedTables[] = $tableName;
|
||||
}
|
||||
if (count($droppedTables)) {
|
||||
$output->info(count($droppedTables) . ' orphaned tables were dropped: ' . implode(", ", $droppedTables));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove obsolete columns, if they exist
|
||||
*/
|
||||
public static function removeObsoleteColumns(ISchemaWrapper &$schema, IOutput &$output) {
|
||||
$droppedColumns = [];
|
||||
foreach (self::GONE_COLUMNS as $tableName => $columns) {
|
||||
if ($schema->hasTable($tableName)) {
|
||||
$table = $schema->getTable($tableName);
|
||||
foreach ($columns as $columnName) {
|
||||
if ($table->hasColumn($columnName)) {
|
||||
$table->dropColumn($columnName);
|
||||
$droppedColumns[] = $tableName . ':' . $columnName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count($droppedColumns)) {
|
||||
$output->info(count($droppedColumns) . ' orphaned columns were dropped: ' . implode(", ", $droppedColumns));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tidy migrations table and remove obsolete migration entries.
|
||||
*/
|
||||
public static function removeObsoleteMigrations(IDBConnection &$connection, IOutput &$output) {
|
||||
$query = $connection->getQueryBuilder();
|
||||
$output->info('tidy migration entries');
|
||||
foreach (self::GONE_MIGRATIONS as $version) {
|
||||
$query->delete('migrations')
|
||||
->where('app = :appName')
|
||||
->andWhere('version = :version')
|
||||
->setParameter('appName', 'polls')
|
||||
->setParameter('version', $version )
|
||||
->execute();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,440 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2017 René Gieling <github@dartcafe.de>
|
||||
*
|
||||
* @author René Gieling <github@dartcafe.de>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Polls\Migration;
|
||||
|
||||
use OCP\DB\ISchemaWrapper;
|
||||
use OCP\DB\Types;
|
||||
use OCP\IConfig;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\Migration\SimpleMigrationStep;
|
||||
use OCP\Migration\IOutput;
|
||||
|
||||
/**
|
||||
* Installation class for the polls app.
|
||||
* Initial db creation
|
||||
*/
|
||||
class Version0200Date20010606120000 extends SimpleMigrationStep {
|
||||
|
||||
/** @var IDBConnection */
|
||||
protected $connection;
|
||||
|
||||
/** @var IConfig */
|
||||
protected $config;
|
||||
|
||||
public function __construct(IDBConnection $connection, IConfig $config) {
|
||||
$this->connection = $connection;
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* $schemaClosure The `\Closure` returns a `ISchemaWrapper`
|
||||
*/
|
||||
public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options) {
|
||||
/** @var ISchemaWrapper $schema */
|
||||
$schema = $schemaClosure();
|
||||
if (!$schema->hasTable('polls_polls')) {
|
||||
$table = $schema->createTable('polls_polls');
|
||||
$table->addColumn('id', TYPES::INTEGER, [
|
||||
'autoincrement' => true,
|
||||
'notnull' => true,
|
||||
'length' => 11,
|
||||
]);
|
||||
$table->addColumn('type', TYPES::STRING, [
|
||||
'notnull' => true,
|
||||
'default' => 'datePoll',
|
||||
'length' => 64,
|
||||
]);
|
||||
$table->addColumn('title', TYPES::STRING, [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
'length' => 128,
|
||||
]);
|
||||
$table->addColumn('description', TYPES::TEXT, [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
]);
|
||||
$table->addColumn('owner', TYPES::STRING, [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
'length' => 64,
|
||||
]);
|
||||
$table->addColumn('created', TYPES::INTEGER, [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
$table->addColumn('expire', TYPES::INTEGER, [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
$table->addColumn('deleted', TYPES::INTEGER, [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
$table->addColumn('access', TYPES::STRING, [
|
||||
'notnull' => true,
|
||||
'default' => 'hidden',
|
||||
'length' => 1024,
|
||||
]);
|
||||
$table->addColumn('anonymous', TYPES::INTEGER, [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
$table->addColumn('allow_maybe', TYPES::INTEGER, [
|
||||
'notnull' => true,
|
||||
'default' => 1,
|
||||
'length' => 11,
|
||||
]);
|
||||
$table->addColumn('vote_limit', TYPES::INTEGER, [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
$table->addColumn('option_limit', TYPES::INTEGER, [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
$table->addColumn('show_results', TYPES::STRING, [
|
||||
'notnull' => true,
|
||||
'default' => 'always',
|
||||
'length' => 64,
|
||||
]);
|
||||
$table->addColumn('admin_access', TYPES::INTEGER, [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 8,
|
||||
]);
|
||||
$table->addColumn('important', TYPES::INTEGER, [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
$table->addColumn('allow_comment', TYPES::INTEGER, [
|
||||
'notnull' => true,
|
||||
'default' => 1,
|
||||
'length' => 11,
|
||||
]);
|
||||
$table->addColumn('hide_booked_up', TYPES::INTEGER, [
|
||||
'notnull' => true,
|
||||
'default' => 1,
|
||||
'length' => 11,
|
||||
]);
|
||||
$table->addColumn('allow_proposals', TYPES::STRING, [
|
||||
'notnull' => true,
|
||||
'default' => 'disallow',
|
||||
'length' => 64,
|
||||
]);
|
||||
$table->addColumn('use_no', TYPES::INTEGER, [
|
||||
'notnull' => true,
|
||||
'default' => 1,
|
||||
'length' => 11,
|
||||
]);
|
||||
$table->addColumn('proposals_expire', TYPES::INTEGER, [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
|
||||
$table->setPrimaryKey(['id']);
|
||||
}
|
||||
|
||||
if (!$schema->hasTable('polls_options')) {
|
||||
$table = $schema->createTable('polls_options');
|
||||
$table->addColumn('id', TYPES::INTEGER, [
|
||||
'autoincrement' => true,
|
||||
'notnull' => true,
|
||||
'length' => 11,
|
||||
]);
|
||||
$table->addColumn('poll_id', TYPES::INTEGER, [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
$table->addColumn('poll_option_text', TYPES::STRING, [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
'length' => 256,
|
||||
]);
|
||||
$table->addColumn('timestamp', TYPES::INTEGER, [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
$table->addColumn('duration', TYPES::INTEGER, [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
$table->addColumn('order', TYPES::INTEGER, [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
$table->addColumn('confirmed', TYPES::INTEGER, [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
$table->addColumn('owner', TYPES::STRING, [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
'length' => 64,
|
||||
]);
|
||||
$table->addColumn('released', TYPES::INTEGER, [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
$table->setPrimaryKey(['id']);
|
||||
}
|
||||
|
||||
if (!$schema->hasTable('polls_votes')) {
|
||||
$table = $schema->createTable('polls_votes');
|
||||
$table->addColumn('id', TYPES::INTEGER, [
|
||||
'autoincrement' => true,
|
||||
'notnull' => true,
|
||||
'length' => 11,
|
||||
]);
|
||||
$table->addColumn('poll_id', TYPES::INTEGER, [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
$table->addColumn('user_id', TYPES::STRING, [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
'length' => 64,
|
||||
]);
|
||||
$table->addColumn('vote_option_id', TYPES::INTEGER, [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 64,
|
||||
]);
|
||||
$table->addColumn('vote_option_text', TYPES::STRING, [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
'length' => 256,
|
||||
]);
|
||||
$table->addColumn('vote_answer', TYPES::STRING, [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
'length' => 64,
|
||||
]);
|
||||
$table->setPrimaryKey(['id']);
|
||||
}
|
||||
|
||||
if (!$schema->hasTable('polls_comments')) {
|
||||
$table = $schema->createTable('polls_comments');
|
||||
$table->addColumn('id', TYPES::INTEGER, [
|
||||
'autoincrement' => true,
|
||||
'notnull' => true,
|
||||
]);
|
||||
$table->addColumn('poll_id', TYPES::INTEGER, [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
$table->addColumn('user_id', TYPES::STRING, [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
'length' => 64,
|
||||
]);
|
||||
$table->addColumn('comment', TYPES::STRING, [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
'length' => 1024,
|
||||
]);
|
||||
$table->addColumn('timestamp', TYPES::INTEGER, [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
$table->setPrimaryKey(['id']);
|
||||
}
|
||||
|
||||
if (!$schema->hasTable('polls_notif')) {
|
||||
$table = $schema->createTable('polls_notif');
|
||||
$table->addColumn('id', TYPES::INTEGER, [
|
||||
'autoincrement' => true,
|
||||
'notnull' => true,
|
||||
]);
|
||||
$table->addColumn('poll_id', TYPES::INTEGER, [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
$table->addColumn('user_id', TYPES::STRING, [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
'length' => 64,
|
||||
]);
|
||||
$table->setPrimaryKey(['id']);
|
||||
}
|
||||
|
||||
if (!$schema->hasTable('polls_share')) {
|
||||
$table = $schema->createTable('polls_share');
|
||||
$table->addColumn('id', TYPES::INTEGER, [
|
||||
'autoincrement' => true,
|
||||
'notnull' => true,
|
||||
'length' => 11,
|
||||
]);
|
||||
$table->addColumn('token', TYPES::STRING, [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
'length' => 64,
|
||||
]);
|
||||
$table->addColumn('type', TYPES::STRING, [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
'length' => 64,
|
||||
]);
|
||||
$table->addColumn('poll_id', TYPES::INTEGER, [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
$table->addColumn('user_id', TYPES::STRING, [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
'length' => 64,
|
||||
]);
|
||||
$table->addColumn('invitation_sent', TYPES::INTEGER, [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
$table->addColumn('display_name', TYPES::STRING, [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
'length' => 64,
|
||||
]);
|
||||
$table->addColumn('email_address', TYPES::STRING, [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
'length' => 254,
|
||||
]);
|
||||
$table->setPrimaryKey(['id']);
|
||||
}
|
||||
|
||||
if (!$schema->hasTable('polls_log')) {
|
||||
$table = $schema->createTable('polls_log');
|
||||
$table->addColumn('id', TYPES::INTEGER, [
|
||||
'autoincrement' => true,
|
||||
'notnull' => true,
|
||||
'length' => 11,
|
||||
]);
|
||||
$table->addColumn('created', TYPES::INTEGER, [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
$table->addColumn('processed', TYPES::INTEGER, [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
$table->addColumn('poll_id', TYPES::INTEGER, [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
$table->addColumn('user_id', TYPES::STRING, [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
'length' => 64,
|
||||
]);
|
||||
$table->addColumn('display_name', TYPES::STRING, [
|
||||
'notnull' => false,
|
||||
'length' => 64,
|
||||
]);
|
||||
$table->addColumn('message_id', TYPES::STRING, [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
'length' => 64,
|
||||
]);
|
||||
|
||||
$table->setPrimaryKey(['id']);
|
||||
}
|
||||
|
||||
// since polls 1.5
|
||||
// Version0105Date20200523142076
|
||||
if (!$schema->hasTable('polls_preferences')) {
|
||||
$table = $schema->createTable('polls_preferences');
|
||||
|
||||
$table->addColumn('id', TYPES::INTEGER, [
|
||||
'autoincrement' => true,
|
||||
'notnull' => true,
|
||||
'length' => 11,
|
||||
]);
|
||||
$table->addColumn('user_id', TYPES::STRING, [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
'length' => 64,
|
||||
]);
|
||||
$table->addColumn('timestamp', TYPES::INTEGER, [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
$table->addColumn('preferences', TYPES::TEXT, [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
]);
|
||||
$table->setPrimaryKey(['id']);
|
||||
}
|
||||
|
||||
// since polls 1.8
|
||||
// Version0108Date20210307130003
|
||||
if (!$schema->hasTable('polls_watch')) {
|
||||
$table = $schema->createTable('polls_watch');
|
||||
$table->addColumn('id', TYPES::INTEGER, [
|
||||
'autoincrement' => true,
|
||||
'notnull' => true,
|
||||
'length' => 11,
|
||||
]);
|
||||
$table->addColumn('table', TYPES::STRING, [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
'length' => 64,
|
||||
]);
|
||||
$table->addColumn('poll_id', TYPES::INTEGER, [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
$table->addColumn('updated', TYPES::INTEGER, [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
$table->setPrimaryKey(['id']);
|
||||
}
|
||||
|
||||
return $schema;
|
||||
}
|
||||
}
|
|
@ -1,606 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2017 René Gieling <github@dartcafe.de>
|
||||
*
|
||||
* @author René Gieling <github@dartcafe.de>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Polls\Migration;
|
||||
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
use Doctrine\DBAL\Types\TextType;
|
||||
use OCP\DB\ISchemaWrapper;
|
||||
use OCP\IConfig;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\Migration\SimpleMigrationStep;
|
||||
use OCP\Migration\IOutput;
|
||||
|
||||
class Version0200Date20010606120001 extends SimpleMigrationStep {
|
||||
|
||||
/** @var IDBConnection */
|
||||
protected $connection;
|
||||
|
||||
/** @var IConfig */
|
||||
protected $config;
|
||||
|
||||
/** @var bool */
|
||||
protected $migrateOrder;
|
||||
|
||||
/** @var bool */
|
||||
protected $migrateInvitationSent;
|
||||
|
||||
public function __construct(IDBConnection $connection, IConfig $config) {
|
||||
$this->connection = $connection;
|
||||
$this->config = $config;
|
||||
$this->migrateOrder = false;
|
||||
$this->migrateInvitationSent = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make an initial migration from schemas before polls 2.0
|
||||
* =======================================================
|
||||
* This migration can be safely removed, if the initial migration is
|
||||
* still present, but migrations from version before 2.0 will get lost
|
||||
*/
|
||||
public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options) {
|
||||
/** @var ISchemaWrapper $schema */
|
||||
$schema = $schemaClosure();
|
||||
|
||||
/**
|
||||
* Drop old tables, if they still exist. Make sure no unused tables
|
||||
* prior to polls 2.0 are present
|
||||
*/
|
||||
|
||||
// Version0010Date20200119101800 -> drop table 'polls_events'
|
||||
if ($schema->hasTable('polls_events')) {
|
||||
$schema->dropTable('polls_events');
|
||||
}
|
||||
|
||||
// Version0009Date20181125062101 -> drop table 'polls_dts'
|
||||
if ($schema->hasTable('polls_dts')) {
|
||||
$schema->dropTable('polls_dts');
|
||||
}
|
||||
|
||||
// Version0009Date20181125062101 -> drop table 'polls_txts'
|
||||
if ($schema->hasTable('polls_txts')) {
|
||||
$schema->dropTable('polls_txts');
|
||||
}
|
||||
|
||||
// Version0009Date20181125062101 -> drop table 'polls_particip'
|
||||
if ($schema->hasTable('polls_particip')) {
|
||||
$schema->dropTable('polls_particip');
|
||||
}
|
||||
|
||||
// Version0009Date20181125062101 -> drop table 'polls_particip_text'
|
||||
if ($schema->hasTable('polls_particip_text')) {
|
||||
$schema->dropTable('polls_particip_text');
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply changes to the polls_polls table, which resided in migrations
|
||||
* prior to polls 2.0
|
||||
*/
|
||||
if ($schema->hasTable('polls_polls')) {
|
||||
$table = $schema->getTable('polls_polls');
|
||||
|
||||
/** Add missing columns */
|
||||
|
||||
// Version0105Date20200903172733 -> introduce column 'important'
|
||||
if (!$table->hasColumn('important')) {
|
||||
$table->addColumn('important', 'integer', [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
}
|
||||
|
||||
// Version0107Date20210104135506 -> introduce column 'proposals_expire'
|
||||
if (!$table->hasColumn('option_limit')) {
|
||||
$table->addColumn('option_limit', 'integer', [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
}
|
||||
|
||||
// Version0108Date20210307130003 -> introduce column 'allow_comment'
|
||||
if (!$table->hasColumn('allow_comment')) {
|
||||
$table->addColumn('allow_comment', 'integer', [
|
||||
'notnull' => true,
|
||||
'default' => 1,
|
||||
'length' => 11,
|
||||
]);
|
||||
}
|
||||
|
||||
// Version0108Date20210307130003 -> introduce column 'hide_booked_up'
|
||||
if (!$table->hasColumn('hide_booked_up')) {
|
||||
$table->addColumn('hide_booked_up', 'integer', [
|
||||
'notnull' => true,
|
||||
'default' => 1,
|
||||
'length' => 11,
|
||||
]);
|
||||
}
|
||||
|
||||
// Version0109Date20210323120002 -> introduce column 'allow_proposals'
|
||||
if (!$table->hasColumn('allow_proposals')) {
|
||||
$table->addColumn('allow_proposals', 'string', [
|
||||
'notnull' => true,
|
||||
'default' => 'disallow',
|
||||
'length' => 64,
|
||||
]);
|
||||
}
|
||||
|
||||
// Version0109Date20210323120002 -> introduce column 'use_no'
|
||||
if (!$table->hasColumn('use_no')) {
|
||||
$table->addColumn('use_no', 'integer', [
|
||||
'notnull' => true,
|
||||
'default' => 1,
|
||||
'length' => 11,
|
||||
]);
|
||||
}
|
||||
|
||||
// Version0109Date20210323120002 -> introduce column 'proposals_expire'
|
||||
if (!$table->hasColumn('proposals_expire')) {
|
||||
$table->addColumn('proposals_expire', 'integer', [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
}
|
||||
|
||||
/** Change attributes of columns */
|
||||
|
||||
// Version0104Date20200314074611 -> column 'description' type changed
|
||||
if ($table->hasColumn('description')) {
|
||||
$column = $table->getColumn('description');
|
||||
if (!($column->getType() instanceof TextType)) {
|
||||
$table->changeColumn('description', [
|
||||
'type' => Type::getType('text'),
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
]);
|
||||
}
|
||||
}
|
||||
// Version0200Date20010606120000 -> column 'allow_maybe' length changed
|
||||
$table->changeColumn('allow_maybe', [
|
||||
'length' => 11,
|
||||
]);
|
||||
|
||||
// Version0200Date20010606120000 -> column 'title' default changed
|
||||
$table->changeColumn('title', [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
]);
|
||||
|
||||
// Version0200Date20010606120000 -> column 'description' default changed
|
||||
$table->changeColumn('description', [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
]);
|
||||
|
||||
// Version0200Date20010606120000 -> column 'anonymous' length changed
|
||||
$table->changeColumn('anonymous', [
|
||||
'length' => 11,
|
||||
]);
|
||||
|
||||
/** Drop obsolete columns */
|
||||
|
||||
// Version0200Date20010606120000 -> drop 'full_anonymous'
|
||||
if ($table->hasColumn('full_anonymous')) {
|
||||
$table->dropColumn('full_anonymous');
|
||||
}
|
||||
|
||||
// Version0200Date20010606120000 -> drop 'options'
|
||||
if ($table->hasColumn('options')) {
|
||||
$table->dropColumn('options');
|
||||
}
|
||||
|
||||
// Version0200Date20010606120000 -> drop 'settings'
|
||||
if ($table->hasColumn('settings')) {
|
||||
$table->dropColumn('settings');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply changes to the polls_options table, which resided in migrations
|
||||
* prior to polls 2.0
|
||||
*/
|
||||
if ($schema->hasTable('polls_options')) {
|
||||
$table = $schema->getTable('polls_options');
|
||||
|
||||
/** Add missing columns */
|
||||
|
||||
// Version0103Date20200130171244 -> introduce column 'order'
|
||||
if (!$table->hasColumn('order')) {
|
||||
// migrate in postSchemaChange
|
||||
$this->migrateOrder = true;
|
||||
$table->addColumn('order', 'integer', [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
}
|
||||
|
||||
// Version0105Date20200508211943 -> introduce column 'confirmed'
|
||||
if (!$table->hasColumn('confirmed')) {
|
||||
$table->addColumn('confirmed', 'integer', [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
}
|
||||
|
||||
// Version0108Date20210307130003 -> introduce column 'duration'
|
||||
if (!$table->hasColumn('duration')) {
|
||||
$table->addColumn('duration', 'integer', [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
}
|
||||
|
||||
// Version0109Date20210323120002 -> introduce column 'owner'
|
||||
if (!$table->hasColumn('owner')) {
|
||||
$table->addColumn('owner', 'string', [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
'length' => 64,
|
||||
]);
|
||||
}
|
||||
|
||||
// Version0109Date20210323120002 -> introduce column 'released'
|
||||
if (!$table->hasColumn('released')) {
|
||||
$table->addColumn('released', 'integer', [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
}
|
||||
|
||||
/** Change attributes of columns */
|
||||
|
||||
// Version0107Date20201210204702 -> column 'poll_option_text' notnull, default changed
|
||||
$table->changeColumn('poll_option_text', [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
]);
|
||||
|
||||
// Version0107Date20201210204702 -> column 'timestamp' notnull, default changed
|
||||
// Version0200Date20010606120000 -> column 'id' length changed
|
||||
$table->changeColumn('timestamp', [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
|
||||
// Version0200Date20010606120000 -> column 'poll_id' notnull, default changed
|
||||
$table->changeColumn('poll_id', [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
|
||||
// Version0200Date20010606120000 -> column 'id' length changed
|
||||
$table->changeColumn('id', [
|
||||
'length' => 11,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply changes to the polls_votes table, which resided in migrations
|
||||
* prior to polls 2.0
|
||||
*/
|
||||
if ($schema->hasTable('polls_votes')) {
|
||||
$table = $schema->getTable('polls_votes');
|
||||
|
||||
/** Change attributes of columns */
|
||||
|
||||
// Version0107Date20201210213303 -> column 'user_id' notnull, default changed
|
||||
$table->changeColumn('user_id', [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
]);
|
||||
|
||||
// Version0107Date20201210213303 -> column 'vote_option_text' notnull, default changed
|
||||
$table->changeColumn('vote_option_text', [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
]);
|
||||
|
||||
// Version0200Date20010606120000 -> column 'id' length changed
|
||||
$table->changeColumn('id', [
|
||||
'length' => 11,
|
||||
]);
|
||||
|
||||
// Version0200Date20010606120000 -> column 'poll_id' notnull, default, length changed
|
||||
$table->changeColumn('poll_id', [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
|
||||
// Version0200Date20010606120000 -> column 'vote_answer' notnull, default changed
|
||||
$table->changeColumn('vote_answer', [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply changes to the polls_comments table, which resided in migrations
|
||||
* prior to polls 2.0
|
||||
*/
|
||||
if ($schema->hasTable('polls_comments')) {
|
||||
$table = $schema->getTable('polls_comments');
|
||||
|
||||
/** Add missing columns */
|
||||
|
||||
// Version0010Date20191227063812 -> added 'timestamp'
|
||||
if (!$table->hasColumn('timestamp')) {
|
||||
$table->addColumn('timestamp', 'integer', [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
}
|
||||
|
||||
/** Change attributes of columns */
|
||||
|
||||
// Version0200Date20010606120000 -> column 'poll_id' notnull, default, length changed
|
||||
$table->changeColumn('poll_id', [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
|
||||
// Version0200Date20010606120000 -> column 'user_id' default changed
|
||||
$table->changeColumn('user_id', [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
]);
|
||||
|
||||
// Version0200Date20010606120000 -> column 'comments' default changed
|
||||
$table->changeColumn('comment', [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
]);
|
||||
|
||||
/** Drop obsolete columns */
|
||||
// Version0200Date20010606120000 -> drop 'settings'
|
||||
if ($table->hasColumn('dt')) {
|
||||
$table->dropColumn('dt');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply changes to the polls_notif table, which resided in migrations
|
||||
* prior to polls 2.0
|
||||
*/
|
||||
if ($schema->hasTable('polls_share')) {
|
||||
$table = $schema->getTable('polls_share');
|
||||
|
||||
/** Change attributes of columns */
|
||||
|
||||
// Version0200Date20010606120000 -> column 'poll_id' notnull, default, length changed
|
||||
$table->changeColumn('poll_id', [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
|
||||
// Version0200Date20010606120000 -> column 'user_id' default changed
|
||||
$table->changeColumn('user_id', [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply changes to the polls_share table, which resided in migrations
|
||||
* prior to polls 2.0
|
||||
*/
|
||||
if ($schema->hasTable('polls_share')) {
|
||||
$table = $schema->getTable('polls_share');
|
||||
|
||||
/** Add missing columns */
|
||||
// Version0105Date20200704084037 -> introduce column 'invitation_sent'
|
||||
if (!$table->hasColumn('invitation_sent')) {
|
||||
// migrate in postSchemaChange
|
||||
$this->migrateInvitationSent = true;
|
||||
$table->addColumn('invitation_sent', 'integer', [
|
||||
'notnull' => true,
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
}
|
||||
|
||||
// Version0106Date20201031080745 -> introduce column 'display_name'
|
||||
if (!$table->hasColumn('display_name')) {
|
||||
$table->addColumn('display_name', 'string', [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
'length' => 64,
|
||||
]);
|
||||
}
|
||||
|
||||
// Version0106Date20201031080745 -> introduce column 'email_address'
|
||||
// ignore migration from user_email to email_address
|
||||
if (!$table->hasColumn('email_address')) {
|
||||
$table->addColumn('email_address', 'string', [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
'length' => 254,
|
||||
]);
|
||||
}
|
||||
|
||||
/** Change attributes of columns */
|
||||
|
||||
// Version0107Date20201217071304 -> column 'user_id' notnull, default changed
|
||||
$table->changeColumn('user_id', [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
]);
|
||||
|
||||
// Version0200Date20010606120000 -> column 'id' length changed
|
||||
$table->changeColumn('id', [
|
||||
'length' => 11,
|
||||
]);
|
||||
|
||||
// Version0200Date20010606120000 -> column 'token' default changed
|
||||
$table->changeColumn('token', [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
]);
|
||||
|
||||
// Version0200Date20010606120000 -> column 'type' default changed
|
||||
$table->changeColumn('type', [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
]);
|
||||
|
||||
// Version0200Date20010606120000 -> column 'poll_id' default, length changed
|
||||
$table->changeColumn('poll_id', [
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
|
||||
|
||||
/** Drop obsolete columns */
|
||||
|
||||
// Version0101Date20200122194300 -> drop 'user'
|
||||
if ($table->hasColumn('user')) {
|
||||
$table->dropColumn('user');
|
||||
}
|
||||
|
||||
// Version0106Date20201031080946 -> drop 'user_email'
|
||||
// ignore migration from user_email to email_address
|
||||
if ($table->hasColumn('user_email')) {
|
||||
$table->dropColumn('user_email');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply changes to the polls_log table, which resided in migrations
|
||||
* prior to polls 2.0
|
||||
*/
|
||||
if ($schema->hasTable('polls_log')) {
|
||||
$table = $schema->getTable('polls_log');
|
||||
|
||||
/** Change attributes of columns */
|
||||
|
||||
// Version0107Date20210121220707 -> column 'poll_id' default changed
|
||||
// Version0200Date20010606120000 -> column 'poll_id' length changed
|
||||
$table->changeColumn('poll_id', [
|
||||
'default' => 0,
|
||||
'length' => 11,
|
||||
]);
|
||||
|
||||
// Version0107Date20210121220707 -> column 'user_id' length, notnull, default changed
|
||||
$table->changeColumn('user_id', [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
'length' => 64,
|
||||
]);
|
||||
|
||||
// Version0107Date20210121220707 -> column 'message_id' notnull, default changed
|
||||
$table->changeColumn('message_id', [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
]);
|
||||
|
||||
// Version0200Date20010606120000 -> column 'id' length changed
|
||||
$table->changeColumn('id', [
|
||||
'length' => 11,
|
||||
]);
|
||||
|
||||
/** Drop obsolete columns */
|
||||
|
||||
// Version0107Date20210121220707 -> drop column 'message'
|
||||
if ($table->hasColumn('message')) {
|
||||
$table->dropColumn('message');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply changes to the polls_preferences table, which resided in migrations
|
||||
* prior to polls 2.0
|
||||
*/
|
||||
if ($schema->hasTable('polls_preferences')) {
|
||||
$table = $schema->getTable('polls_preferences');
|
||||
|
||||
/** Change attributes of columns */
|
||||
|
||||
// Version0106Date20201031080745 -> column 'user_id' default changed
|
||||
$table->changeColumn('user_id', [
|
||||
'notnull' => false,
|
||||
'default' => '',
|
||||
]);
|
||||
|
||||
// Version0106Date20201031080745 -> column 'preferences' notnull changed
|
||||
$table->changeColumn('preferences', [
|
||||
'notnull' => false,
|
||||
]);
|
||||
|
||||
// Version0200Date20010606120000 -> column 'id' length changed
|
||||
$table->changeColumn('id', [
|
||||
'length' => 11,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply changes to the polls_watch table, which resided in migrations
|
||||
* prior to polls 2.0
|
||||
*/
|
||||
if ($schema->hasTable('polls_watch')) {
|
||||
$table = $schema->getTable('polls_watch');
|
||||
|
||||
/** Change attributes of columns */
|
||||
|
||||
// Version0200Date20010606120000 -> column 'id' length changed
|
||||
$table->changeColumn('id', [
|
||||
'length' => 11,
|
||||
]);
|
||||
}
|
||||
|
||||
return $schema;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function postSchemaChange(IOutput $output, \Closure $schemaClosure, array $options) {
|
||||
$query = $this->connection->getQueryBuilder();
|
||||
|
||||
// Version0103Date20200130171244 -> introduce column 'order'
|
||||
// possibly not needed any more, because in the entity the timestamp is
|
||||
// returned as order, if timestamp is set.
|
||||
if ($this->migrateOrder) {
|
||||
$query->update('polls_options')
|
||||
->set('order', 'timestamp');
|
||||
}
|
||||
|
||||
// Version0105Date20200704084037 -> introduce column 'invitation_sent'
|
||||
if ($this->migrateInvitationSent) {
|
||||
$query->update('polls_share')
|
||||
->set('invitation_sent', 'id');
|
||||
}
|
||||
|
||||
$query->execute();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2021 René Gieling <github@dartcafe.de>
|
||||
*
|
||||
* @author René Gieling <github@dartcafe.de>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Polls\Migration;
|
||||
|
||||
use OCP\DB\ISchemaWrapper;
|
||||
use OCP\IConfig;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\Migration\SimpleMigrationStep;
|
||||
use OCP\Migration\IOutput;
|
||||
// use Doctrine\DBAL\Types\Type;
|
||||
|
||||
/**
|
||||
* Installation class for the polls app.
|
||||
* Initial db creation
|
||||
* Changed class naming: Version[jjmmpp]Date[YYYYMMDDHHMMSS]
|
||||
* Version: jj = major version, mm = minor, pp = patch
|
||||
*/
|
||||
class Version030000Date20210611120000 extends SimpleMigrationStep {
|
||||
|
||||
/** @var IDBConnection */
|
||||
protected $connection;
|
||||
|
||||
/** @var IConfig */
|
||||
protected $config;
|
||||
|
||||
public function __construct(IDBConnection $connection, IConfig $config) {
|
||||
$this->connection = $connection;
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* $schemaClosure The `\Closure` returns a `ISchemaWrapper`
|
||||
*/
|
||||
public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options) {
|
||||
/** @var ISchemaWrapper $schema */
|
||||
$schema = $schemaClosure();
|
||||
|
||||
// Call initial migration from class TableSchema
|
||||
// Drop old tables, which are migrated in prior versions
|
||||
TableSchema::removeObsoleteTables($schema, $output);
|
||||
// Drop old columns, which are migrated in prior versions
|
||||
TableSchema::removeObsoleteColumns($schema, $output);
|
||||
// Create tables, as defined in TableSchema or fix column definitions
|
||||
TableSchema::CreateOrUpdateSchema($schema, $output);
|
||||
// remove old migration entries from versions prior to polls 3.x
|
||||
// including migration versions from test releases
|
||||
// theoretically, only this migration should be existen. If not, no matter
|
||||
TableSchema::removeObsoleteMigrations($this->connection, $output);
|
||||
|
||||
return $schema;
|
||||
}
|
||||
|
||||
}
|
Загрузка…
Ссылка в новой задаче