Passed
Push — dbal ( 65949b )
by Greg
14:44
created

WebtreesSchema::tableGedcom()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 8
nc 1
nop 2
dl 0
loc 11
rs 10
c 1
b 0
f 0
1
<?php
2
3
/**
4
 * webtrees: online genealogy
5
 * Copyright (C) 2022 webtrees development team
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
 * GNU General Public License for more details.
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16
 */
17
18
declare(strict_types=1);
19
20
namespace Fisharebest\Webtrees;
21
22
use Closure;
23
use Doctrine\DBAL\Connection;
24
use Doctrine\DBAL\DriverManager;
25
use Doctrine\DBAL\Query\QueryBuilder;
26
use Doctrine\DBAL\Schema\Schema;
27
use Doctrine\DBAL\Schema\SchemaConfig;
28
use Doctrine\DBAL\Schema\SchemaException;
29
use Doctrine\DBAL\Schema\Table;
30
use Doctrine\DBAL\Types\Types;
31
use ErrorException;
32
use Fisharebest\Webtrees\Factories\CacheFactory;
33
use Fisharebest\Webtrees\Factories\CalendarDateFactory;
34
use Fisharebest\Webtrees\Factories\ElementFactory;
35
use Fisharebest\Webtrees\Factories\EncodingFactory;
36
use Fisharebest\Webtrees\Factories\FamilyFactory;
37
use Fisharebest\Webtrees\Factories\FilesystemFactory;
38
use Fisharebest\Webtrees\Factories\GedcomRecordFactory;
39
use Fisharebest\Webtrees\Factories\HeaderFactory;
40
use Fisharebest\Webtrees\Factories\ImageFactory;
41
use Fisharebest\Webtrees\Factories\IndividualFactory;
42
use Fisharebest\Webtrees\Factories\LocationFactory;
43
use Fisharebest\Webtrees\Factories\MarkdownFactory;
44
use Fisharebest\Webtrees\Factories\MediaFactory;
45
use Fisharebest\Webtrees\Factories\NoteFactory;
46
use Fisharebest\Webtrees\Factories\RepositoryFactory;
47
use Fisharebest\Webtrees\Factories\ResponseFactory;
48
use Fisharebest\Webtrees\Factories\RouteFactory;
49
use Fisharebest\Webtrees\Factories\SharedNoteFactory;
50
use Fisharebest\Webtrees\Factories\SlugFactory;
51
use Fisharebest\Webtrees\Factories\SourceFactory;
52
use Fisharebest\Webtrees\Factories\SubmissionFactory;
53
use Fisharebest\Webtrees\Factories\SubmitterFactory;
54
use Fisharebest\Webtrees\Factories\SurnameTraditionFactory;
55
use Fisharebest\Webtrees\Factories\TimeFactory;
56
use Fisharebest\Webtrees\Factories\TimestampFactory;
57
use Fisharebest\Webtrees\Factories\IdFactory;
58
use Fisharebest\Webtrees\Factories\XrefFactory;
59
use Fisharebest\Webtrees\GedcomFilters\GedcomEncodingFilter;
60
use Fisharebest\Webtrees\Http\Middleware\BadBotBlocker;
61
use Fisharebest\Webtrees\Http\Middleware\BaseUrl;
62
use Fisharebest\Webtrees\Http\Middleware\BootModules;
63
use Fisharebest\Webtrees\Http\Middleware\CheckForMaintenanceMode;
64
use Fisharebest\Webtrees\Http\Middleware\CheckForNewVersion;
65
use Fisharebest\Webtrees\Http\Middleware\ClientIp;
66
use Fisharebest\Webtrees\Http\Middleware\CompressResponse;
67
use Fisharebest\Webtrees\Http\Middleware\ContentLength;
68
use Fisharebest\Webtrees\Http\Middleware\DoHousekeeping;
69
use Fisharebest\Webtrees\Http\Middleware\EmitResponse;
70
use Fisharebest\Webtrees\Http\Middleware\HandleExceptions;
71
use Fisharebest\Webtrees\Http\Middleware\LoadRoutes;
72
use Fisharebest\Webtrees\Http\Middleware\NoRouteFound;
73
use Fisharebest\Webtrees\Http\Middleware\ReadConfigIni;
74
use Fisharebest\Webtrees\Http\Middleware\RegisterGedcomTags;
75
use Fisharebest\Webtrees\Http\Middleware\Router;
76
use Fisharebest\Webtrees\Http\Middleware\SecurityHeaders;
77
use Fisharebest\Webtrees\Http\Middleware\UpdateDatabaseSchema;
78
use Fisharebest\Webtrees\Http\Middleware\UseDatabase;
79
use Fisharebest\Webtrees\Http\Middleware\UseLanguage;
80
use Fisharebest\Webtrees\Http\Middleware\UseSession;
81
use Fisharebest\Webtrees\Http\Middleware\UseTheme;
82
use Fisharebest\Webtrees\Http\Middleware\UseTransaction;
83
use Illuminate\Container\Container;
84
use Illuminate\Database\Capsule\Manager as DB;
85
use Illuminate\Database\Schema\Blueprint;
86
use Middleland\Dispatcher;
87
use Nyholm\Psr7\Factory\Psr17Factory;
88
use Nyholm\Psr7Server\ServerRequestCreator;
89
use Psr\Container\ContainerInterface;
90
use Psr\Http\Message\ResponseFactoryInterface;
91
use Psr\Http\Message\ResponseInterface;
92
use Psr\Http\Message\ServerRequestFactoryInterface;
93
use Psr\Http\Message\ServerRequestInterface;
94
use Psr\Http\Message\StreamFactoryInterface;
95
use Psr\Http\Message\UploadedFileFactoryInterface;
96
use Psr\Http\Message\UriFactoryInterface;
97
use Psr\Http\Server\MiddlewareInterface;
98
99
use function date_default_timezone_set;
100
use function error_reporting;
101
use function is_string;
102
use function mb_internal_encoding;
103
use function set_error_handler;
104
use function stream_filter_register;
105
106
use const E_ALL;
107
use const E_DEPRECATED;
108
use const E_USER_DEPRECATED;
109
110
/**
111
 * Definitions for the webtrees database.
112
 */
113
class WebtreesSchema extends  Schema
114
{
115
    private const OPTIONS = [
116
        //'charset'   => 'utf8mb4',
117
        'collation' => 'utf8mb4_unicode_ci',
118
    ];
119
120
    /**
121
     * @param Schema $schema
122
     * @param string $prefix
123
     *
124
     * @return Table
125
     * @throws SchemaException
126
     */
127
    private static function tableGedcom(Schema $schema, string $prefix): Table
128
    {
129
        $table = $schema->createTable($prefix . 'gedcom');
130
        $table->addColumn('gedcom_id', Types::INTEGER, ['autoincrement' => true]);
131
        $table->addColumn('gedcom_name', Types::STRING, ['length' => 255]);
132
        $table->addColumn('sort_order', Types::INTEGER, ['default' => 0]);
133
        $table->setPrimaryKey(['gedcom_id']);
134
        $table->addUniqueIndex(['gedcom_name']);
135
        $table->addIndex(['sort_order']);
136
137
        return $table;
138
    }
139
140
   /**
141
     * @param Schema $schema
142
     * @param string $prefix
143
     *
144
     * @return Table
145
     * @throws SchemaException
146
     */
147
    private static function tableGedcomSetting(Schema $schema, string $prefix): Table
148
    {
149
        $table = $schema->createTable($prefix . 'gedcom_setting');
150
        $table->addColumn('gedcom_id', Types::INTEGER);
151
        $table->addColumn('setting_name', Types::STRING, ['length' => 32]);
152
        $table->addColumn('setting_value', Types::STRING, ['length' => 255, 'platformOptions' => self::OPTIONS]);
153
        $table->setPrimaryKey(['gedcom_id', 'setting_name']);
154
155
        return $table;
156
    }
157
158
   /**
159
     * @param Schema $schema
160
     * @param string $prefix
161
     *
162
     * @return Table
163
     * @throws SchemaException
164
     */
165
    private static function tableSiteSetting(Schema $schema, string $prefix): Table
166
    {
167
        $table = $schema->createTable($prefix . 'site_setting');
168
        $table->addColumn('setting_name', Types::STRING, ['length' => 32]);
169
        $table->addColumn('setting_value', Types::STRING, ['length' => 2000, 'platformOptions' => self::OPTIONS]);
170
        $table->setPrimaryKey(['setting_name']);
171
172
        return $table;
173
    }
174
175
   /**
176
     * @param Schema $schema
177
     * @param string $prefix
178
     *
179
     * @return Table
180
     * @throws SchemaException
181
     */
182
    private static function tableUser(Schema $schema, string $prefix): Table
183
    {
184
        $table = $schema->createTable($prefix . 'user');
185
        $table->addColumn('user_id', Types::INTEGER, ['autoincrement' => true]);
186
        $table->addColumn('user_name', Types::STRING, ['length' => 32]);
187
        $table->addColumn('real_name', Types::STRING, ['length' => 64]);
188
        $table->addColumn('email', Types::STRING, ['length' => 64]);
189
        $table->addColumn('password', Types::STRING, ['length' => 128]);
190
        $table->setPrimaryKey(['user_id']);
191
        $table->addUniqueIndex(['user_name']);
192
        $table->addUniqueIndex(['email']);
193
194
        return $table;
195
    }
196
197
   /**
198
     * @param Schema $schema
199
     * @param string $prefix
200
     *
201
     * @return Table
202
     * @throws SchemaException
203
     */
204
    private static function tableUserGedcomSetting(Schema $schema, string $prefix): Table
205
    {
206
        $table = $schema->createTable($prefix . 'user_gedcom_setting');
207
        //$table->addOption('charset', 'utf8mb4');
208
        $table->addOption('collation', 'utf8mb4_bin');
209
        $table->addOption('create_options', self::OPTIONS);
210
        $table->addColumn('user_id', Types::INTEGER);
211
        $table->addColumn('gedcom_id', Types::INTEGER);
212
        $table->addColumn('setting_name', Types::STRING, ['length' => 32]);
213
        $table->addColumn('setting_value', Types::STRING, ['length' => 255]);
214
        $table->setPrimaryKey(['user_id', 'gedcom_id', 'setting_name']);
215
        $table->addIndex(['gedcom_id']);
216
217
        return $table;
218
    }
219
220
   /**
221
     * @param Schema $schema
222
     * @param string $prefix
223
     *
224
     * @return Table
225
     * @throws SchemaException
226
     */
227
    private static function tableUserSetting(Schema $schema, string $prefix): Table
228
    {
229
        $table = $schema->createTable($prefix . 'user_setting');
230
        //$table->addOption('charset', 'utf8mb4');
231
        $table->addOption('collation', 'utf8mb4_bin');
232
        $table->addOption('create_options', self::OPTIONS);
233
        $table->addColumn('user_id', Types::INTEGER);
234
        $table->addColumn('setting_name', Types::STRING, ['length' => 32]);
235
        $table->addColumn('setting_value', Types::STRING, ['length' => 255]);
236
        $table->setPrimaryKey(['user_id', 'setting_name']);
237
238
        return $table;
239
    }
240
241
    /**
242
     * @param Connection $connection
243
     * @param string     $prefix
244
     *
245
     * @return void
246
     *
247
     * @throws SchemaException
248
     * @throws \Doctrine\DBAL\Exception
249
     */
250
    public static function migrate(Connection $connection, string $prefix): void
251
    {
252
        $schema = new Schema();
253
254
        $gedcom              = self::tableGedcom($schema, $prefix);
255
        $gedcom_setting      = self::tableGedcomSetting($schema, $prefix);
256
        $site_setting        = self::tableSiteSetting($schema, $prefix);
0 ignored issues
show
Unused Code introduced by
The assignment to $site_setting is dead and can be removed.
Loading history...
257
        $user                = self::tableUser($schema, $prefix);
258
        $user_gedcom_setting = self::tableUserGedcomSetting($schema, $prefix);
259
        $user_setting        = self::tableUserSetting($schema, $prefix);
260
261
        $gedcom_setting->addForeignKeyConstraint($gedcom, ['gedcom_id'], ['gedcom_id'], ['onDelete' => 'CASCADE', 'onUpdate' => 'CASCADE']);
262
263
        $user_gedcom_setting->addForeignKeyConstraint($gedcom, ['gedcom_id'], ['gedcom_id'], ['onDelete' => 'CASCADE', 'onUpdate' => 'CASCADE']);
264
        $user_gedcom_setting->addForeignKeyConstraint($user, ['user_id'], ['user_id'], ['onDelete' => 'CASCADE', 'onUpdate' => 'CASCADE']);
265
266
        $user_setting->addForeignKeyConstraint($user, ['user_id'], ['user_id'], ['onDelete' => 'CASCADE', 'onUpdate' => 'CASCADE']);
267
268
        $schema_config = new SchemaConfig();
269
        $schema_config->setDefaultTableOptions(['create_options' => self::OPTIONS]);
270
        $user = $schema->createTable($prefix . 'users');
271
        $user->addOption('charset', 'utf8mb4');
272
        $user->addOption('collation', 'utf8mb4_unicode_bin');
273
        $user->addOption('engine', 'memory');
274
        $user->addColumn('user_id', Types::INTEGER, ['autoincrement' => true]);
275
        $user->addColumn('user_name', Types::STRING, ['length' => 32]);
276
        $user->addColumn('real_name', Types::STRING, ['length' => 64]);
277
        $user->addColumn('email', Types::STRING, ['length' => 64]);
278
        $user->addColumn('password', Types::STRING, ['length' => 128]);
279
        $user->setPrimaryKey(['user_id']);
280
        $user->addUniqueIndex(['user_name']);
281
        $user->addUniqueIndex(['email']);
282
283
        $platform = $connection->getDatabasePlatform();
284
285
        // Existing databases may have enum columns.
286
        $platform->registerDoctrineTypeMapping('enum', 'string');
287
288
        $schema_manager = $connection->createSchemaManager();
289
        $comparator = $schema_manager->createComparator();
290
        $difference = $comparator->compareSchemas($schema_manager->createSchema(), $schema);
291
        $queries = $difference->toSql($platform);
292
        foreach ($queries as $query) {
293
            echo '<p>' . $query . '</p>';
294
        }
295
296
    }
297
}
298