Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
D
doctrine-dbal
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Tomáš Trávníček
doctrine-dbal
Commits
03e17189
Commit
03e17189
authored
Jun 23, 2017
by
Marco Pivetta
Committed by
GitHub
Jun 23, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2688 from jnvsor/isnull
Connection: Support IS NULL in update/delete criteria
parents
638cb41b
f4437acb
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
187 additions
and
65 deletions
+187
-65
Connection.php
lib/Doctrine/DBAL/Connection.php
+54
-35
ConnectionTest.php
tests/Doctrine/Tests/DBAL/ConnectionTest.php
+93
-30
WriteTest.php
tests/Doctrine/Tests/DBAL/Functional/WriteTest.php
+40
-0
No files found.
lib/Doctrine/DBAL/Connection.php
View file @
03e17189
...
@@ -602,6 +602,36 @@ class Connection implements DriverConnection
...
@@ -602,6 +602,36 @@ class Connection implements DriverConnection
return
$this
->
_transactionNestingLevel
>
0
;
return
$this
->
_transactionNestingLevel
>
0
;
}
}
/**
* Gathers conditions for an update or delete call.
*
* @param array $identifiers Input array of columns to values
*
* @return string[][] a triplet with:
* - the first key being the columns
* - the second key being the values
* - the third key being the conditions
*/
private
function
gatherConditions
(
array
$identifiers
)
{
$columns
=
[];
$values
=
[];
$conditions
=
[];
foreach
(
$identifiers
as
$columnName
=>
$value
)
{
if
(
null
===
$value
)
{
$conditions
[]
=
$this
->
getDatabasePlatform
()
->
getIsNullExpression
(
$columnName
);
continue
;
}
$columns
[]
=
$columnName
;
$values
[]
=
$value
;
$conditions
[]
=
$columnName
.
' = ?'
;
}
return
[
$columns
,
$values
,
$conditions
];
}
/**
/**
* Executes an SQL DELETE statement on a table.
* Executes an SQL DELETE statement on a table.
*
*
...
@@ -621,20 +651,12 @@ class Connection implements DriverConnection
...
@@ -621,20 +651,12 @@ class Connection implements DriverConnection
throw
InvalidArgumentException
::
fromEmptyCriteria
();
throw
InvalidArgumentException
::
fromEmptyCriteria
();
}
}
$columnList
=
array
();
list
(
$columns
,
$values
,
$conditions
)
=
$this
->
gatherConditions
(
$identifier
);
$criteria
=
array
();
$paramValues
=
array
();
foreach
(
$identifier
as
$columnName
=>
$value
)
{
$columnList
[]
=
$columnName
;
$criteria
[]
=
$columnName
.
' = ?'
;
$paramValues
[]
=
$value
;
}
return
$this
->
executeUpdate
(
return
$this
->
executeUpdate
(
'DELETE FROM '
.
$tableExpression
.
' WHERE '
.
implode
(
' AND '
,
$c
riteria
),
'DELETE FROM '
.
$tableExpression
.
' WHERE '
.
implode
(
' AND '
,
$c
onditions
),
$
paramV
alues
,
$
v
alues
,
is_string
(
key
(
$types
))
?
$this
->
extractTypeValues
(
$column
List
,
$types
)
:
$types
is_string
(
key
(
$types
))
?
$this
->
extractTypeValues
(
$column
s
,
$types
)
:
$types
);
);
}
}
...
@@ -692,31 +714,28 @@ class Connection implements DriverConnection
...
@@ -692,31 +714,28 @@ class Connection implements DriverConnection
*/
*/
public
function
update
(
$tableExpression
,
array
$data
,
array
$identifier
,
array
$types
=
array
())
public
function
update
(
$tableExpression
,
array
$data
,
array
$identifier
,
array
$types
=
array
())
{
{
$columnList
=
array
();
$setColumns
=
array
();
$setValues
=
array
();
$set
=
array
();
$set
=
array
();
$criteria
=
array
();
$paramValues
=
array
();
foreach
(
$data
as
$columnName
=>
$value
)
{
foreach
(
$data
as
$columnName
=>
$value
)
{
$columnList
[]
=
$columnName
;
$setColumns
[]
=
$columnName
;
$setValues
[]
=
$value
;
$set
[]
=
$columnName
.
' = ?'
;
$set
[]
=
$columnName
.
' = ?'
;
$paramValues
[]
=
$value
;
}
}
foreach
(
$identifier
as
$columnName
=>
$value
)
{
list
(
$conditionColumns
,
$conditionValues
,
$conditions
)
=
$this
->
gatherConditions
(
$identifier
);
$columnList
[]
=
$columnName
;
$columns
=
array_merge
(
$setColumns
,
$conditionColumns
);
$criteria
[]
=
$columnName
.
' = ?'
;
$values
=
array_merge
(
$setValues
,
$conditionValues
);
$paramValues
[]
=
$value
;
}
if
(
is_string
(
key
(
$types
)))
{
if
(
is_string
(
key
(
$types
)))
{
$types
=
$this
->
extractTypeValues
(
$column
List
,
$types
);
$types
=
$this
->
extractTypeValues
(
$column
s
,
$types
);
}
}
$sql
=
'UPDATE '
.
$tableExpression
.
' SET '
.
implode
(
', '
,
$set
)
$sql
=
'UPDATE '
.
$tableExpression
.
' SET '
.
implode
(
', '
,
$set
)
.
' WHERE '
.
implode
(
' AND '
,
$c
riteria
);
.
' WHERE '
.
implode
(
' AND '
,
$c
onditions
);
return
$this
->
executeUpdate
(
$sql
,
$
paramV
alues
,
$types
);
return
$this
->
executeUpdate
(
$sql
,
$
v
alues
,
$types
);
}
}
/**
/**
...
@@ -736,21 +755,21 @@ class Connection implements DriverConnection
...
@@ -736,21 +755,21 @@ class Connection implements DriverConnection
return
$this
->
executeUpdate
(
'INSERT INTO '
.
$tableExpression
.
' ()'
.
' VALUES ()'
);
return
$this
->
executeUpdate
(
'INSERT INTO '
.
$tableExpression
.
' ()'
.
' VALUES ()'
);
}
}
$column
List
=
array
();
$column
s
=
array
();
$
paramPlaceholder
s
=
array
();
$
value
s
=
array
();
$
paramValues
=
array
();
$
set
=
array
();
foreach
(
$data
as
$columnName
=>
$value
)
{
foreach
(
$data
as
$columnName
=>
$value
)
{
$column
List
[]
=
$columnName
;
$column
s
[]
=
$columnName
;
$
paramPlaceholders
[]
=
'?'
;
$
values
[]
=
$value
;
$
paramValues
[]
=
$value
;
$
set
[]
=
'?'
;
}
}
return
$this
->
executeUpdate
(
return
$this
->
executeUpdate
(
'INSERT INTO '
.
$tableExpression
.
' ('
.
implode
(
', '
,
$column
List
)
.
')'
.
'INSERT INTO '
.
$tableExpression
.
' ('
.
implode
(
', '
,
$column
s
)
.
')'
.
' VALUES ('
.
implode
(
', '
,
$
paramPlaceholders
)
.
')'
,
' VALUES ('
.
implode
(
', '
,
$
set
)
.
')'
,
$
paramV
alues
,
$
v
alues
,
is_string
(
key
(
$types
))
?
$this
->
extractTypeValues
(
$column
List
,
$types
)
:
$types
is_string
(
key
(
$types
))
?
$this
->
extractTypeValues
(
$column
s
,
$types
)
:
$types
);
);
}
}
...
...
tests/Doctrine/Tests/DBAL/ConnectionTest.php
View file @
03e17189
...
@@ -34,6 +34,22 @@ class ConnectionTest extends \Doctrine\Tests\DbalTestCase
...
@@ -34,6 +34,22 @@ class ConnectionTest extends \Doctrine\Tests\DbalTestCase
$this
->
_conn
=
\Doctrine\DBAL\DriverManager
::
getConnection
(
$this
->
params
);
$this
->
_conn
=
\Doctrine\DBAL\DriverManager
::
getConnection
(
$this
->
params
);
}
}
public
function
getExecuteUpdateMockConnection
()
{
$driverMock
=
$this
->
createMock
(
\Doctrine\DBAL\Driver
::
class
);
$driverMock
->
expects
(
$this
->
any
())
->
method
(
'connect'
)
->
will
(
$this
->
returnValue
(
new
DriverConnectionMock
()));
$conn
=
$this
->
getMockBuilder
(
Connection
::
class
)
->
setMethods
([
'executeUpdate'
])
->
setConstructorArgs
([[
'platform'
=>
new
Mocks\MockPlatform
()],
$driverMock
])
->
getMock
();
return
$conn
;
}
public
function
testIsConnected
()
public
function
testIsConnected
()
{
{
$this
->
assertFalse
(
$this
->
_conn
->
isConnected
());
$this
->
assertFalse
(
$this
->
_conn
->
isConnected
());
...
@@ -285,16 +301,7 @@ class ConnectionTest extends \Doctrine\Tests\DbalTestCase
...
@@ -285,16 +301,7 @@ class ConnectionTest extends \Doctrine\Tests\DbalTestCase
public
function
testEmptyInsert
()
public
function
testEmptyInsert
()
{
{
$driverMock
=
$this
->
createMock
(
'Doctrine\DBAL\Driver'
);
$conn
=
$this
->
getExecuteUpdateMockConnection
();
$driverMock
->
expects
(
$this
->
any
())
->
method
(
'connect'
)
->
will
(
$this
->
returnValue
(
new
DriverConnectionMock
()));
$conn
=
$this
->
getMockBuilder
(
'Doctrine\DBAL\Connection'
)
->
setMethods
(
array
(
'executeUpdate'
))
->
setConstructorArgs
(
array
(
array
(
'platform'
=>
new
Mocks\MockPlatform
()),
$driverMock
))
->
getMock
();
$conn
->
expects
(
$this
->
once
())
$conn
->
expects
(
$this
->
once
())
->
method
(
'executeUpdate'
)
->
method
(
'executeUpdate'
)
...
@@ -308,16 +315,7 @@ class ConnectionTest extends \Doctrine\Tests\DbalTestCase
...
@@ -308,16 +315,7 @@ class ConnectionTest extends \Doctrine\Tests\DbalTestCase
*/
*/
public
function
testUpdateWithDifferentColumnsInDataAndIdentifiers
()
public
function
testUpdateWithDifferentColumnsInDataAndIdentifiers
()
{
{
$driverMock
=
$this
->
createMock
(
'Doctrine\DBAL\Driver'
);
$conn
=
$this
->
getExecuteUpdateMockConnection
();
$driverMock
->
expects
(
$this
->
any
())
->
method
(
'connect'
)
->
will
(
$this
->
returnValue
(
new
DriverConnectionMock
()));
$conn
=
$this
->
getMockBuilder
(
'Doctrine\DBAL\Connection'
)
->
setMethods
(
array
(
'executeUpdate'
))
->
setConstructorArgs
(
array
(
array
(
'platform'
=>
new
Mocks\MockPlatform
()),
$driverMock
))
->
getMock
();
$conn
->
expects
(
$this
->
once
())
$conn
->
expects
(
$this
->
once
())
->
method
(
'executeUpdate'
)
->
method
(
'executeUpdate'
)
...
@@ -361,16 +359,7 @@ class ConnectionTest extends \Doctrine\Tests\DbalTestCase
...
@@ -361,16 +359,7 @@ class ConnectionTest extends \Doctrine\Tests\DbalTestCase
*/
*/
public
function
testUpdateWithSameColumnInDataAndIdentifiers
()
public
function
testUpdateWithSameColumnInDataAndIdentifiers
()
{
{
$driverMock
=
$this
->
createMock
(
'Doctrine\DBAL\Driver'
);
$conn
=
$this
->
getExecuteUpdateMockConnection
();
$driverMock
->
expects
(
$this
->
any
())
->
method
(
'connect'
)
->
will
(
$this
->
returnValue
(
new
DriverConnectionMock
()));
$conn
=
$this
->
getMockBuilder
(
'Doctrine\DBAL\Connection'
)
->
setMethods
(
array
(
'executeUpdate'
))
->
setConstructorArgs
(
array
(
array
(
'platform'
=>
new
Mocks\MockPlatform
()),
$driverMock
))
->
getMock
();
$conn
->
expects
(
$this
->
once
())
$conn
->
expects
(
$this
->
once
())
->
method
(
'executeUpdate'
)
->
method
(
'executeUpdate'
)
...
@@ -408,6 +397,80 @@ class ConnectionTest extends \Doctrine\Tests\DbalTestCase
...
@@ -408,6 +397,80 @@ class ConnectionTest extends \Doctrine\Tests\DbalTestCase
);
);
}
}
/**
* @group DBAL-2688
*/
public
function
testUpdateWithIsNull
()
{
$conn
=
$this
->
getExecuteUpdateMockConnection
();
$conn
->
expects
(
$this
->
once
())
->
method
(
'executeUpdate'
)
->
with
(
'UPDATE TestTable SET text = ?, is_edited = ? WHERE id IS NULL AND name = ?'
,
[
'some text'
,
null
,
'foo'
,
],
[
'string'
,
'boolean'
,
'string'
,
]
);
$conn
->
update
(
'TestTable'
,
[
'text'
=>
'some text'
,
'is_edited'
=>
null
,
],
[
'id'
=>
null
,
'name'
=>
'foo'
,
],
[
'text'
=>
'string'
,
'is_edited'
=>
'boolean'
,
'id'
=>
'integer'
,
'name'
=>
'string'
,
]
);
}
/**
* @group DBAL-2688
*/
public
function
testDeleteWithIsNull
()
{
$conn
=
$this
->
getExecuteUpdateMockConnection
();
$conn
->
expects
(
$this
->
once
())
->
method
(
'executeUpdate'
)
->
with
(
'DELETE FROM TestTable WHERE id IS NULL AND name = ?'
,
[
'foo'
,
],
[
'string'
,
]
);
$conn
->
delete
(
'TestTable'
,
[
'id'
=>
null
,
'name'
=>
'foo'
,
],
[
'id'
=>
'integer'
,
'name'
=>
'string'
,
]
);
}
public
function
testFetchAssoc
()
public
function
testFetchAssoc
()
{
{
$statement
=
'SELECT * FROM foo WHERE bar = ?'
;
$statement
=
'SELECT * FROM foo WHERE bar = ?'
;
...
...
tests/Doctrine/Tests/DBAL/Functional/WriteTest.php
View file @
03e17189
...
@@ -285,4 +285,44 @@ class WriteTest extends \Doctrine\Tests\DbalFunctionalTestCase
...
@@ -285,4 +285,44 @@ class WriteTest extends \Doctrine\Tests\DbalFunctionalTestCase
}
}
/**
* @group DBAL-2688
*/
public
function
testUpdateWhereIsNull
()
{
$this
->
_conn
->
insert
(
'write_table'
,
[
'test_int'
=>
'30'
,
'test_string'
=>
null
],
[
'test_string'
=>
'string'
,
'test_int'
=>
'integer'
]
);
$data
=
$this
->
_conn
->
fetchAll
(
'SELECT * FROM write_table WHERE test_int = 30'
);
$this
->
assertCount
(
1
,
$data
);
$this
->
_conn
->
update
(
'write_table'
,
[
'test_int'
=>
10
],
[
'test_string'
=>
null
],
[
'test_string'
=>
'string'
,
'test_int'
=>
'integer'
]);
$data
=
$this
->
_conn
->
fetchAll
(
'SELECT * FROM write_table WHERE test_int = 30'
);
$this
->
assertCount
(
0
,
$data
);
}
public
function
testDeleteWhereIsNull
()
{
$this
->
_conn
->
insert
(
'write_table'
,
[
'test_int'
=>
'30'
,
'test_string'
=>
null
],
[
'test_string'
=>
'string'
,
'test_int'
=>
'integer'
]
);
$data
=
$this
->
_conn
->
fetchAll
(
'SELECT * FROM write_table WHERE test_int = 30'
);
$this
->
assertCount
(
1
,
$data
);
$this
->
_conn
->
delete
(
'write_table'
,
[
'test_string'
=>
null
],
[
'test_string'
=>
'string'
]);
$data
=
$this
->
_conn
->
fetchAll
(
'SELECT * FROM write_table WHERE test_int = 30'
);
$this
->
assertCount
(
0
,
$data
);
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment