Completed
Push — master ( 5be6f2...0a5d5e )
by Sébastien
03:56
created

AbstractMetadataReader::getTableMetadata()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 14
c 0
b 0
f 0
ccs 9
cts 9
cp 1
rs 9.4285
cc 2
eloc 9
nc 2
nop 1
crap 2
1
<?php
2
3
namespace Soluble\Metadata\Reader;
4
5
use Soluble\Metadata\ColumnsMetadata;
6
use Soluble\Metadata\Exception;
7
8
abstract class AbstractMetadataReader
9
{
10
    /**
11
     * Keep static cache in memory.
12
     *
13
     * @var bool
14
     */
15
    protected $cache_active = true;
16
17
    /**
18
     * @var array
19
     */
20
    protected static $metadata_cache = [];
21
22
    /**
23
     * @param bool $active
24
     *
25
     * @return AbstractMetadataReader
26
     */
27 1
    public function setStaticCache($active = true)
28
    {
29 1
        $this->cache_active = $active;
30
31 1
        return $this;
32
    }
33
34
    /**
35
     * Return columns metadata from query.
36
     *
37
     * @throws Exception\UnsupportedTypeException
38
     * @throws Exception\AmbiguousColumnException
39
     * @throws Exception\InvalidQueryException
40
     *
41
     * @param string $sql
42
     *
43
     * @return ColumnsMetadata
44
     */
45 18
    public function getColumnsMetadata($sql)
46
    {
47 18
        if ($this->cache_active) {
48 17
            $cache_key = md5($sql);
49 17
            if (!array_key_exists($cache_key, static::$metadata_cache)) {
50 11
                $md = $this->readColumnsMetadata($sql);
51 4
                static::$metadata_cache[$cache_key] = $md;
52 4
            }
53
54 10
            return static::$metadata_cache[$cache_key];
55
        }
56
57 1
        return $this->readColumnsMetadata($sql);
58
    }
59
60
    /**
61
     * Return columns metadata from a table.
62
     *
63
     * @throws Exception\UnsupportedTypeException
64
     * @throws Exception\AmbiguousColumnException
65
     * @throws Exception\TableNotFoundException
66
     *
67
     * @param string $table
68
     *
69
     * @return ColumnsMetadata
70
     */
71 2
    public function getTableMetadata($table)
72
    {
73
        try {
74 2
            $metadata = $this->getColumnsMetadata(sprintf('select * from %s', $table));
75 2
        } catch (Exception\InvalidQueryException $e) {
76 1
            throw new Exception\TableNotFoundException(sprintf(
77 1
                'Table "%s" does not exists (%s).',
78 1
                $table,
79 1
                $e->getMessage()
80 1
            ));
81
        }
82
83 1
        return $metadata;
84
    }
85
86
    /**
87
     * Read metadata information from source.
88
     *
89
     * @throws Exception\UnsupportedTypeException
90
     * @throws Exception\AmbiguousColumnException
91
     * @throws \Soluble\Metadata\Exception\InvalidQueryException
92
     *
93
     * @param string $sql
94
     *
95
     * @return ColumnsMetadata
96
     */
97
    abstract protected function readColumnsMetadata($sql);
98
99
    /**
100
     * Optimization, will add false condition to the query
101
     * so the metadata loading will be faster.
102
     *
103
     * @param string $sql query string
104
     *
105
     * @return string
106
     */
107 11
    protected function getEmptiedQuery($sql)
108
    {
109
        // see the reason why in Vision_Store_Adapter_ZendDbSelect::getMetaData
110
        //$sql = str_replace("('__innerselect'='__innerselect')", '(1=0)', $sql);
111
112 11
        $sql = preg_replace('/(\r\n|\r|\n|\t)+/', ' ', strtolower($sql));
113 11
        $sql = trim($sql);
114 11
        $sql = preg_replace('/\s+/', ' ', $sql);
115
116 11
        $replace_regexp = "LIMIT[\s]+[\d]+((\s*,\s*\d+)|(\s+OFFSET\s+\d+)){0,1}";
117
118 11
        $search_regexp = "$replace_regexp";
119 11
        if (!preg_match("/$search_regexp/i", $sql)) {
120
            // Limit is not already present
121 11
            $sql .= ' LIMIT 0';
122 11
        } else {
123
            // replace first if offset exists, then if not
124
            //preg_match_all("/($search_regexp)/i", $sql, $matches, PREG_PATTERN_ORDER);
125
            //var_dump($matches);
126
127 1
            $sql = preg_replace("/($replace_regexp)/i", 'LIMIT 0', $sql);
128
        }
129
130 11
        return $sql;
131
    }
132
}
133