Completed
Pull Request — master (#49)
by Thomas
02:16
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
        switch ($name) {
117 117
            case 'name':
118 112
                return $this->columnDefinition['column_name'];
119 51
            case 'type':
120 28
                return $this->getType();
121 23
            case 'default':
122 14
                return $this->columnDefinition['column_default'];
123 12
            case 'nullable':
124 11
                return $this->columnDefinition['is_nullable'] === true ||
125 11
                       $this->columnDefinition['is_nullable'] === 'YES';
126
            default:
127 1
                return isset($this->columnDefinition[$name]) ? $this->columnDefinition[$name] : null;
128
        }
129
    }
130
131
    /**
132
     * Check if default value is given
133
     *
134
     * @return bool
135
     */
136 13
    public function hasDefault()
137
    {
138 13
        return $this->default !== null;
139
    }
140
141
    /**
142
     * Determine and return the type
143
     *
144
     * @return Type
145
     */
146 103
    public function getType()
147
    {
148 103
        if (!$this->type) {
149 103
            if (!isset($this->columnDefinition['type'])) {
150 7
                $class = self::getRegisteredType($this->columnDefinition);
151
            } else {
152 96
                $class = $this->columnDefinition['type'];
153
            }
154
155 103
            if ($class === null || !is_callable([ $class, 'factory' ])) {
156 6
                $class = Type\Text::class;
157
            }
158
159 103
            $this->type = call_user_func([ $class, 'factory' ], $this->dbal, $this->columnDefinition);
160
        }
161
162 103
        return $this->type;
163
    }
164
}
165