Passed
Push — master ( 565c26...461f06 )
by Aleksei
02:34
created

MigrationsTable::isTableExists()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
/**
4
 * Spiral Framework.
5
 *
6
 * @license MIT
7
 * @author  Anton Titov (Wolfy-J)
8
 */
9
10
declare(strict_types=1);
11
12
namespace Cycle\Migrations\Migrator;
13
14
use Cycle\Database\Database;
15
use Cycle\Database\Schema\AbstractTable;
16
17
/**
18
 * This class is responsible for managing the migration table within a
19
 * specific database.
20
 *
21
 * @internal MigrationsTable is an internal library class, please do not use it in your code.
22
 * @psalm-internal Cycle\Migrations
23
 */
24
class MigrationsTable
25
{
26
    /**
27
     * List of fields in the migration table. An implementation is specified in
28
     * the {@see MigrationsTable::actualize()} method.
29
     *
30
     * @var array<non-empty-string>
31
     */
32
    private const MIGRATION_TABLE_FIELDS = [
33
        'id',
34
        'migration',
35
        'time_executed',
36
        'created_at'
37
    ];
38
39
    /**
40
     * List of indices in the migration table. An implementation is specified in
41
     * the {@see MigrationsTable::actualize()} method.
42
     *
43
     * @var array<non-empty-string>
44
     */
45
    private const MIGRATION_TABLE_INDICES = [
46
        'migration',
47
        'created_at'
48
    ];
49
50
    /**
51
     * @var Database
52
     */
53
    private $db;
54
55
    /**
56
     * @var string
57
     */
58
    private $name;
59
60
    /**
61
     * @var AbstractTable
62
     */
63
    private $schema;
64
65
    /**
66
     * @param Database $db
67
     * @param string $name
68
     */
69
    public function __construct(Database $db, string $name)
70
    {
71
        $this->db = $db;
72
        $this->name = $name;
73
74
        $table = $db->table($name);
75
        $this->schema = $table->getSchema();
76
    }
77
78
    /**
79
     * Schema update will automatically sync all needed data.
80
     *
81
     * Please note that if you change this migration, you will also need to
82
     * change the list of fields in this migration specified in
83
     * the {@see MigrationsTable::MIGRATION_TABLE_FIELDS}
84
     * and {@see MigrationsTable::MIGRATION_TABLE_INDICES} constants.
85
     *
86
     * @return void
87
     */
88
    public function actualize(): void
89
    {
90
        $this->schema->primary('id');
91
        $this->schema->string('migration', 191)->nullable(false);
92
        $this->schema->datetime('time_executed')->datetime();
93
        $this->schema->datetime('created_at')->datetime();
94
95
        $this->schema->index(['migration', 'created_at'])
96
            ->unique(true);
97
98
        if ($this->schema->hasIndex(['migration'])) {
99
            $this->schema->dropIndex(['migration']);
100
        }
101
102
        $this->schema->save();
103
    }
104
105
    /**
106
     * Returns {@see true} if the migration table in the database is up to date
107
     * or {@see false} instead.
108
     *
109
     * @return bool
110
     */
111
    public function isPresent(): bool
112
    {
113
        if (!$this->isTableExists()) {
114
            return false;
115
        }
116
117
        if (!$this->isNecessaryColumnsExists()) {
118
            return false;
119
        }
120
121
        if (!$this->isNecessaryIndicesExists()) {
122
            return false;
123
        }
124
125
        return true;
126
    }
127
128
    /**
129
     * Returns {@see true} if the migration's table exists or {@see false}
130
     * instead.
131
     *
132
     * @return bool
133
     */
134
    private function isTableExists(): bool
135
    {
136
        return $this->db->hasTable($this->name);
137
    }
138
139
    /**
140
     * Returns {@see true} if all migration's fields is present or {@see false}
141
     * otherwise.
142
     *
143
     * @return bool
144
     */
145
    private function isNecessaryColumnsExists(): bool
146
    {
147
        foreach (self::MIGRATION_TABLE_FIELDS as $field) {
148
            if (!$this->schema->hasColumn($field)) {
149
                return false;
150
            }
151
        }
152
153
        return true;
154
    }
155
156
    /**
157
     * Returns {@see true} if all migration's indices is present or {@see false}
158
     * otherwise.
159
     *
160
     * @return bool
161
     */
162
    private function isNecessaryIndicesExists(): bool
163
    {
164
        return $this->schema->hasIndex(self::MIGRATION_TABLE_INDICES);
165
    }
166
}
167