Skip to content

Commit c3f7ef5

Browse files
committed
Merge remote-tracking branch 'origin/master'
2 parents 354c264 + 8498abc commit c3f7ef5

File tree

5 files changed

+190
-15
lines changed

5 files changed

+190
-15
lines changed

README.md

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
mysql query builder (php 5.4+)
22
==============================
3+
4+
[![Build Status](https://travis-ci.org/rkrx/php-mysql-query-builder.svg)](https://travis-ci.org/rkrx/php-mysql-query-builder)
5+
36
Simple mysql query builder to build select, insert, update and delete queries with conditional parts.
47
This library was initially not intended to build prepared statements, but this is also possible.
58
The main motive for this library is an environment where a lot of things are automated.
@@ -8,4 +11,79 @@ Here a few things to keep in mind:
811

912
* The charset is up to you. No special binding to UTF8, although UTF8 is the default.
1013
* The order of method-calls of each statement-builder is irrelevant. The resulting query will always render the right order.
11-
* No animals were harmed due to the production of this library.
14+
* No animals were harmed due to the production of this library.
15+
16+
## Some examples
17+
18+
### Initialization
19+
20+
```PHP
21+
$pdo = new PDO('mysql:host=127.0.0.1;dbname=test;charset=utf8', 'root', '');
22+
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
23+
24+
$mysql = new MySQL($pdo);
25+
$mysql->getAliasRegistry()->add('textprefix', 'testdb.test__');
26+
```
27+
28+
### Select
29+
30+
```PHP
31+
$select = $mysql->select(['customer_count' => 'COUNT(*)'])
32+
->from('t1', 'textprefix#test1') // You are forced to used aliases for tables.
33+
->joinInner('t2', 'textprefix#test2', 't2.test_id = t1.id AND t2.field1 = ?', 123)
34+
->joinLeft('t3', 'textprefix#test3', 't3.test_id = t1.id')
35+
->joinRight('t4', 'textprefix#test4', 't4.test_id = t1.id')
36+
->orderBy('t1.field1')
37+
->orderBy('t1.field2', 'DESC')
38+
->limit(100)
39+
->offset(50);
40+
41+
if($contition === true) {
42+
$select->where('t1.somefield = ?', $someValue);
43+
}
44+
45+
$rows = $select->fetchRows();
46+
47+
foreach($rows as $row) {
48+
print_r($row);
49+
}
50+
```
51+
52+
### Insert
53+
54+
You can insert key-value-arrays with `addAll`, `updateAll`, `addOrUpdateAll`. As the second parameter you can provide an array to specify the only fields to consider.
55+
56+
```PHP
57+
$mysql->insert()
58+
->into('test')
59+
->addOrUpdateAll($data, ['field1', 'field2', 'field3'])
60+
->add('created_at=NOW()')
61+
->addOrUpdateExpr('updated_at=NOW()')
62+
->run();
63+
```
64+
65+
There is also an option to build an `INSERT INTO ... SELECT ... FROM ... ON DUPLICATE KEY UPDATE ...`
66+
67+
### Update
68+
69+
```PHP
70+
$mysql->update()
71+
->table('t1', 'test1')
72+
->joinLeft('t2', 'test2', 't1.id = t2.test_id')
73+
->setAll($data)
74+
->where("t1.field1 = ? OR t2.field2 > ?", 1, 10)
75+
->where("field IN (?)", [1, 2, 3, 4, 5, 6])
76+
->run();
77+
```
78+
79+
### Delete
80+
81+
You can use joins in delete-statements. But only the rows of tables specified in `from` will be modified (deleted).
82+
83+
```PHP
84+
$mysql->delete()
85+
->from('t1', 'test1')
86+
->joinLeft('t2', 'test2', 't1.id=t2.test_id')
87+
->where('t1.field1=? AND t2.field2 > ?', 1, 10)
88+
->run();
89+
```

src/Builder/Insert.php

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ public function into($table) {
5252
/**
5353
* @param bool $value
5454
* @return $this
55-
5655
*/
5756
public function setIgnore($value = true) {
5857
$this->ignore = $value;
@@ -65,7 +64,6 @@ public function setIgnore($value = true) {
6564
*
6665
* @param string $field
6766
* @return $this
68-
6967
*/
7068
public function setKey($field) {
7169
$this->keyField = $field;
@@ -146,10 +144,13 @@ public function addOrUpdateExpr($str) {
146144

147145
/**
148146
* @param array $data
147+
* @param array $mask
149148
* @return $this
150-
* @throws UnexpectedValueException
151149
*/
152-
public function addAll(array $data) {
150+
public function addAll(array $data, array $mask = null) {
151+
if($mask !== null) {
152+
$data = array_intersect_key($data, array_combine($mask, $mask));
153+
}
153154
$data = $this->clearValues($data);
154155
foreach ($data as $field => $value) {
155156
$this->add($field, $value);
@@ -159,10 +160,13 @@ public function addAll(array $data) {
159160

160161
/**
161162
* @param array $data
162-
* @throws UnexpectedValueException
163+
* @param array $mask
163164
* @return $this
164165
*/
165-
public function updateAll(array $data) {
166+
public function updateAll(array $data, array $mask = null) {
167+
if($mask !== null) {
168+
$data = array_intersect_key($data, array_combine($mask, $mask));
169+
}
166170
$data = $this->clearValues($data);
167171
foreach ($data as $field => $value) {
168172
if ($field != $this->keyField) {
@@ -174,12 +178,12 @@ public function updateAll(array $data) {
174178

175179
/**
176180
* @param array $data
177-
* @throws UnexpectedValueException
181+
* @param array $mask
178182
* @return $this
179183
*/
180-
public function addOrUpdateAll(array $data) {
181-
$this->addAll($data);
182-
$this->updateAll($data);
184+
public function addOrUpdateAll(array $data, array $mask = null) {
185+
$this->addAll($data, $mask);
186+
$this->updateAll($data, $mask);
183187
return $this;
184188
}
185189

@@ -267,7 +271,9 @@ private function clearValues(array $values) {
267271
if(!count($values)) {
268272
return [];
269273
}
270-
$fields = $this->db()->getTableFields($this->table);
274+
275+
$tableName = (new AliasReplacer($this->db()->getAliasRegistry()))->replace($this->table);
276+
$fields = $this->db()->getTableFields($tableName);
271277
$result = array();
272278

273279
foreach ($values as $fieldName => $fieldValue) {
File renamed without changes.

tests.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
verbose="true"
66
timeoutForSmallTests="5">
77
<testsuites>
8-
<testsuite name="Streams">
8+
<testsuite name="Tests">
99
<directory>tests</directory>
1010
</testsuite>
1111
</testsuites>

tests/Builder/InsertTest.php

Lines changed: 93 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33

44
use Kir\MySQL\Builder\InsertTest\TestInsert;
55
use Kir\MySQL\Builder\SelectTest\TestSelect;
6-
use Kir\MySQL\Database;
7-
use Kir\MySQL\Tools\AliasRegistry;
86
use Phake;
97

108
class InsertTest extends \PHPUnit_Framework_TestCase {
@@ -38,4 +36,97 @@ public function testMassInsert() {
3836

3937
$this->assertEquals("INSERT INTO\n\ttravis_test.test2\n\t(a)\nSELECT\n\tb AS `a`\nFROM\n\ttravis_test.test1 oi\nWHERE\n\t(1!=2)\nON DUPLICATE KEY UPDATE\n\ta = VALUES(a)\n;\n", $query);
4038
}
39+
40+
public function testAddAll() {
41+
$reg = Phake::mock('Kir\\MySQL\\Tools\\AliasRegistry');
42+
Phake::when($reg)->__call('get', ['travis'])->thenReturn('travis_test.');
43+
44+
$db = Phake::mock('Kir\\MySQL\\Database');
45+
Phake::when($db)->__call('getTableFields', ['test1'])->thenReturn(['field1', 'field2']);
46+
Phake::when($db)->__call('getTableFields', ['travis_test.test1'])->thenReturn(['field1', 'field2']);
47+
Phake::when($db)->__call('quoteField', [Phake::anyParameters()])->thenGetReturnByLambda(function ($fieldName) { return "`{$fieldName}`"; });
48+
Phake::when($db)->__call('quote', [Phake::anyParameters()])->thenGetReturnByLambda(function ($value) { return "'{$value}'"; });
49+
Phake::when($db)->__call('getAliasRegistry', [])->thenReturn($reg);
50+
51+
$query = (new TestInsert($db))
52+
->into('test1')
53+
->addAll(['field1' => 123, 'field2' => 456])
54+
->asString();
55+
$this->assertEquals("INSERT INTO\n\ttest1\nSET\n\t`field1`='123',\n\t`field2`='456'\n;\n", $query);
56+
57+
$query = (new TestInsert($db))
58+
->into('test1')
59+
->addAll(['field1' => 123, 'field2' => 456], ['field1'])
60+
->asString();
61+
$this->assertEquals("INSERT INTO\n\ttest1\nSET\n\t`field1`='123'\n;\n", $query);
62+
63+
$query = (new TestInsert($db))
64+
->into('travis#test1')
65+
->addAll(['field1' => 123, 'field2' => 456], ['field1'])
66+
->asString();
67+
$this->assertEquals("INSERT INTO\n\ttravis_test.test1\nSET\n\t`field1`='123'\n;\n", $query);
68+
}
69+
70+
public function testUpdateAll() {
71+
$reg = Phake::mock('Kir\\MySQL\\Tools\\AliasRegistry');
72+
Phake::when($reg)->__call('get', ['travis'])->thenReturn('travis_test.');
73+
74+
$db = Phake::mock('Kir\\MySQL\\Database');
75+
Phake::when($db)->__call('getTableFields', ['test1'])->thenReturn(['field1', 'field2']);
76+
Phake::when($db)->__call('getTableFields', ['travis_test.test1'])->thenReturn(['field1', 'field2']);
77+
Phake::when($db)->__call('quoteField', [Phake::anyParameters()])->thenGetReturnByLambda(function ($fieldName) { return "`{$fieldName}`"; });
78+
Phake::when($db)->__call('quote', [Phake::anyParameters()])->thenGetReturnByLambda(function ($value) { return "'{$value}'"; });
79+
Phake::when($db)->__call('getAliasRegistry', [])->thenReturn($reg);
80+
81+
$query = (new TestInsert($db))
82+
->into('test1')
83+
->add('field1', 123)
84+
->updateAll(['field1' => 123, 'field2' => 456])
85+
->asString();
86+
$this->assertEquals("INSERT INTO\n\ttest1\nSET\n\t`field1`='123'\nON DUPLICATE KEY UPDATE\n\t`field1`='123',\n\t`field2`='456'\n;\n", $query);
87+
88+
$query = (new TestInsert($db))
89+
->into('test1')
90+
->add('field1', 123)
91+
->updateAll(['field1' => 123, 'field2' => 456], ['field1'])
92+
->asString();
93+
$this->assertEquals("INSERT INTO\n\ttest1\nSET\n\t`field1`='123'\nON DUPLICATE KEY UPDATE\n\t`field1`='123'\n;\n", $query);
94+
95+
$query = (new TestInsert($db))
96+
->into('travis#test1')
97+
->add('field1', 123)
98+
->updateAll(['field1' => 123, 'field2' => 456], ['field1'])
99+
->asString();
100+
$this->assertEquals("INSERT INTO\n\ttravis_test.test1\nSET\n\t`field1`='123'\nON DUPLICATE KEY UPDATE\n\t`field1`='123'\n;\n", $query);
101+
}
102+
103+
public function testAddOrUpdateAll() {
104+
$reg = Phake::mock('Kir\\MySQL\\Tools\\AliasRegistry');
105+
Phake::when($reg)->__call('get', ['travis'])->thenReturn('travis_test.');
106+
107+
$db = Phake::mock('Kir\\MySQL\\Database');
108+
Phake::when($db)->__call('getTableFields', ['test1'])->thenReturn(['field1', 'field2']);
109+
Phake::when($db)->__call('getTableFields', ['travis_test.test1'])->thenReturn(['field1', 'field2']);
110+
Phake::when($db)->__call('quoteField', [Phake::anyParameters()])->thenGetReturnByLambda(function ($fieldName) { return "`{$fieldName}`"; });
111+
Phake::when($db)->__call('quote', [Phake::anyParameters()])->thenGetReturnByLambda(function ($value) { return "'{$value}'"; });
112+
Phake::when($db)->__call('getAliasRegistry', [])->thenReturn($reg);
113+
114+
$query = (new TestInsert($db))
115+
->into('test1')
116+
->addOrUpdateAll(['field1' => 123, 'field2' => 456])
117+
->asString();
118+
$this->assertEquals("INSERT INTO\n\ttest1\nSET\n\t`field1`='123',\n\t`field2`='456'\nON DUPLICATE KEY UPDATE\n\t`field1`='123',\n\t`field2`='456'\n;\n", $query);
119+
120+
$query = (new TestInsert($db))
121+
->into('test1')
122+
->addOrUpdateAll(['field1' => 123, 'field2' => 456], ['field1'])
123+
->asString();
124+
$this->assertEquals("INSERT INTO\n\ttest1\nSET\n\t`field1`='123'\nON DUPLICATE KEY UPDATE\n\t`field1`='123'\n;\n", $query);
125+
126+
$query = (new TestInsert($db))
127+
->into('travis#test1')
128+
->addOrUpdateAll(['field1' => 123, 'field2' => 456], ['field1'])
129+
->asString();
130+
$this->assertEquals("INSERT INTO\n\ttravis_test.test1\nSET\n\t`field1`='123'\nON DUPLICATE KEY UPDATE\n\t`field1`='123'\n;\n", $query);
131+
}
41132
}

0 commit comments

Comments
 (0)