Completed
Push — master ( 8a9a36...5d30b0 )
by Ondřej
03:00
created

ProjectedRelationBase::__construct()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 16
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 16
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 10
nc 4
nop 2
1
<?php
2
declare(strict_types=1);
3
4
namespace Ivory\Relation;
5
6
abstract class ProjectedRelationBase extends StreamlinedRelation
7
{
8
    /** @var Column[] */
9
    private $projectedColumns;
10
    /** @var array map: column name => offset of the first column of the name, or {@link Tuple::AMBIGUOUS_COL} */
11
    private $projectedColNameMap;
12
13
    public function __construct(IRelation $source, array $columns)
14
    {
15
        parent::__construct($source);
16
        $this->projectedColumns = $columns;
17
18
        $this->projectedColNameMap = [];
19
        foreach ($columns as $colOffset => $col) {
20
            $colName = $col->getName();
21
            if ($colName !== null && $colName !== '') {
22
                $this->projectedColNameMap[$colName] = (isset($this->projectedColNameMap[$colName]) ?
23
                    Tuple::AMBIGUOUS_COL :
24
                    $colOffset
25
                );
26
            }
27
        }
28
    }
29
30
31
    /**
32
     * Converts a simple macro, as accepted, e.g., by {@link IRelation::project()}, to a PCRE.
33
     *
34
     * @param string $macroPattern the simple macro to convert
35
     * @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...
36
     * @return string PCRE equivalent to <tt>$macroPattern</tt>
37
     */
38
    protected static function simpleMacroPatternToPcre(string $macroPattern, int &$starCnt = null): string
39
    {
40
        $starCnt = 0;
41
        $pcre = '/^';
42
        $escaped = false;
43
        $lastLiteral = '';
44
        for ($i = 0; $i < strlen($macroPattern); $i++) {
45
            $c = $macroPattern[$i];
46
            if ($escaped) {
47
                $lastLiteral .= $c;
48
                $escaped = false;
49
            } else {
50
                switch ($c) {
51
                    case '\\':
52
                        $escaped = true;
53
                        break;
54
                    case '*':
55
                        $pcre .= preg_quote($lastLiteral, '/');
56
                        $lastLiteral = '';
57
                        $pcre .= '(.*)';
58
                        $starCnt++;
59
                        break;
60
                    default:
61
                        $lastLiteral .= $c;
62
                }
63
            }
64
        }
65
        if ($escaped) {
66
            $lastLiteral .= '\\';
67
        }
68
        $pcre .= preg_quote($lastLiteral, '/');
69
        $pcre .= '$/';
70
        return $pcre;
71
    }
72
73
    protected static function simpleMacroReplacementToPcre(string $macroReplacement): string
74
    {
75
        $repl = '';
76
        $stars = 0;
77
        $escaped = false;
78
        for ($i = 0; $i < strlen($macroReplacement); $i++) {
79
            $c = $macroReplacement[$i];
80
            if ($escaped) {
81
                if ($c == '$' || $c == '\\') {
82
                    $repl .= '\\';
83
                }
84
                $repl .= $c;
85
                $escaped = false;
86
            } else {
87
                switch ($c) {
88
                    case '\\':
89
                        $escaped = true;
90
                        break;
91
                    case '*':
92
                        $stars++;
93
                        $repl .= '${' . $stars . '}';
94
                        break;
95
                    /** @noinspection PhpMissingBreakStatementInspection */
96
                    case '$':
97
                        $repl .= '\\';
98
                        // no break
99
                    default:
100
                        $repl .= $c;
101
                }
102
            }
103
        }
104
        if ($escaped) {
105
            $repl .= '\\\\';
106
        }
107
108
        return $repl;
109
    }
110
111
112
    public function getColumns(): array
113
    {
114
        return $this->projectedColumns;
115
    }
116
117
    protected function getColNameMap(): array
118
    {
119
        return $this->projectedColNameMap;
120
    }
121
122
    public function col($offsetOrNameOrEvaluator): IColumn
123
    {
124
        return $this->_colImpl($offsetOrNameOrEvaluator, $this->projectedColumns, $this->projectedColNameMap, $this);
125
    }
126
127
    public function getIterator()
128
    {
129
        $cnt = $this->count();
130
        for ($i = 0; $i < $cnt; $i++) {
131
            yield $this->tuple($i);
132
        }
133
    }
134
}
135