Passed
Pull Request — main (#157)
by Martin
02:26
created

transformPostgresTextArrayToPHPArray()   A

Complexity

Conditions 6
Paths 1

Size

Total Lines 30
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 16
c 1
b 0
f 0
dl 0
loc 30
rs 9.1111
cc 6
nc 1
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace MartinGeorgiev\Utils;
6
7
/**
8
 * Util class with helpers for working with PostgreSql data structures.
9
 *
10
 * @since 0.9
11
 *
12
 * @author Martin Georgiev <[email protected]>
13
 */
14
class DataStructure
15
{
16
    /**
17
     * This method supports only single-dimensioned text arrays and
18
     * relays on the default escaping strategy in PostgreSql (double quotes).
19
     */
20
    public static function transformPostgresTextArrayToPHPArray(string $postgresArray): array
21
    {
22
        $transform = static function (string $textArrayToTransform): array {
23
            $indicatesMultipleDimensions = \mb_strpos($textArrayToTransform, '},{') !== false
24
                || \mb_strpos($textArrayToTransform, '{{') === 0;
25
            if ($indicatesMultipleDimensions) {
26
                throw new \InvalidArgumentException('Only single-dimensioned arrays are supported');
27
            }
28
29
            $phpArray = \str_getcsv(\trim($textArrayToTransform, '{}'), escape: '\\');
30
            foreach ($phpArray as $i => $text) {
31
                if ($text === null) {
32
                    unset($phpArray[$i]);
33
34
                    break;
35
                }
36
37
                if (!\is_string($text)) {
38
                    $exceptionMessage = 'Unsupported data type encountered. Expected null, integer, float or string value. Instead it is "%s".';
39
40
                    throw new \InvalidArgumentException(\sprintf($exceptionMessage, \gettype($text)));
41
                }
42
43
                $phpArray[$i] = \stripslashes(\str_replace('\"', '"', $text));
44
            }
45
46
            return $phpArray;
47
        };
48
49
        return $transform($postgresArray);
50
    }
51
52
    /**
53
     * This method supports only single-dimensioned PHP arrays.
54
     * This method relays on the default escaping strategy in PostgreSql (double quotes).
55
     *
56
     * @see https://stackoverflow.com/a/5632171/3425372 Kudos to jmz for the inspiration
57
     */
58
    public static function transformPHPArrayToPostgresTextArray(array $phpArray): string
59
    {
60
        $transform = static function (array $phpArrayToTransform): string {
61
            $result = [];
62
            foreach ($phpArrayToTransform as $text) {
63
                if (\is_array($text)) {
64
                    throw new \InvalidArgumentException('Only single-dimensioned arrays are supported');
65
                }
66
67
                $escapedText = \is_numeric($text) || \ctype_digit($text) ? $text : \sprintf('"%s"', \addcslashes($text, '"\\'));
68
                $result[] = $escapedText;
69
            }
70
71
            return '{'.\implode(',', $result).'}';
72
        };
73
74
        return $transform($phpArray);
75
    }
76
}
77