Select::setDbAdapter()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1
Metric Value
dl 0
loc 5
ccs 3
cts 3
cp 1
rs 9.4285
cc 1
eloc 3
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Soluble\Db\Sql;
4
5
use Zend\Db\Sql\Sql;
6
use Zend\Db\Sql\Expression;
7
use Zend\Db\Sql\Predicate;
8
use Zend\Db\Sql\Select as ZendDbSqlSelect;
9
use Zend\Db\Adapter\Adapter;
10
use Zend\Db\Adapter\AdapterAwareInterface;
11
use Zend\Db\ResultSet\ResultSet;
12
13
class Select extends ZendDbSqlSelect implements AdapterAwareInterface
14
{
15
    /**
16
     *
17
     * @var Adapter
18
     */
19
    protected $adapter;
20
21
    /**
22
     * Constructor
23
     *
24
     * @param Adapter $adapter
25
     * @param  null|string|array|\Zend\Db\Sql\TableIdentifier $table
26
     */
27 103
    public function __construct(Adapter $adapter = null, $table = null)
28
    {
29 103
        if ($adapter) {
30
            $this->setDbAdapter($adapter);
31
        }
32 103
        parent::__construct($table);
33 103
    }
34
35
36
    /**
37
     * Create an where clause with 'OR'
38
     *
39
     * @param  \Zend\Db\Sql\Where|\Closure|string|array|Predicate\PredicateInterface $predicate
40
     * @throws Zend\Db\Sql\Exception\InvalidArgumentException
41
     * @return Select
42
     */
43 1
    public function orWhere($predicate)
44
    {
45 1
        return $this->where($predicate, Predicate\PredicateSet::OP_OR);
46
    }
47
48
49
50
    /**
51
     * Add table prefixed columns, will automatically
52
     * quote table parts identifiers found in the column name.
53
     * It provides an alternative for defining columns from multiple/joined
54
     * table in one go.
55
     *
56
     * <code>
57
     * $select->from(array('p' =>'product')
58
     *        ->prefixedColumns(array('product_title' => 'p.title'));
59
     * </code>
60
     * Possible valid states:
61
     *   array(value, ...)
62
     *     value can be strings or Expression objects
63
     *
64
     *   array(string => value, ...)
65
     *     key string will be use as alias,
66
     *     value can be string or Expression objects
67
     *
68
     * @throws Exception\InvalidArgumentException when usage not correct
69
     * @param  array $columns
70
     * @return Select
71
     */
72 11
    public function prefixedColumns(array $columns)
73
    {
74 11
        $pf = $this->adapter->getPlatform();
75 11
        $identifierSeparator = $pf->getIdentifierSeparator();
76 11
        $names = [];
77 11
        $cols = [];
78 11
        foreach ($columns as $alias => $column) {
79 11
            if (is_string($column)) {
80 11
                if (strpos($column, self::SQL_STAR) !== false) {
81 3
                    $msg = __METHOD__ . " Invalid argument, prefixedColumn() does not accept sql * column specification";
82 3
                    throw new Exception\InvalidArgumentException($msg);
83
                }
84 8
                $parts = explode($identifierSeparator, $column);
85 8
                if (count($parts) > 1) {
86 6
                    $quotedParts = [];
87 6
                    foreach ($parts as $part) {
88 6
                        $quotedParts[] = $pf->quoteIdentifier($part);
89 6
                    }
90
                    // to remove PHPAnalyzer warnings
91
                    //var_dump($quotedParts[count($quotedParts)-1]);
92
                    //die();
93 6
                    $last_part = $parts[count($parts)-1];
94
95 6
                    if (!is_string($alias)) {
96 5
                        $alias = $last_part;
97 5
                    }
98
99 6
                    if (in_array($alias, $names)) {
100 2
                        $msg = __METHOD__ . ": Invalid argument, multiple columns have the same alias ($alias)";
101 2
                        throw new Exception\InvalidArgumentException($msg);
102
                    }
103 6
                    $names[] = $alias;
104
105 6
                    $cols[$alias] = new Expression(implode($identifierSeparator, $quotedParts));
106 6
                } else {
107 2
                    if (in_array($alias, $names)) {
108 1
                        $msg = __METHOD__ . ": Invalid argument, multiple columns have the same alias ($alias)";
109 1
                        throw new Exception\InvalidArgumentException($msg);
110
                    }
111
112 1
                    $cols[$alias] = $column;
113 1
                    $names[] = $alias;
114
                }
115 7
            } else {
116 6
                if (in_array($alias, $names)) {
117 1
                    $msg = __METHOD__ . ": Invalid argument, multiple columns have the same alias ($alias)";
118 1
                    throw new Exception\InvalidArgumentException($msg);
119
                }
120
121 5
                $cols[$alias] = $column;
122 5
                $names[] = $alias;
123
            }
124 8
        }
125 4
        $this->columns($cols);
126 4
        return $this;
127
    }
128
129
130
131
    /**
132
     * Set database adapter
133
     *
134
     * @param Adapter $adapter
135
     * @return Select
136
     */
137 100
    public function setDbAdapter(Adapter $adapter)
138
    {
139 100
        $this->adapter = $adapter;
140 100
        return $this;
141
    }
142
143
    /**
144
     * Return an sql string accordingly to the internat database adapter
145
     *
146
     * @throws Exception\InvalidUsageException
147
     * @return string
148
     */
149 5
    public function getSql()
150
    {
151 5
        if ($this->adapter === null) {
152 2
            $msg = __METHOD__ . ": Error, prior to use execute method you must provide a valid database adapter. See Select::setDbAdapter() method.";
153 2
            throw new Exception\InvalidUsageException($msg);
154
        }
155 3
        $sql = new Sql($this->adapter);
156 3
        return $sql->getSqlStringForSqlObject($this);
157
    }
158
159
    /**
160
     * Execute the query and return a Zend\Db\Resultset\ResultSet object
161
     *
162
     * @throws Exception\InvalidUsageException
163
     * @return \Zend\Db\ResultSet\ResultSet
164
     */
165 81
    public function execute()
166
    {
167 81
        if ($this->adapter === null) {
168 1
            $msg = __METHOD__ . ": Error, prior to use execute method you must provide a valid database adapter. See Select::setDbAdapter() method.";
169 1
            throw new Exception\InvalidUsageException($msg);
170
        }
171 80
        $sql = new Sql($this->adapter);
172 80
        $sql_string = $sql->getSqlStringForSqlObject($this);
173
174
        //return $this->adapter->createStatement($sql_string)->execute();
175
        //return $this->adapter->query($sql_string, Adapter::QUERY_MODE_EXECUTE);
176 80
        $result = $this->adapter->getDriver()->getConnection()->execute($sql_string);
177 75
        $resultset = new ResultSet();
178 75
        $resultset->initialize($result);
179 75
        return $resultset;
180
    }
181
182
183
    /**
184
     * Return an sql string accordingly to the internat database adapter
185
     *
186
     * @throws Exception\InvalidUsageException
187
     * @return string
188
     */
189 2
    public function __toString()
190
    {
191 2
        return $this->getSql();
192
    }
193
}
194