Completed
Push — master ( 4370c7...e76084 )
by Thomas
22s queued 10s
created

Column::validate()   A

Complexity

Conditions 6
Paths 5

Size

Total Lines 21
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 6

Importance

Changes 0
Metric Value
eloc 10
dl 0
loc 21
ccs 11
cts 11
cp 1
rs 9.2222
c 0
b 0
f 0
cc 6
nc 5
nop 1
crap 6
1
<?php
2
3
namespace ORM\Dbal;
4
5
use ORM\Dbal\Error\NotValid;
6
7
/**
8
 * Describes a column of a database table
9
 *
10
 * @package ORM\Dbal
11
 * @author  Thomas Flori <[email protected]>
12
 *
13
 * @property string name
14
 * @property Type   type
15
 * @property mixed  default
16
 * @property bool   nullable
17
 */
18
class Column
19
{
20
    /** @var string[] */
21
    protected static $registeredTypes = [];
22
23
    /**
24
     * Register $type for describe
25
     *
26
     * @param string $type The full qualified class name
27
     */
28 7
    public static function registerType($type)
29
    {
30 7
        if (!in_array($type, static::$registeredTypes)) {
31 7
            array_unshift(static::$registeredTypes, $type);
32
        }
33 7
    }
34
35
    /**
36
     * Get the registered type for $columnDefinition
37
     *
38
     * @param array $columnDefinition
39
     * @return string
40
     */
41 7
    protected static function getRegisteredType(array $columnDefinition)
42
    {
43 7
        foreach (self::$registeredTypes as $class) {
44 4
            if (call_user_func([ $class, 'fits' ], $columnDefinition)) {
45 4
                return $class;
46
            }
47
        }
48
49 6
        return null;
50
    }
51
52
    /** @var array */
53
    protected $columnDefinition;
54
55
    /** @var Dbal */
56
    protected $dbal;
57
58
    /** @var TypeInterface */
59
    protected $type;
60
61
    /** @var bool */
62
    protected $hasDefault;
63
64
    /** @var bool */
65
    protected $isNullable;
66
67
    /**
68
     * Column constructor.
69
     *
70
     * @param Dbal  $dbal
71
     * @param array $columnDefinition
72
     */
73 136
    public function __construct(Dbal $dbal, array $columnDefinition)
74
    {
75 136
        $this->dbal             = $dbal;
76 136
        $this->columnDefinition = $columnDefinition;
77 136
    }
78
79
    /**
80
     * Check if $value is valid for this type
81
     *
82
     * @param mixed $value
83
     * @return boolean|Error
84
     */
85 7
    public function validate($value)
86
    {
87 7
        if ($value === null) {
88 4
            if ($this->nullable || $this->hasDefault()) {
89 3
                return true;
90
            }
91
92 2
            return new Error\NotNullable($this);
93
        }
94
95 4
        $valid = $this->getType()->validate($value);
96
97 4
        if ($valid === false) {
98 1
            return new NotValid($this, new Error());
99
        }
100
101 3
        if ($valid instanceof Error) {
102 1
            return new NotValid($this, $valid);
103
        }
104
105 2
        return true;
106
    }
107
108
    /**
109
     * Get attributes from column
110
     *
111
     * @param string $name
112
     * @return mixed
113
     */
114 117
    public function __get($name)
115
    {
116
        $method = [$this, 'get' . ucfirst($name)];
117 117
        return is_callable($method) ? call_user_func($method) :
118 112
            (isset($this->columnDefinition[$name]) ? $this->columnDefinition[$name] : null);
119 51
    }
120 28
121 23
    /**
122 14
     * Get the name of the column
123 12
     *
124 11
     * @return string
125 11
     */
126
    public function getName()
127 1
    {
128
        return $this->columnDefinition['column_name'];
129
    }
130
131
    /**
132
     * Get the default value of the column
133
     *
134
     * @return mixed
135
     */
136 13
    public function getDefault()
137
    {
138 13
        return $this->columnDefinition['column_default'];
139
    }
140
141
    /**
142
     * Check if the column is nullable
143
     *
144
     * @return bool
145
     */
146 103
    public function isNullable()
147
    {
148 103
        return $this->columnDefinition['is_nullable'] === true ||
149 103
               $this->columnDefinition['is_nullable'] === 'YES';
150 7
    }
151
152 96
    /**
153
     * Get the nullable status of the column
154
     *
155 103
     * @return bool
156 6
     */
157
    public function getNullable()
158
    {
159 103
        return $this->isNullable();
160
    }
161
162 103
    /**
163
     * Check if default value is given
164
     *
165
     * @return bool
166
     */
167
    public function hasDefault()
168
    {
169
        return $this->default !== null;
170
    }
171
172
    /**
173
     * Determine and return the type
174
     *
175
     * @return Type
176
     */
177
    public function getType()
178
    {
179
        if (!$this->type) {
180
            if (!isset($this->columnDefinition['type'])) {
181
                $class = self::getRegisteredType($this->columnDefinition);
182
            } else {
183
                $class = $this->columnDefinition['type'];
184
            }
185
186
            if ($class === null || !is_callable([ $class, 'factory' ])) {
187
                $class = Type\Text::class;
188
            }
189
190
            $this->type = call_user_func([ $class, 'factory' ], $this->dbal, $this->columnDefinition);
191
        }
192
193
        return $this->type;
194
    }
195
}
196