Issues (41)

code/PostgreSQLQuery.php (1 issue)

1
<?php
2
3
namespace SilverStripe\PostgreSQL;
4
5
use SilverStripe\ORM\Connect\Query;
6
7
/**
8
 * A result-set from a PostgreSQL database.
9
 *
10
 * @package sapphire
11
 * @subpackage model
12
 */
13
class PostgreSQLQuery extends Query
14
{
15
    /**
16
     * The internal Postgres handle that points to the result set.
17
     * @var resource
18
     */
19
    private $handle;
20
21
    private $columnNames = [];
22
23
    /**
24
     * Mapping of postgresql types to PHP types
25
     * Note that the bool => int mapping is by design, designed to mimic MySQL's behaviour
26
     * @var array
27
     */
28
    protected static $typeMapping = [
29
        'bool' => 'int',
30
        'int2' => 'int',
31
        'int4' => 'int',
32
        'int8' => 'int',
33
        'float4' => 'float',
34
        'float8' => 'float',
35
        'numeric' => 'float',
36
    ];
37
38
    /**
39
     * Hook the result-set given into a Query class, suitable for use by sapphire.
40
     * @param resource $handle the internal Postgres handle that is points to the resultset.
41
     */
42
    public function __construct($handle)
43
    {
44
        $this->handle = $handle;
45
46
        $numColumns = pg_num_fields($handle);
47
        for ($i = 0; $i < $numColumns; $i++) {
48
            $this->columnNames[$i] = pg_field_name($handle, $i);
49
        }
50
    }
51
52
    public function __destruct()
53
    {
54
        if (is_resource($this->handle)) {
55
            pg_free_result($this->handle);
56
        }
57
    }
58
59
    public function getIterator()
60
    {
61
        pg_result_seek($this->handle, 0);
62
        while ($data = $this->nextRecord()) {
63
            yield $data;
64
        }
65
    }
66
67
    public function numRecords()
68
    {
69
        return pg_num_rows($this->handle);
70
    }
71
72
    public function nextRecord()
73
    {
74
        $row = pg_fetch_array($this->handle, null, PGSQL_NUM);
75
76
        // Correct non-string types
77
        if ($row) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $row of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
78
            return $this->parseResult($row);
79
        }
80
81
        return false;
82
    }
83
84
    /**
85
     * @param array $row
86
     * @return array
87
     */
88
    protected function parseResult(array $row)
89
    {
90
        $record = [];
91
92
        foreach ($row as $i => $v) {
93
            $k = $this->columnNames[$i];
94
            $record[$k] = $v;
95
            $type = pg_field_type($this->handle, $i);
96
            if (isset(self::$typeMapping[$type])) {
97
                if ($type === 'bool' && $record[$k] === 't') {
98
                    $record[$k] = 1;
99
100
                    // Note that boolean 'f' will be converted to 0 by this
101
                } else {
102
                    settype($record[$k], self::$typeMapping[$type]);
103
                }
104
            }
105
        }
106
107
        return $record;
108
    }
109
}
110