AbstractType::mapType()
last analyzed

Size

Total Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 1
ccs 0
cts 0
cp 0
c 0
b 0
f 0
nc 1
1
<?php
2
namespace Nkey\Caribu\Type;
3
4
use Nkey\Caribu\Orm\Orm;
5
6
/**
7
 * Abstract database type
8
 *
9
 * This class is part of Caribu package
10
 *
11
 * @author Maik Greubel <[email protected]>
12
 */
13
abstract class AbstractType implements IType
14
{
15
    /**
16
     * Include generics interpolation functionality
17
     */
18
    use \Generics\Util\Interpolator;
19
20
    /**
21
     * Interpolate a string
22
     *
23
     * @param string $string
24
     *            The string to interpolate
25
     * @param array $context
26
     *            The context variables and values to replace
27
     *            
28
     * @return string The interpolated string
29
     */
30 13
    protected function interp(string $string, array $context): string
31
    {
32 13
        return $this->interpolate($string, $context);
33
    }
34
35
    /**
36
     * Retrieve primary key column for given table
37
     *
38
     * @param Orm $orm
39
     *            The Orm instance
40
     * @param string $table
41
     *            The name of tablee
42
     * @param string $query
43
     *            The sql query which retrieves the column name
44
     *            
45
     * @return string The column name
46
     *        
47
     * @throws \Nkey\Caribu\Orm\OrmException
48
     */
49 2
    protected function getPrimaryColumnViaSql(\Nkey\Caribu\Orm\Orm $orm, string $table, string $query): string
50
    {
51 2
        $sql = $this->interp($query, array(
52 2
            'table' => $table,
53 2
            'schema' => $orm->getSchema()
54
        ));
55
        
56 2
        $name = null;
57
        try {
58 2
            $stmt = $orm->getConnection()->query($sql);
59 2
            $stmt->setFetchMode(\PDO::FETCH_ASSOC);
60 2
            $count = 0;
61 2
            while ($result = $stmt->fetch()) {
62 2
                $name = $result['column_name'];
63 2
                $count ++;
64
            }
65 2
            $stmt->closeCursor();
66
            
67 2
            if ($count > 1) {
68
                throw new \Nkey\Caribu\Orm\OrmException("Table {table} contains more than one primary key! Please annotate!", array(
69 2
                    'table' => $table
70
                ));
71
            }
72
        } catch (\PDOException $exception) {
73
            throw \Nkey\Caribu\Orm\OrmException::fromPrevious($exception);
74
        }
75
        
76 2
        return $name;
77
    }
78
79
    /**
80
     * Change the locks on table or row via sql
81
     *
82
     * @param Orm $orm
83
     *            The Orm instance
84
     * @param string $table
85
     *            The table name
86
     * @param string $sql
87
     *            The sql to execute for changing the lock level
88
     *            
89
     * @throws \Nkey\Caribu\Orm\OrmException
90
     */
91 8
    protected function changeLockViaSql(\Nkey\Caribu\Orm\Orm $orm, string $table, string $sql)
92
    {
93 8
        $connection = $orm->getConnection();
94
        
95
        try {
96 8
            if ($connection->exec($sql) === false) {
97
                throw new \Nkey\Caribu\Orm\OrmException("Could not change lock type table {table}", array(
98 8
                    'table' => $table
99
                ));
100
            }
101
        } catch (\PDOException $exception) {
102
            throw \Nkey\Caribu\Orm\OrmException::fromPrevious($exception, "Could not change lock type of table");
103
        }
104 8
    }
105
106
    /**
107
     * Map the type result from statement into an orm type
108
     *
109
     * @param array $result            
110
     *
111
     * @return int The orm type mapped
112
     */
113
    abstract protected function mapType(array $result): int;
114
115
    /**
116
     * Retrieve query which is results a mapable type from database
117
     *
118
     * @return string The query
119
     */
120
    abstract protected function getTypeQuery(): string;
121
122
    /**
123
     * (non-PHPdoc)
124
     *
125
     * @see \Nkey\Caribu\Type\IType::getColumnType()
126
     */
127 6
    public function getColumnType(string $table, string $columnName, \Nkey\Caribu\Orm\Orm $orm): int
128
    {
129 6
        $sql = $this->interp($this->getTypeQuery(), array(
130 6
            'table' => $table,
131 6
            'schema' => $orm->getSchema(),
132 6
            'column' => $columnName
133
        ));
134
        
135 6
        $stmt = null;
136
        try {
137 6
            $stmt = $orm->getConnection()->query($sql);
138 6
            $stmt->setFetchMode(\PDO::FETCH_ASSOC);
139
            
140 6
            $result = $stmt->fetch();
141
            
142 6
            $this->handleNoColumn($table, $columnName, $orm, $stmt, $result);
143
            
144 6
            $type = $this->mapType($result);
145
            
146 6
            $stmt->closeCursor();
147
        } catch (\PDOException $exception) {
148
            if ($stmt) {
149
                $stmt->closeCursor();
150
            }
151
            throw \Nkey\Caribu\Orm\OrmException::fromPrevious($exception);
152
        }
153
        
154 6
        return $type;
155
    }
156
157
    /**
158
     * Handle empty result while query table column
159
     *
160
     * @param string $table
161
     *            The name of table
162
     * @param string $columnName
163
     *            The name of column
164
     * @param Orm $orm
165
     *            The orm instance
166
     * @param \PDOStatement $stmt
167
     *            The prepared statement
168
     * @param array $result
169
     *            The result either filled or empty
170
     *            
171
     * @throws \Nkey\Caribu\Orm\OrmException
172
     */
173 6
    protected function handleNoColumn(string $table, string $columnName, \Nkey\Caribu\Orm\Orm $orm, \PDOStatement $stmt, array $result)
174
    {
175 6
        if (false === $result) {
176
            $stmt->closeCursor();
177
            throw new \Nkey\Caribu\Orm\OrmException("No such column {column} in {schema}.{table}", array(
178
                'column' => $columnName,
179
                'schema' => $orm->getSchema(),
180
                'table' => $table
181
            ));
182
        }
183 6
    }
184
}
185