Select::generateSelect()   B
last analyzed

Complexity

Conditions 7
Paths 10

Size

Total Lines 29
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 15
nc 10
nop 0
dl 0
loc 29
rs 8.8333
c 0
b 0
f 0
1
<?php
2
3
namespace BfwSql\Queries;
4
5
use \BfwSql\SqlConnect;
6
7
/**
8
 * Class to write SELECT queries
9
 * 
10
 * @package bfw-sql
11
 * @author Vermeulen Maxime <[email protected]>
12
 * @version 2.0
13
 * 
14
 * @method \BfwSql\Queries\Select subQuery(string $shortcut, string|\BfwSql\Queries\AbstractQuery $subQuery)
15
 * @method \BfwSql\Queries\Select from(string|array $nameInfos, string|array|null $columns=null)
16
 * @method \BfwSql\Queries\Select fromColumns(array $columns)
17
 * @method \BfwSql\Queries\Select order(string $expr, string|null $sort = 'ASC')
18
 * @method \BfwSql\Queries\Select limit([int $offset,] int $rowCount)
19
 * @method \BfwSql\Queries\Select group(string $expr)
20
 */
21
class Select extends AbstractQuery
22
{
23
    use JoinTrait;
24
    
25
    /**
26
     * {@inheritdoc}
27
     */
28
    protected $requestType = 'select';
29
    
30
    /**
31
     * Constructor
32
     * 
33
     * @param \BfwSql\SqlConnect $sqlConnect Instance of SGBD connexion
34
     * @param string             $returnType PHP type used for return result
35
     */
36
    public function __construct(SqlConnect $sqlConnect, string $returnType)
37
    {
38
        parent::__construct($sqlConnect);
39
        
40
        $usedClass      = \BfwSql\UsedClass::getInstance();
41
        $executerClass  = $usedClass->obtainClassNameToUse('ExecutersSelect');
42
        $this->executer = new $executerClass($this);
43
        $this->executer->setReturnType($returnType);
44
    }
45
    
46
    /**
47
     * {@inheritdoc}
48
     */
49
    protected function defineQueriesParts()
50
    {
51
        parent::defineQueriesParts();
52
        
53
        $usedClass         = \BfwSql\UsedClass::getInstance();
54
        $subQueryListClass = $usedClass->obtainClassNameToUse('QueriesPartsSubQueryList');
55
        $joinListClass     = $usedClass->obtainClassNameToUse('QueriesPartsJoinList');
56
        $orderListClass    = $usedClass->obtainClassNameToUse('QueriesPartsOrderList');
57
        $limitClass        = $usedClass->obtainClassNameToUse('QueriesPartsLimit');
58
        $commonListClass   = $usedClass->obtainClassNameToUse('QueriesPartsCommonList');
59
        
60
        $this->queriesParts['subQuery']    = new $subQueryListClass($this);
61
        $this->queriesParts['from']        = $this->queriesParts['table'];
62
        $this->queriesParts['fromColumns'] = &$this->queriesParts['table']->getColumns();
63
        $this->queriesParts['join']        = new $joinListClass($this);
64
        $this->queriesParts['joinLeft']    = new $joinListClass($this);
65
        $this->queriesParts['joinRight']   = new $joinListClass($this);
66
        $this->queriesParts['order']       = new $orderListClass($this);
67
        $this->queriesParts['limit']       = new $limitClass($this);
68
        $this->queriesParts['group']       = new $commonListClass($this);
69
        
70
        $this->joinDefinePrefix();
71
        $this->queriesParts['group']->setSeparator(',');
72
        $this->queriesParts['group']->setPartPrefix('GROUP BY');
73
        
74
        $this->queriesParts['table']->createColumnInstance();
75
        
76
        $this->querySgbd->disableQueriesParts($this->queriesParts);
77
    }
78
    
79
    /**
80
     * {@inheritdoc}
81
     */
82
    protected function obtainGenerateOrder(): array
83
    {
84
        return [
85
            'select'    => [
86
                'prefix'     => 'SELECT',
87
                'callback'   => [$this, 'generateSelect'],
88
                'canBeEmpty' => false
89
            ],
90
            'from'      => [
91
                'prefix'     => 'FROM',
92
                'canBeEmpty' => false
93
            ],
94
            'join'      => [],
95
            'joinLeft'  => [],
96
            'joinRight' => [],
97
            'where'     => [],
98
            'group'     => [],
99
            'order'     => [],
100
            'limit'     => []
101
        ];
102
    }
103
    
104
    /**
105
     * Callback used by assembleRequestPart method
106
     * Generate the sql query for the SELECT part who contains all columns to
107
     * return and all sub-queries defined.
108
     * 
109
     * @return string
110
     */
111
    protected function generateSelect(): string
112
    {
113
        $sqlParts = $this->queriesParts['from']->getColumns()->generate();
114
        
115
        $joinKeyList = ['join', 'joinLeft', 'joinRight'];
116
        foreach ($joinKeyList as $joinKeyName) {
117
            foreach ($this->queriesParts[$joinKeyName] as $join) {
118
                $joinSql = $join->getColumns()->generate();
119
                
120
                if (empty($joinSql)) {
121
                    continue;
122
                }
123
                
124
                if ($sqlParts !== '') {
125
                    $sqlParts .= ',';
126
                }
127
                
128
                $sqlParts .= $joinSql;
129
            }
130
        }
131
        
132
        $sqlSubQueries = $this->queriesParts['subQuery']->generate();
133
        if ($sqlParts !== '' && $sqlSubQueries !== '') {
134
            $sqlParts .= ',';
135
        }
136
        
137
        $sqlParts .= $sqlSubQueries;
138
        
139
        return $sqlParts;
140
    }
141
} 
142