Passed
Push — master ( 699f14...ba067d )
by y
01:34
created

TextTrait::trim()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
1
<?php
2
3
namespace Helix\DB\Fluent\Text;
4
5
use Helix\DB\Fluent\Num;
6
use Helix\DB\Fluent\Num\BaseConversionTrait;
7
use Helix\DB\Fluent\Text;
8
use Helix\DB\Fluent\Value\ValueTrait;
9
use Helix\DB\Fluent\ValueInterface;
10
11
/**
12
 * Character string expression manipulation.
13
 */
14
trait TextTrait
15
{
16
17
    use ValueTrait;
18
    use BaseConversionTrait;
19
20
    /**
21
     * @param int $direction
22
     * @param null|string $chars
23
     * @return Text
24
     * @internal
25
     */
26
    protected function _trim(int $direction, string $chars = null)
27
    {
28
        $function = [-1 => 'LTRIM', 0 => 'TRIM', 1 => 'RTRIM'][$direction];
29
        if (isset($chars)) {
30
            $chars = $this->db->quote($chars);
31
            if ($this->db->isSQLite()) {
32
                return Text::factory($this->db, "{$function}({$this},{$chars})");
33
            }
34
            $direction = [-1 => 'LEADING', 0 => 'BOTH', 1 => 'TRAILING'][$direction];
35
            return Text::factory($this->db, "TRIM({$direction} {$chars} FROM {$this})");
36
        }
37
        return Text::factory($this->db, "{$function}({$this})");
38
    }
39
40
    /**
41
     * Concatenate other strings.
42
     *
43
     * - SQLite: `($this || ...)`
44
     * - MySQL: `CONCAT($this, ...)`
45
     *
46
     * @param string|ValueInterface ...$strings
47
     * @return Text
48
     */
49
    public function concat(...$strings)
50
    {
51
        array_unshift($strings, $this);
52
        $strings = $this->db->quoteArray($strings);
53
        if ($this->db->isSQLite()) {
54
            return Text::factory($this->db, sprintf('(%s)', implode(' || ', $strings)));
55
        }
56
        return Text::factory($this->db, sprintf('CONCAT(%s)', implode(',', $strings)));
57
    }
58
59
    /**
60
     * Hex representation.
61
     *
62
     * `HEX($this)`
63
     *
64
     * @return Text
65
     */
66
    public function hex()
67
    {
68
        return Text::factory($this->db, "HEX({$this})");
69
    }
70
71
    /**
72
     * Number of characters (not necessarily bytes).
73
     *
74
     * @see TextTrait::size()
75
     *
76
     * @return Num
77
     */
78
    public function length()
79
    {
80
        if ($this->db->isSQLite()) {
81
            return Num::factory($this->db, "LENGTH(CAST({$this} AS TEXT))");
82
        }
83
        return Num::factory($this->db, "CHAR_LENGTH({$this})");
84
    }
85
86
    /**
87
     * Lowercase.
88
     *
89
     * `LOWER($this)`
90
     *
91
     * @return Text
92
     */
93
    public function lower()
94
    {
95
        return Text::factory($this->db, "LOWER({$this})");
96
    }
97
98
    /**
99
     * @see TextTrait::trim()
100
     * @param null|string $chars
101
     * @return Text
102
     */
103
    public function ltrim(string $chars = null)
104
    {
105
        return $this->_trim(-1, $chars);
106
    }
107
108
    /**
109
     * Substring's position (1-based).
110
     *
111
     * The position is `0` if the substring isn't found.
112
     *
113
     * @param string $substring
114
     * @return Num
115
     */
116
    public function position(string $substring)
117
    {
118
        $substring = $this->db->quote($substring);
119
        if ($this->db->isSQLite()) {
120
            return Num::factory($this->db, "INSTR({$this},{$substring})");
121
        }
122
        return Num::factory($this->db, "LOCATE({$substring},{$this})");
123
    }
124
125
    /**
126
     * String replacement.
127
     *
128
     * `REPLACE($this,$search,$replace)`
129
     *
130
     * @param string $search
131
     * @param string $replace
132
     * @return Text
133
     */
134
    public function replace(string $search, string $replace)
135
    {
136
        $search = $this->db->quote($search);
137
        $replace = $this->db->quote($replace);
138
        return Text::factory($this->db, "REPLACE({$this},{$search},{$replace})");
139
    }
140
141
    /**
142
     * @see TextTrait::trim()
143
     * @param null|string $chars
144
     * @return Text
145
     */
146
    public function rtrim(string $chars = null)
147
    {
148
        return $this->_trim(1, $chars);
149
    }
150
151
    /**
152
     * Size in bytes.
153
     *
154
     * @return Num
155
     */
156
    public function size()
157
    {
158
        if ($this->db->isSQLite()) {
159
            return Num::factory($this->db, "LENGTH(CAST({$this} AS BLOB))");
160
        }
161
        return Num::factory($this->db, "LENGTH({$this})");
162
    }
163
164
    /**
165
     * Substring.
166
     *
167
     * `SUBSTR($this,$start)` or `SUBSTR($this,$start,$length)`
168
     *
169
     * @param int $start 1-based, can be negative to start from the right.
170
     * @param null|int $length
171
     * @return Text
172
     */
173
    public function substr(int $start, int $length = null)
174
    {
175
        if (isset($length)) {
176
            return Text::factory($this->db, "SUBSTR({$this},{$start},{$length})");
177
        }
178
        return Text::factory($this->db, "SUBSTR({$this},{$start})");
179
    }
180
181
    /**
182
     * Convert from an arbitrary base to base 10.
183
     *
184
     * `CONV($this,$from,10)`
185
     *
186
     * @param int $from
187
     * @return Num
188
     */
189
    public function toBase10(int $from)
190
    {
191
        return Num::factory($this->db, "CONV({$this},{$from},10)");
192
    }
193
194
    /**
195
     * Trims whitespace (or other things) from both ends of the string.
196
     *
197
     * If `$chars` is given:
198
     * - SQLite treats it as individual characters (same as PHP)
199
     * - MySQL treats it as a leading/trailing string
200
     *
201
     * @see TextTrait::ltrim()
202
     * @see TextTrait::rtrim()
203
     * @param null|string $chars
204
     * @return Text
205
     */
206
    public function trim(string $chars = null)
207
    {
208
        return $this->_trim(0, $chars);
209
    }
210
211
    /**
212
     * Uppercase.
213
     *
214
     * `UPPER($this)`
215
     *
216
     * @return Text
217
     */
218
    public function upper()
219
    {
220
        return Text::factory($this->db, "UPPER({$this})");
221
    }
222
}
223