Completed
Push — master ( 529f36...77a63f )
by Restu
13:12
created

GrammarMySql::build()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 1
Metric Value
cc 4
eloc 9
c 3
b 0
f 1
nc 4
nop 0
dl 0
loc 14
rs 9.2
1
<?php
2
namespace JayaCode\Framework\Core\Database\Query\Grammar;
3
4
use JayaCode\Framework\Core\Database\Query\Query;
5
use Stringy\Stringy;
6
7
/**
8
 * Class GrammarMySql
9
 * @package JayaCode\Framework\Core\Database\Query\Grammar
10
 */
11
class GrammarMySql extends Grammar
12
{
13
14
    /**
15
     * @return string
16
     */
17
    public function build()
18
    {
19
        switch ($this->query->getType()) {
20
            case Query::TYPE_SELECT:
21
                return $this->select();
22
23
            case Query::TYPE_INSERT:
24
                return $this->insert();
25
26
            case Query::TYPE_QUERY:
27
                return $this->query->query;
28
        }
29
        return null;
30
    }
31
32
    /**
33
     * @return string
34
     */
35
    private function select()
36
    {
37
        $this->queryString = "SELECT ";
38
39
        $this->queryString .= $this->selectColumn();
40
41
        $table = $this->query->table;
42
        $this->queryString .= " FROM {$this->getFormattedTableOrColumn($table)}";
43
44
        $this->queryString .= $this->where();
45
46
        return $this->queryString;
47
    }
48
49
    /**
50
     * @return string
51
     */
52
    private function selectColumn()
53
    {
54
        $columns = $this->query->columns;
55
        if (is_null($columns)) {
56
            $columns = [Query::sql("*")];
57
        }
58
59
        if (is_string($columns)) {
60
            $columns = array($columns);
61
        }
62
63
        foreach ($columns as $key => $val) {
64
            if ($columns[$key] instanceof Query) {
65
                $columns[$key] = $columns[$key]->query;
66
            } else {
67
                $columns[$key] = $this->getFormattedTableOrColumn($val);
68
            }
69
        }
70
71
        return implode(', ', $columns);
72
    }
73
74
    /**
75
     * @return string
76
     */
77
    private function where()
78
    {
79
        if (count($this->query->where) <= 0) {
80
            return "";
81
        }
82
83
        $q = Stringy::create("");
84
85
        foreach ($this->query->where as $where) {
86
            $type = $where[0];
87
            $arr = $where[1];
88
89
            if ($q->count() > 1) {
90
                $q = $q->append(" {$type} ");
91
            }
92
93
            if (is_string($arr)) {
94
                $q = $q->append($arr);
95
            }
96
97
            if (is_array($arr)) {
98
                $q = $q->append($this->buildArrWhere($arr));
99
100
                $this->params[] = $arr[2];
101
            }
102
        }
103
104
        return $q->count()?$q->prepend(" WHERE ")->__toString():"";
105
    }
106
107
    /**
108
     * @param $arr
109
     * @return string
110
     */
111
    private function buildArrWhere($arr)
112
    {
113
        if (count($arr) != 3) {
114
            throw new \OutOfBoundsException();
115
        }
116
117
        switch ($arr[1]) {
118
            case "BETWEEN":
119
                return "`{$arr[0]}` {$arr[1]} ? AND ?";
120
            default:
121
                return "`{$arr[0]}` {$arr[1]} ?";
122
        }
123
    }
124
125
    /**
126
     * @return string
127
     */
128
    private function insert()
129
    {
130
131
        $this->params = $this->query->values;
132
133
        $table = $this->query->table;
134
        $this->queryString = "INSERT INTO {$this->getFormattedTableOrColumn($table)}";
135
136
        $this->queryString .= "({$this->selectColumn()})";
137
138
        $this->queryString .= " VALUES(";
139
140
        $params = array();
141
        for ($i=0; count($this->query->columns) > $i; $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
142
             $params[] = "?";
143
        }
144
        $this->queryString .= join(', ', $params).")";
145
146
        return $this->queryString;
147
    }
148
149
150
    /**
151
     * @param null $str
152
     * @return null|string
153
     */
154
    private function getFormattedTableOrColumn($str = null)
155
    {
156
        $tmpStr = $str?$str:$this->query->table;
157
        $strArr = explode(".", $tmpStr);
158
159
        foreach ($strArr as $key => $val) {
160
            $strArr[$key] = "`{$val}`";
161
        }
162
163
        return join(".", $strArr);
164
    }
165
}
166