social/lib/Migration/Version0002Date201906220000...

405 wiersze
9.0 KiB
PHP

<?php
declare(strict_types=1);
/**
* Nextcloud - Social Support
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*
* @author Maxence Lange <maxence@artificial-owl.com>
* @copyright 2018, Maxence Lange <maxence@artificial-owl.com>
* @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\Social\Migration;
use Closure;
use Doctrine\DBAL\Schema\SchemaException;
use Doctrine\DBAL\Types\Type;
use Exception;
use OCP\DB\ISchemaWrapper;
use OCP\IDBConnection;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
/**
* Class Version0002Date20190226000001
*
* @package OCA\Social\Migration
*/
class Version0002Date20190622000001 extends SimpleMigrationStep {
/** @var IDBConnection */
private $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
*
* @return ISchemaWrapper
* @throws SchemaException
*/
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options
): ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
if (!$schema->hasTable('social_a2_stream')) {
return $schema;
}
$table = $schema->getTable('social_a2_stream');
if (!$table->hasColumn('details')) {
$table->addColumn(
'details', Type::TEXT,
[
'notnull' => false
]
);
}
return $schema;
}
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
*
* @throws Exception
*/
public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options) {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
// $qb = $this->connection->getQueryBuilder();
// $qb->delete('social_a2_stream');
// $expr = $qb->expr();
// $qb->where($expr->eq('type', $qb->createNamedParameter('Announce')));
//
// $qb->execute();
$this->check(
$schema, 'id', 'social_server_follows', 'social_a2_follows', 'accepted', 'boolean'
);
$this->check(
$schema, 'id', 'social_server_notes', 'social_a2_stream', 'local', 'boolean'
);
$this->check(
$schema, 'id', 'social_cache_actors', 'social_a2_cache_actors', 'local', 'boolean'
);
$this->check(
$schema, 'id', 'social_cache_documents', 'social_a2_cache_docum', 'public',
'boolean'
);
$this->check(
$schema, 'id', 'social_server_actors', 'social_a2_actors', 'creation', 'datetime'
);
$this->check(
$schema, 'id', 'social_server_follows', 'social_a2_follows', 'creation', 'datetime'
);
$this->check(
$schema, 'id', 'social_server_notes', 'social_a2_stream', 'creation', 'datetime'
);
$this->check(
$schema, 'id', 'social_cache_actors', 'social_a2_cache_actors', 'creation',
'datetime'
);
$this->check(
$schema, 'id', 'social_cache_documents', 'social_a2_cache_docum', 'creation',
'datetime'
);
$this->check(
$schema, 'id', 'social_cache_documents', 'social_a2_cache_docum', 'caching',
'datetime'
);
// $this->check($schema, 'id', 'social_request_queue', 'social_a2_req_queue','last', 'datetime');
// $this->check($schema, 'id', 'social_queue_stream', 'social_a2_stream_queue', 'last', 'datetime');
$this->check(
$schema, 'id', 'social_server_notes', 'social_a2_stream', 'published_time',
'datetime'
);
}
private function check(
ISchemaWrapper $schema,
string $prim,
string $source,
string $dest,
string $field,
string $type
) {
if (!$schema->hasTable($source)) {
return;
}
$qb = $this->connection->getQueryBuilder();
$qb->select($prim, $field)
->from($source);
$cursor = $qb->execute();
while ($data = $cursor->fetch()) {
$this->fixMigration($dest, $prim, $field, $type, $data);
}
$cursor->closeCursor();
}
/**
* @param string $k
* @param array $arr
* @param string $default
*
* @return string
*/
private function get(string $k, array $arr, string $default = ''): string {
if ($arr === null) {
return $default;
}
if (!array_key_exists($k, $arr)) {
$subs = explode('.', $k, 2);
if (sizeof($subs) > 1) {
if (!array_key_exists($subs[0], $arr)) {
return $default;
}
$r = $arr[$subs[0]];
if (!is_array($r)) {
return $default;
}
return $this->get($subs[1], $r, $default);
} else {
return $default;
}
}
if ($arr[$k] === null || !is_string($arr[$k]) && (!is_int($arr[$k]))) {
return $default;
}
return (string)$arr[$k];
}
/**
* @param string $k
* @param array $arr
* @param bool $default
*
* @return bool
*/
protected function getBool(string $k, array $arr, bool $default = false): bool {
if ($arr === null) {
return $default;
}
if (!array_key_exists($k, $arr)) {
$subs = explode('.', $k, 2);
if (sizeof($subs) > 1) {
if (!array_key_exists($subs[0], $arr)) {
return $default;
}
return $this->getBool($subs[1], $arr[$subs[0]], $default);
} else {
return $default;
}
}
if ($arr[$k] === null) {
return $default;
}
if (is_bool($arr[$k])) {
return $arr[$k];
}
if ($arr[$k] === '1') {
return true;
}
if ($arr[$k] === '0') {
return false;
}
return $default;
}
//
//
// /**
// * @param string $table
// * @param array $fields
// * @param array $data
// *
// * @throws Exception
// */
// private function insertInto(string $table, array $fields, array $data) {
// $insert = $this->connection->getQueryBuilder();
// $insert->insert($table);
//
// $datetimeFields = [
// 'creation',
// 'last',
// 'caching',
// 'published_time'
// ];
//
// $booleanFields = [
// 'local',
// 'public',
// 'accepted',
// 'hidden_on_timeline'
// ];
//
// foreach ($fields as $field) {
// $value = $this->get($field, $data, '');
// if ($field === 'id_prim'
// && $value === ''
// && $this->get('id', $data, '') !== '') {
// $value = hash('sha512', $this->get('id', $data, ''));
// }
//
// if (in_array($field, $datetimeFields) && $value === '') {
// $insert->setValue(
// $field,
// $insert->createNamedParameter(new DateTime('now'), IQueryBuilder::PARAM_DATE)
// );
// } else if (in_array($field, $booleanFields) && $value === '') {
// $insert->setValue(
// $field, $insert->createNamedParameter('0')
// );
// } else {
// $insert->setValue(
// $field, $insert->createNamedParameter($value)
// );
// }
// }
//
// try {
// $insert->execute();
// } catch (UniqueConstraintViolationException $e) {
// }
// }
/**
* @param string $dest
* @param string $prim
* @param string $field
* @param string $type
* @param array $old
*/
private function fixMigration(
string $dest, string $prim, string $field, string $type, array $old
) {
// foreach ($fields as $field) {
// $value = $this->get($field, $data, '');
// if ($field === 'id_prim'
// && $value === ''
// && $this->get('id', $data, '') !== '') {
// $value = hash('sha512', $this->get('id', $data, ''));
// }
$current = $this->connection->getQueryBuilder();
$current->select($field)
->from($dest);
$cursor = $current->execute();
$data = $cursor->fetch();
$cursor->closeCursor();
if ($data === false) {
return;
}
switch ($type) {
case 'datetime':
$oldValue = $this->get($field, $old);
$oldId = $this->get($prim, $old);
$currValue = $this->get($field, $data, '');
if ($currValue !== '') {
return;
}
if ($oldValue === '') {
$oldValue = null;
}
$update = $this->connection->getQueryBuilder();
$update->update($dest);
$update->set($field, $update->createNamedParameter($oldValue));
$expr = $update->expr();
$update->where($expr->eq($prim, $update->createNamedParameter($oldId)));
try {
$update->execute();
} catch (Exception $e) {
}
break;
case 'boolean':
$oldValue = $this->getBool($field, $old);
$oldId = $this->get($prim, $old);
$update = $this->connection->getQueryBuilder();
$update->update($dest);
$update->set($field, $update->createNamedParameter(($oldValue) ? '1' : '0'));
$expr = $update->expr();
$update->where($expr->eq($prim, $update->createNamedParameter($oldId)));
$update->execute();
break;
}
}
}