Passed
Push — master ( fd358c...339072 )
by Ondřej
03:23
created

ProjectedRelationBase::getColNames()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
namespace Ivory\Relation;
3
4
abstract class ProjectedRelationBase extends StreamlinedRelation
5
{
6
    /** @var Column[] */
7
    private $projectedColumns;
8
    /** @var array map: column name => offset of the first column of the name, or {@link Tuple::AMBIGUOUS_COL} */
9
    private $projectedColNameMap;
10
11
    public function __construct(IRelation $source, array $columns)
12
    {
13
        parent::__construct($source);
14
        $this->projectedColumns = $columns;
15
16
        $this->projectedColNameMap = [];
17
        foreach ($columns as $colOffset => $col) {
18
            $colName = $col->getName();
19
            if (strlen($colName) > 0) {
20
                $this->projectedColNameMap[$colName] = (isset($this->projectedColNameMap[$colName]) ?
21
                    Tuple::AMBIGUOUS_COL :
22
                    $colOffset
23
                );
24
            }
25
        }
26
    }
27
28
29
    /**
30
     * Converts a simple macro, as accepted, e.g., by {@link IRelation::project()}, to a PCRE.
31
     *
32
     * @param string $macroPattern the simple macro to convert
33
     * @param int $starCnt number of star wildcards is stored here
0 ignored issues
show
Documentation introduced by
Should the type for parameter $starCnt not be null|integer?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
34
     * @return string PCRE equivalent to <tt>$macroPattern</tt>
35
     */
36
    protected static function simpleMacroPatternToPcre(string $macroPattern, int &$starCnt = null): string
37
    {
38
        $starCnt = 0;
39
        $pcre = '/^';
40
        $escaped = false;
41
        $lastLiteral = '';
42
        for ($i = 0; $i < strlen($macroPattern); $i++) {
43
            $c = $macroPattern[$i];
44
            if ($escaped) {
45
                $lastLiteral .= $c;
46
                $escaped = false;
47
            } else {
48
                switch ($c) {
49
                    case '\\':
50
                        $escaped = true;
51
                        break;
52
                    case '*':
53
                        $pcre .= preg_quote($lastLiteral, '/');
54
                        $lastLiteral = '';
55
                        $pcre .= '(.*)';
56
                        $starCnt++;
57
                        break;
58
                    default:
59
                        $lastLiteral .= $c;
60
                }
61
            }
62
        }
63
        if ($escaped) {
64
            $lastLiteral .= '\\';
65
        }
66
        $pcre .= preg_quote($lastLiteral, '/');
67
        $pcre .= '$/';
68
        return $pcre;
69
    }
70
71
    protected static function simpleMacroReplacementToPcre(string $macroReplacement): string
72
    {
73
        $repl = '';
74
        $stars = 0;
75
        $escaped = false;
76
        for ($i = 0; $i < strlen($macroReplacement); $i++) {
77
            $c = $macroReplacement[$i];
78
            if ($escaped) {
79
                if ($c == '$' || $c == '\\') {
80
                    $repl .= '\\';
81
                }
82
                $repl .= $c;
83
                $escaped = false;
84
            } else {
85
                switch ($c) {
86
                    case '\\':
87
                        $escaped = true;
88
                        break;
89
                    case '*':
90
                        $stars++;
91
                        $repl .= '${' . $stars . '}';
92
                        break;
93
                    /** @noinspection PhpMissingBreakStatementInspection */
94
                    case '$':
95
                        $repl .= '\\';
96
                        // no break
97
                    default:
98
                        $repl .= $c;
99
                }
100
            }
101
        }
102
        if ($escaped) {
103
            $repl .= '\\\\';
104
        }
105
106
        return $repl;
107
    }
108
109
110
    public function getColumns()
111
    {
112
        return $this->projectedColumns;
113
    }
114
115
    protected function getColNameMap()
116
    {
117
        return $this->projectedColNameMap;
118
    }
119
120
    public function col($offsetOrNameOrEvaluator): IColumn
121
    {
122
        return $this->_colImpl($offsetOrNameOrEvaluator, $this->projectedColumns, $this->projectedColNameMap, $this);
123
    }
124
125
    public function getIterator()
126
    {
127
        $cnt = $this->count();
128
        for ($i = 0; $i < $cnt; $i++) {
129
            yield $this->tuple($i);
130
        }
131
    }
132
}
133