Completed
Branch feature/pre-split (f8e7b8)
by Anton
04:02
created

QueryBuilder::iocContainer()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * Spiral Framework.
4
 *
5
 * @license   MIT
6
 * @author    Anton Titov (Wolfy-J)
7
 */
8
9
namespace Spiral\Database\Builders;
10
11
use Interop\Container\ContainerInterface;
12
use Spiral\Core\Component;
13
use Spiral\Database\Entities\Driver;
14
use Spiral\Database\Entities\QueryCompiler;
15
use Spiral\Database\Exceptions\BuilderException;
16
use Spiral\Database\Helpers\QueryInterpolator;
17
use Spiral\Database\Injections\ExpressionInterface;
18
use Spiral\Database\Injections\ParameterInterface;
19
20
/**
21
 * QueryBuilder classes generate set of control tokens for query compilers, this is query level
22
 * abstraction.
23
 */
24
abstract class QueryBuilder extends Component implements ExpressionInterface
25
{
26
    /**
27
     * @invisible
28
     *
29
     * @var Driver
30
     */
31
    protected $driver = null;
32
33
    /**
34
     * @invisible
35
     *
36
     * @var QueryCompiler
37
     */
38
    protected $compiler = null;
39
40
    /**
41
     * @param Driver        $driver   Associated driver.
42
     * @param QueryCompiler $compiler Driver specific QueryCompiler instance (one per builder).
43
     */
44
    public function __construct(Driver $driver, QueryCompiler $compiler)
45
    {
46
        $this->driver = $driver;
47
        $this->compiler = $compiler;
48
    }
49
50
    /**
51
     * {@inheritdoc}
52
     *
53
     * @param QueryCompiler $compiler Associated compiled to be used by default.
54
     */
55
    abstract public function sqlStatement(QueryCompiler $compiler = null): string;
56
57
    /**
58
     * Get ordered list of builder parameters in a form of ParameterInterface array.
59
     *
60
     * @param QueryCompiler $compiler Compiler is needed to validly sort parameters from different
61
     *                                query parts (potentially deprecated). Associated compiled to
62
     *                                be used by default.
63
     *
64
     * @return array|ParameterInterface[]
65
     *
66
     * @throws BuilderException
67
     */
68
    abstract public function getParameters(QueryCompiler $compiler = null): array;
69
70
    /**
71
     * Get interpolated (populated with parameters) SQL which will be run against database, please
72
     * use this method for debugging purposes only.
73
     *
74
     * @return string
75
     */
76
    public function queryString(): string
77
    {
78
        return QueryInterpolator::interpolate($this->sqlStatement(), $this->getParameters());
79
    }
80
81
    /**
82
     * @return string
83
     */
84
    public function __toString(): string
85
    {
86
        return $this->sqlStatement();
87
    }
88
89
    /**
90
     * @return array
91
     */
92
    public function __debugInfo()
93
    {
94
        try {
95
            $queryString = $this->queryString();
96
        } catch (\Exception $e) {
97
            $queryString = "[ERROR: {$e->getMessage()}]";
98
        }
99
100
        $debugInfo = [
101
            'statement' => $queryString,
102
            'compiler'  => $this->compiler,
103
            'driver'    => $this->driver,
104
        ];
105
106
        return $debugInfo;
107
    }
108
109
    /**
110
     * Helper methods used to correctly fetch and split identifiers provided by function
111
     * parameters.
112
     * It support array list, string or comma separated list. Attention, this method will not work
113
     * with complex parameters (such as functions) provided as one comma separated string, please
114
     * use arrays in this case.
115
     *
116
     * @param array $identifiers
117
     *
118
     * @return array
119
     */
120
    protected function fetchIdentifiers(array $identifiers): array
121
    {
122
        if (count($identifiers) == 1 && is_string($identifiers[0])) {
123
            return array_map('trim', explode(',', $identifiers[0]));
124
        }
125
126
        if (count($identifiers) == 1 && is_array($identifiers[0])) {
127
            return $identifiers[0];
128
        }
129
130
        return $identifiers;
131
    }
132
133
    /**
134
     * Expand all QueryBuilder parameters to create flatten list.
135
     *
136
     * @param array $parameters
137
     *
138
     * @return array
139
     */
140
    protected function flattenParameters(array $parameters): array
141
    {
142
        $result = [];
143
        foreach ($parameters as $parameter) {
144
            if ($parameter instanceof self) {
145
                $result = array_merge($result, $parameter->getParameters());
146
                continue;
147
            }
148
149
            $result[] = $parameter;
150
        }
151
152
        return $result;
153
    }
154
155
    /**
156
     * Generate PDO statement based on generated sql and parameters.
157
     *
158
     * @return \PDOStatement
159
     */
160
    protected function pdoStatement(): \PDOStatement
161
    {
162
        return $this->driver->statement($this->sqlStatement(), $this->getParameters());
163
    }
164
165
    /**
166
     * @return ContainerInterface
167
     */
168
    protected function iocContainer()
169
    {
170
        //Falling back to driver specific container
171
        return $this->driver->iocContainer();
1 ignored issue
show
Bug introduced by
The method iocContainer() cannot be called from this context as it is declared protected in class Spiral\Core\Component.

This check looks for access to methods that are not accessible from the current context.

If you need to make a method accessible to another context you can raise its visibility level in the defining class.

Loading history...
172
    }
173
}
174