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
8f9e9021
Unverified
Commit
8f9e9021
authored
Jun 26, 2020
by
Sergei Morozov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove deprecated statement classes
parent
10357097
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
855 additions
and
910 deletions
+855
-910
UPGRADE.md
UPGRADE.md
+5
-0
phpcs.xml.dist
phpcs.xml.dist
+1
-1
psalm.xml
psalm.xml
+1
-1
DB2Statement.php
src/Driver/IBMDB2/DB2Statement.php
+0
-201
Statement.php
src/Driver/IBMDB2/Statement.php
+192
-1
MysqliStatement.php
src/Driver/Mysqli/MysqliStatement.php
+0
-227
Statement.php
src/Driver/Mysqli/Statement.php
+218
-1
OCI8Statement.php
src/Driver/OCI8/OCI8Statement.php
+0
-164
Statement.php
src/Driver/OCI8/Statement.php
+153
-1
Statement.php
src/Driver/PDO/Statement.php
+92
-2
PDOStatement.php
src/Driver/PDOStatement.php
+0
-106
SQLSrvStatement.php
src/Driver/SQLSrv/SQLSrvStatement.php
+0
-204
Statement.php
src/Driver/SQLSrv/Statement.php
+193
-1
No files found.
UPGRADE.md
View file @
8f9e9021
...
...
@@ -6,15 +6,20 @@
-
`DriverException`
-
`PDOConnection`
-
`PDOException`
-
`PDOStatement`
-
`IBMDB2\DB2Connection`
-
`IBMDB2\DB2Driver`
-
`IBMDB2\DB2Exception`
-
`IBMDB2\DB2Statement`
-
`Mysqli\MysqliConnection`
-
`Mysqli\MysqliException`
-
`Mysqli\MysqliStatement`
-
`OCI8\OCI8Connection`
-
`OCI8\OCI8Exception`
-
`OCI8\OCI8Statement`
-
`SQLSrv\SQLSrvConnection`
-
`SQLSrv\SQLSrvException`
-
`SQLSrv\SQLSrvStatement`
## BC BREAK: `ServerInfoAwareConnection::requiresQueryForServerVersion()` is removed.
...
...
phpcs.xml.dist
View file @
8f9e9021
...
...
@@ -114,6 +114,6 @@
<!-- The SQLSRV_* functions are defined in the upper case by the sqlsrv extension and violate the standard
see https://docs.microsoft.com/en-us/sql/connect/php/constants-microsoft-drivers-for-php-for-sql-server -->
<rule
ref=
"Squiz.PHP.LowercasePHPFunctions"
>
<exclude-pattern>
src/Driver/SQLSrv/S
QLSrvS
tatement.php
</exclude-pattern>
<exclude-pattern>
src/Driver/SQLSrv/Statement.php
</exclude-pattern>
</rule>
</ruleset>
psalm.xml
View file @
8f9e9021
...
...
@@ -55,7 +55,7 @@
Requires a release of
https://github.com/JetBrains/phpstorm-stubs/pull/727
-->
<file
name=
"src/Driver/SQLSrv/S
QLSrvS
tatement.php"
/>
<file
name=
"src/Driver/SQLSrv/Statement.php"
/>
</errorLevel>
</TooFewArguments>
<UndefinedConstant>
...
...
src/Driver/IBMDB2/DB2Statement.php
deleted
100644 → 0
View file @
10357097
<?php
namespace
Doctrine\DBAL\Driver\IBMDB2
;
use
Doctrine\DBAL\Driver\Exception
;
use
Doctrine\DBAL\Driver\IBMDB2\Exception\CannotCopyStreamToStream
;
use
Doctrine\DBAL\Driver\IBMDB2\Exception\CannotCreateTemporaryFile
;
use
Doctrine\DBAL\Driver\IBMDB2\Exception\CannotWriteToTemporaryFile
;
use
Doctrine\DBAL\Driver\IBMDB2\Exception\StatementError
;
use
Doctrine\DBAL\Driver\Result
as
ResultInterface
;
use
Doctrine\DBAL\Driver\Statement
as
StatementInterface
;
use
Doctrine\DBAL\ParameterType
;
use
function
assert
;
use
function
db2_bind_param
;
use
function
db2_execute
;
use
function
error_get_last
;
use
function
fclose
;
use
function
fwrite
;
use
function
is_int
;
use
function
is_resource
;
use
function
ksort
;
use
function
stream_copy_to_stream
;
use
function
stream_get_meta_data
;
use
function
tmpfile
;
use
const
DB2_BINARY
;
use
const
DB2_CHAR
;
use
const
DB2_LONG
;
use
const
DB2_PARAM_FILE
;
use
const
DB2_PARAM_IN
;
/**
* @deprecated Use {@link Statement} instead
*/
class
DB2Statement
implements
StatementInterface
{
/** @var resource */
private
$stmt
;
/** @var mixed[] */
private
$bindParam
=
[];
/**
* Map of LOB parameter positions to the tuples containing reference to the variable bound to the driver statement
* and the temporary file handle bound to the underlying statement
*
* @var mixed[][]
*/
private
$lobs
=
[];
/**
* @internal The statement can be only instantiated by its driver connection.
*
* @param resource $stmt
*/
public
function
__construct
(
$stmt
)
{
$this
->
stmt
=
$stmt
;
}
/**
* {@inheritdoc}
*/
public
function
bindValue
(
$param
,
$value
,
$type
=
ParameterType
::
STRING
)
{
assert
(
is_int
(
$param
));
return
$this
->
bindParam
(
$param
,
$value
,
$type
);
}
/**
* {@inheritdoc}
*/
public
function
bindParam
(
$column
,
&
$variable
,
$type
=
ParameterType
::
STRING
,
$length
=
null
)
{
assert
(
is_int
(
$column
));
switch
(
$type
)
{
case
ParameterType
::
INTEGER
:
$this
->
bind
(
$column
,
$variable
,
DB2_PARAM_IN
,
DB2_LONG
);
break
;
case
ParameterType
::
LARGE_OBJECT
:
if
(
isset
(
$this
->
lobs
[
$column
]))
{
[,
$handle
]
=
$this
->
lobs
[
$column
];
fclose
(
$handle
);
}
$handle
=
$this
->
createTemporaryFile
();
$path
=
stream_get_meta_data
(
$handle
)[
'uri'
];
$this
->
bind
(
$column
,
$path
,
DB2_PARAM_FILE
,
DB2_BINARY
);
$this
->
lobs
[
$column
]
=
[
&
$variable
,
$handle
];
break
;
default
:
$this
->
bind
(
$column
,
$variable
,
DB2_PARAM_IN
,
DB2_CHAR
);
break
;
}
return
true
;
}
/**
* @param int $position Parameter position
* @param mixed $variable
*
* @throws Exception
*/
private
function
bind
(
$position
,
&
$variable
,
int
$parameterType
,
int
$dataType
)
:
void
{
$this
->
bindParam
[
$position
]
=&
$variable
;
if
(
!
db2_bind_param
(
$this
->
stmt
,
$position
,
'variable'
,
$parameterType
,
$dataType
))
{
throw
StatementError
::
new
(
$this
->
stmt
);
}
}
/**
* {@inheritdoc}
*/
public
function
execute
(
$params
=
null
)
:
ResultInterface
{
if
(
$params
===
null
)
{
ksort
(
$this
->
bindParam
);
$params
=
[];
foreach
(
$this
->
bindParam
as
$column
=>
$value
)
{
$params
[]
=
$value
;
}
}
foreach
(
$this
->
lobs
as
[
$source
,
$target
])
{
if
(
is_resource
(
$source
))
{
$this
->
copyStreamToStream
(
$source
,
$target
);
continue
;
}
$this
->
writeStringToStream
(
$source
,
$target
);
}
$result
=
db2_execute
(
$this
->
stmt
,
$params
);
foreach
(
$this
->
lobs
as
[,
$handle
])
{
fclose
(
$handle
);
}
$this
->
lobs
=
[];
if
(
$result
===
false
)
{
throw
StatementError
::
new
(
$this
->
stmt
);
}
return
new
Result
(
$this
->
stmt
);
}
/**
* @return resource
*
* @throws Exception
*/
private
function
createTemporaryFile
()
{
$handle
=
@
tmpfile
();
if
(
$handle
===
false
)
{
throw
CannotCreateTemporaryFile
::
new
(
error_get_last
()[
'message'
]);
}
return
$handle
;
}
/**
* @param resource $source
* @param resource $target
*
* @throws Exception
*/
private
function
copyStreamToStream
(
$source
,
$target
)
:
void
{
if
(
@
stream_copy_to_stream
(
$source
,
$target
)
===
false
)
{
throw
CannotCopyStreamToStream
::
new
(
error_get_last
()[
'message'
]);
}
}
/**
* @param resource $target
*
* @throws Exception
*/
private
function
writeStringToStream
(
string
$string
,
$target
)
:
void
{
if
(
@
fwrite
(
$target
,
$string
)
===
false
)
{
throw
CannotWriteToTemporaryFile
::
new
(
error_get_last
()[
'message'
]);
}
}
}
src/Driver/IBMDB2/Statement.php
View file @
8f9e9021
...
...
@@ -2,6 +2,197 @@
namespace
Doctrine\DBAL\Driver\IBMDB2
;
final
class
Statement
extends
DB2Statement
use
Doctrine\DBAL\Driver\Exception
;
use
Doctrine\DBAL\Driver\IBMDB2\Exception\CannotCopyStreamToStream
;
use
Doctrine\DBAL\Driver\IBMDB2\Exception\CannotCreateTemporaryFile
;
use
Doctrine\DBAL\Driver\IBMDB2\Exception\CannotWriteToTemporaryFile
;
use
Doctrine\DBAL\Driver\IBMDB2\Exception\StatementError
;
use
Doctrine\DBAL\Driver\Result
as
ResultInterface
;
use
Doctrine\DBAL\Driver\Statement
as
StatementInterface
;
use
Doctrine\DBAL\ParameterType
;
use
function
assert
;
use
function
db2_bind_param
;
use
function
db2_execute
;
use
function
error_get_last
;
use
function
fclose
;
use
function
fwrite
;
use
function
is_int
;
use
function
is_resource
;
use
function
ksort
;
use
function
stream_copy_to_stream
;
use
function
stream_get_meta_data
;
use
function
tmpfile
;
use
const
DB2_BINARY
;
use
const
DB2_CHAR
;
use
const
DB2_LONG
;
use
const
DB2_PARAM_FILE
;
use
const
DB2_PARAM_IN
;
final
class
Statement
implements
StatementInterface
{
/** @var resource */
private
$stmt
;
/** @var mixed[] */
private
$bindParam
=
[];
/**
* Map of LOB parameter positions to the tuples containing reference to the variable bound to the driver statement
* and the temporary file handle bound to the underlying statement
*
* @var mixed[][]
*/
private
$lobs
=
[];
/**
* @internal The statement can be only instantiated by its driver connection.
*
* @param resource $stmt
*/
public
function
__construct
(
$stmt
)
{
$this
->
stmt
=
$stmt
;
}
/**
* {@inheritdoc}
*/
public
function
bindValue
(
$param
,
$value
,
$type
=
ParameterType
::
STRING
)
{
assert
(
is_int
(
$param
));
return
$this
->
bindParam
(
$param
,
$value
,
$type
);
}
/**
* {@inheritdoc}
*/
public
function
bindParam
(
$column
,
&
$variable
,
$type
=
ParameterType
::
STRING
,
$length
=
null
)
{
assert
(
is_int
(
$column
));
switch
(
$type
)
{
case
ParameterType
::
INTEGER
:
$this
->
bind
(
$column
,
$variable
,
DB2_PARAM_IN
,
DB2_LONG
);
break
;
case
ParameterType
::
LARGE_OBJECT
:
if
(
isset
(
$this
->
lobs
[
$column
]))
{
[,
$handle
]
=
$this
->
lobs
[
$column
];
fclose
(
$handle
);
}
$handle
=
$this
->
createTemporaryFile
();
$path
=
stream_get_meta_data
(
$handle
)[
'uri'
];
$this
->
bind
(
$column
,
$path
,
DB2_PARAM_FILE
,
DB2_BINARY
);
$this
->
lobs
[
$column
]
=
[
&
$variable
,
$handle
];
break
;
default
:
$this
->
bind
(
$column
,
$variable
,
DB2_PARAM_IN
,
DB2_CHAR
);
break
;
}
return
true
;
}
/**
* @param int $position Parameter position
* @param mixed $variable
*
* @throws Exception
*/
private
function
bind
(
$position
,
&
$variable
,
int
$parameterType
,
int
$dataType
)
:
void
{
$this
->
bindParam
[
$position
]
=&
$variable
;
if
(
!
db2_bind_param
(
$this
->
stmt
,
$position
,
'variable'
,
$parameterType
,
$dataType
))
{
throw
StatementError
::
new
(
$this
->
stmt
);
}
}
/**
* {@inheritdoc}
*/
public
function
execute
(
$params
=
null
)
:
ResultInterface
{
if
(
$params
===
null
)
{
ksort
(
$this
->
bindParam
);
$params
=
[];
foreach
(
$this
->
bindParam
as
$column
=>
$value
)
{
$params
[]
=
$value
;
}
}
foreach
(
$this
->
lobs
as
[
$source
,
$target
])
{
if
(
is_resource
(
$source
))
{
$this
->
copyStreamToStream
(
$source
,
$target
);
continue
;
}
$this
->
writeStringToStream
(
$source
,
$target
);
}
$result
=
db2_execute
(
$this
->
stmt
,
$params
);
foreach
(
$this
->
lobs
as
[,
$handle
])
{
fclose
(
$handle
);
}
$this
->
lobs
=
[];
if
(
$result
===
false
)
{
throw
StatementError
::
new
(
$this
->
stmt
);
}
return
new
Result
(
$this
->
stmt
);
}
/**
* @return resource
*
* @throws Exception
*/
private
function
createTemporaryFile
()
{
$handle
=
@
tmpfile
();
if
(
$handle
===
false
)
{
throw
CannotCreateTemporaryFile
::
new
(
error_get_last
()[
'message'
]);
}
return
$handle
;
}
/**
* @param resource $source
* @param resource $target
*
* @throws Exception
*/
private
function
copyStreamToStream
(
$source
,
$target
)
:
void
{
if
(
@
stream_copy_to_stream
(
$source
,
$target
)
===
false
)
{
throw
CannotCopyStreamToStream
::
new
(
error_get_last
()[
'message'
]);
}
}
/**
* @param resource $target
*
* @throws Exception
*/
private
function
writeStringToStream
(
string
$string
,
$target
)
:
void
{
if
(
@
fwrite
(
$target
,
$string
)
===
false
)
{
throw
CannotWriteToTemporaryFile
::
new
(
error_get_last
()[
'message'
]);
}
}
}
src/Driver/Mysqli/MysqliStatement.php
deleted
100644 → 0
View file @
10357097
<?php
namespace
Doctrine\DBAL\Driver\Mysqli
;
use
Doctrine\DBAL\Driver\Exception
;
use
Doctrine\DBAL\Driver\Mysqli\Exception\ConnectionError
;
use
Doctrine\DBAL\Driver\Mysqli\Exception\FailedReadingStreamOffset
;
use
Doctrine\DBAL\Driver\Mysqli\Exception\StatementError
;
use
Doctrine\DBAL\Driver\Mysqli\Exception\UnknownType
;
use
Doctrine\DBAL\Driver\Result
as
ResultInterface
;
use
Doctrine\DBAL\Driver\Statement
as
StatementInterface
;
use
Doctrine\DBAL\Exception\InvalidArgumentException
;
use
Doctrine\DBAL\ParameterType
;
use
mysqli
;
use
mysqli_stmt
;
use
function
array_fill
;
use
function
assert
;
use
function
count
;
use
function
feof
;
use
function
fread
;
use
function
get_resource_type
;
use
function
is_int
;
use
function
is_resource
;
use
function
str_repeat
;
/**
* @deprecated Use {@link Statement} instead
*/
class
MysqliStatement
implements
StatementInterface
{
/** @var string[] */
protected
static
$_paramTypeMap
=
[
ParameterType
::
STRING
=>
's'
,
ParameterType
::
BINARY
=>
's'
,
ParameterType
::
BOOLEAN
=>
'i'
,
ParameterType
::
NULL
=>
's'
,
ParameterType
::
INTEGER
=>
'i'
,
ParameterType
::
LARGE_OBJECT
=>
'b'
,
];
/** @var mysqli */
protected
$_conn
;
/** @var mysqli_stmt */
protected
$_stmt
;
/** @var mixed[] */
protected
$_bindedValues
;
/** @var string */
protected
$types
;
/**
* Contains ref values for bindValue().
*
* @var mixed[]
*/
protected
$_values
=
[];
/**
* @internal The statement can be only instantiated by its driver connection.
*
* @param string $prepareString
*
* @throws Exception
*/
public
function
__construct
(
mysqli
$conn
,
$prepareString
)
{
$this
->
_conn
=
$conn
;
$stmt
=
$conn
->
prepare
(
$prepareString
);
if
(
$stmt
===
false
)
{
throw
ConnectionError
::
new
(
$this
->
_conn
);
}
$this
->
_stmt
=
$stmt
;
$paramCount
=
$this
->
_stmt
->
param_count
;
if
(
0
>=
$paramCount
)
{
return
;
}
$this
->
types
=
str_repeat
(
's'
,
$paramCount
);
$this
->
_bindedValues
=
array_fill
(
1
,
$paramCount
,
null
);
}
/**
* {@inheritdoc}
*/
public
function
bindParam
(
$column
,
&
$variable
,
$type
=
ParameterType
::
STRING
,
$length
=
null
)
{
assert
(
is_int
(
$column
));
if
(
!
isset
(
self
::
$_paramTypeMap
[
$type
]))
{
throw
UnknownType
::
new
(
$type
);
}
$this
->
_bindedValues
[
$column
]
=&
$variable
;
$this
->
types
[
$column
-
1
]
=
self
::
$_paramTypeMap
[
$type
];
return
true
;
}
/**
* {@inheritdoc}
*/
public
function
bindValue
(
$param
,
$value
,
$type
=
ParameterType
::
STRING
)
{
assert
(
is_int
(
$param
));
if
(
!
isset
(
self
::
$_paramTypeMap
[
$type
]))
{
throw
UnknownType
::
new
(
$type
);
}
$this
->
_values
[
$param
]
=
$value
;
$this
->
_bindedValues
[
$param
]
=&
$this
->
_values
[
$param
];
$this
->
types
[
$param
-
1
]
=
self
::
$_paramTypeMap
[
$type
];
return
true
;
}
/**
* {@inheritdoc}
*/
public
function
execute
(
$params
=
null
)
:
ResultInterface
{
if
(
$this
->
_bindedValues
!==
null
)
{
if
(
$params
!==
null
)
{
if
(
!
$this
->
bindUntypedValues
(
$params
))
{
throw
StatementError
::
new
(
$this
->
_stmt
);
}
}
else
{
$this
->
bindTypedParameters
();
}
}
if
(
!
$this
->
_stmt
->
execute
())
{
throw
StatementError
::
new
(
$this
->
_stmt
);
}
return
new
Result
(
$this
->
_stmt
);
}
/**
* Binds parameters with known types previously bound to the statement
*/
private
function
bindTypedParameters
()
:
void
{
$streams
=
$values
=
[];
$types
=
$this
->
types
;
foreach
(
$this
->
_bindedValues
as
$parameter
=>
$value
)
{
assert
(
is_int
(
$parameter
));
if
(
!
isset
(
$types
[
$parameter
-
1
]))
{
$types
[
$parameter
-
1
]
=
static
::
$_paramTypeMap
[
ParameterType
::
STRING
];
}
if
(
$types
[
$parameter
-
1
]
===
static
::
$_paramTypeMap
[
ParameterType
::
LARGE_OBJECT
])
{
if
(
is_resource
(
$value
))
{
if
(
get_resource_type
(
$value
)
!==
'stream'
)
{
throw
new
InvalidArgumentException
(
'Resources passed with the LARGE_OBJECT parameter type must be stream resources.'
);
}
$streams
[
$parameter
]
=
$value
;
$values
[
$parameter
]
=
null
;
continue
;
}
$types
[
$parameter
-
1
]
=
static
::
$_paramTypeMap
[
ParameterType
::
STRING
];
}
$values
[
$parameter
]
=
$value
;
}
if
(
!
$this
->
_stmt
->
bind_param
(
$types
,
...
$values
))
{
throw
StatementError
::
new
(
$this
->
_stmt
);
}
$this
->
sendLongData
(
$streams
);
}
/**
* Handle $this->_longData after regular query parameters have been bound
*
* @param array<int, resource> $streams
*
* @throws Exception
*/
private
function
sendLongData
(
array
$streams
)
:
void
{
foreach
(
$streams
as
$paramNr
=>
$stream
)
{
while
(
!
feof
(
$stream
))
{
$chunk
=
fread
(
$stream
,
8192
);
if
(
$chunk
===
false
)
{
throw
FailedReadingStreamOffset
::
new
(
$paramNr
);
}
if
(
!
$this
->
_stmt
->
send_long_data
(
$paramNr
-
1
,
$chunk
))
{
throw
StatementError
::
new
(
$this
->
_stmt
);
}
}
}
}
/**
* Binds a array of values to bound parameters.
*
* @param mixed[] $values
*
* @return bool
*/
private
function
bindUntypedValues
(
array
$values
)
{
$params
=
[];
$types
=
str_repeat
(
's'
,
count
(
$values
));
foreach
(
$values
as
&
$v
)
{
$params
[]
=&
$v
;
}
return
$this
->
_stmt
->
bind_param
(
$types
,
...
$params
);
}
}
src/Driver/Mysqli/Statement.php
View file @
8f9e9021
...
...
@@ -2,6 +2,223 @@
namespace
Doctrine\DBAL\Driver\Mysqli
;
final
class
Statement
extends
MysqliStatement
use
Doctrine\DBAL\Driver\Exception
;
use
Doctrine\DBAL\Driver\Mysqli\Exception\ConnectionError
;
use
Doctrine\DBAL\Driver\Mysqli\Exception\FailedReadingStreamOffset
;
use
Doctrine\DBAL\Driver\Mysqli\Exception\StatementError
;
use
Doctrine\DBAL\Driver\Mysqli\Exception\UnknownType
;
use
Doctrine\DBAL\Driver\Result
as
ResultInterface
;
use
Doctrine\DBAL\Driver\Statement
as
StatementInterface
;
use
Doctrine\DBAL\Exception\InvalidArgumentException
;
use
Doctrine\DBAL\ParameterType
;
use
mysqli
;
use
mysqli_stmt
;
use
function
array_fill
;
use
function
assert
;
use
function
count
;
use
function
feof
;
use
function
fread
;
use
function
get_resource_type
;
use
function
is_int
;
use
function
is_resource
;
use
function
str_repeat
;
final
class
Statement
implements
StatementInterface
{
/** @var string[] */
protected
static
$_paramTypeMap
=
[
ParameterType
::
STRING
=>
's'
,
ParameterType
::
BINARY
=>
's'
,
ParameterType
::
BOOLEAN
=>
'i'
,
ParameterType
::
NULL
=>
's'
,
ParameterType
::
INTEGER
=>
'i'
,
ParameterType
::
LARGE_OBJECT
=>
'b'
,
];
/** @var mysqli */
protected
$_conn
;
/** @var mysqli_stmt */
protected
$_stmt
;
/** @var mixed[] */
protected
$_bindedValues
;
/** @var string */
protected
$types
;
/**
* Contains ref values for bindValue().
*
* @var mixed[]
*/
protected
$_values
=
[];
/**
* @internal The statement can be only instantiated by its driver connection.
*
* @param string $prepareString
*
* @throws Exception
*/
public
function
__construct
(
mysqli
$conn
,
$prepareString
)
{
$this
->
_conn
=
$conn
;
$stmt
=
$conn
->
prepare
(
$prepareString
);
if
(
$stmt
===
false
)
{
throw
ConnectionError
::
new
(
$this
->
_conn
);
}
$this
->
_stmt
=
$stmt
;
$paramCount
=
$this
->
_stmt
->
param_count
;
if
(
0
>=
$paramCount
)
{
return
;
}
$this
->
types
=
str_repeat
(
's'
,
$paramCount
);
$this
->
_bindedValues
=
array_fill
(
1
,
$paramCount
,
null
);
}
/**
* {@inheritdoc}
*/
public
function
bindParam
(
$column
,
&
$variable
,
$type
=
ParameterType
::
STRING
,
$length
=
null
)
{
assert
(
is_int
(
$column
));
if
(
!
isset
(
self
::
$_paramTypeMap
[
$type
]))
{
throw
UnknownType
::
new
(
$type
);
}
$this
->
_bindedValues
[
$column
]
=&
$variable
;
$this
->
types
[
$column
-
1
]
=
self
::
$_paramTypeMap
[
$type
];
return
true
;
}
/**
* {@inheritdoc}
*/
public
function
bindValue
(
$param
,
$value
,
$type
=
ParameterType
::
STRING
)
{
assert
(
is_int
(
$param
));
if
(
!
isset
(
self
::
$_paramTypeMap
[
$type
]))
{
throw
UnknownType
::
new
(
$type
);
}
$this
->
_values
[
$param
]
=
$value
;
$this
->
_bindedValues
[
$param
]
=&
$this
->
_values
[
$param
];
$this
->
types
[
$param
-
1
]
=
self
::
$_paramTypeMap
[
$type
];
return
true
;
}
/**
* {@inheritdoc}
*/
public
function
execute
(
$params
=
null
)
:
ResultInterface
{
if
(
$this
->
_bindedValues
!==
null
)
{
if
(
$params
!==
null
)
{
if
(
!
$this
->
bindUntypedValues
(
$params
))
{
throw
StatementError
::
new
(
$this
->
_stmt
);
}
}
else
{
$this
->
bindTypedParameters
();
}
}
if
(
!
$this
->
_stmt
->
execute
())
{
throw
StatementError
::
new
(
$this
->
_stmt
);
}
return
new
Result
(
$this
->
_stmt
);
}
/**
* Binds parameters with known types previously bound to the statement
*/
private
function
bindTypedParameters
()
:
void
{
$streams
=
$values
=
[];
$types
=
$this
->
types
;
foreach
(
$this
->
_bindedValues
as
$parameter
=>
$value
)
{
assert
(
is_int
(
$parameter
));
if
(
!
isset
(
$types
[
$parameter
-
1
]))
{
$types
[
$parameter
-
1
]
=
static
::
$_paramTypeMap
[
ParameterType
::
STRING
];
}
if
(
$types
[
$parameter
-
1
]
===
static
::
$_paramTypeMap
[
ParameterType
::
LARGE_OBJECT
])
{
if
(
is_resource
(
$value
))
{
if
(
get_resource_type
(
$value
)
!==
'stream'
)
{
throw
new
InvalidArgumentException
(
'Resources passed with the LARGE_OBJECT parameter type must be stream resources.'
);
}
$streams
[
$parameter
]
=
$value
;
$values
[
$parameter
]
=
null
;
continue
;
}
$types
[
$parameter
-
1
]
=
static
::
$_paramTypeMap
[
ParameterType
::
STRING
];
}
$values
[
$parameter
]
=
$value
;
}
if
(
!
$this
->
_stmt
->
bind_param
(
$types
,
...
$values
))
{
throw
StatementError
::
new
(
$this
->
_stmt
);
}
$this
->
sendLongData
(
$streams
);
}
/**
* Handle $this->_longData after regular query parameters have been bound
*
* @param array<int, resource> $streams
*
* @throws Exception
*/
private
function
sendLongData
(
array
$streams
)
:
void
{
foreach
(
$streams
as
$paramNr
=>
$stream
)
{
while
(
!
feof
(
$stream
))
{
$chunk
=
fread
(
$stream
,
8192
);
if
(
$chunk
===
false
)
{
throw
FailedReadingStreamOffset
::
new
(
$paramNr
);
}
if
(
!
$this
->
_stmt
->
send_long_data
(
$paramNr
-
1
,
$chunk
))
{
throw
StatementError
::
new
(
$this
->
_stmt
);
}
}
}
}
/**
* Binds a array of values to bound parameters.
*
* @param mixed[] $values
*
* @return bool
*/
private
function
bindUntypedValues
(
array
$values
)
{
$params
=
[];
$types
=
str_repeat
(
's'
,
count
(
$values
));
foreach
(
$values
as
&
$v
)
{
$params
[]
=&
$v
;
}
return
$this
->
_stmt
->
bind_param
(
$types
,
...
$params
);
}
}
src/Driver/OCI8/OCI8Statement.php
deleted
100644 → 0
View file @
10357097
<?php
namespace
Doctrine\DBAL\Driver\OCI8
;
use
Doctrine\DBAL\Driver\OCI8\Exception\Error
;
use
Doctrine\DBAL\Driver\OCI8\Exception\UnknownParameterIndex
;
use
Doctrine\DBAL\Driver\Result
as
ResultInterface
;
use
Doctrine\DBAL\Driver\Statement
as
StatementInterface
;
use
Doctrine\DBAL\ParameterType
;
use
function
assert
;
use
function
is_int
;
use
function
is_resource
;
use
function
oci_bind_by_name
;
use
function
oci_execute
;
use
function
oci_new_descriptor
;
use
function
oci_parse
;
use
const
OCI_B_BIN
;
use
const
OCI_B_BLOB
;
use
const
OCI_COMMIT_ON_SUCCESS
;
use
const
OCI_D_LOB
;
use
const
OCI_NO_AUTO_COMMIT
;
use
const
OCI_TEMP_BLOB
;
use
const
SQLT_CHR
;
/**
* The OCI8 implementation of the Statement interface.
*
* @deprecated Use {@link Statement} instead
*/
class
OCI8Statement
implements
StatementInterface
{
/** @var resource */
protected
$_dbh
;
/** @var resource */
protected
$_sth
;
/** @var ExecutionMode */
private
$executionMode
;
/** @var string[] */
protected
$_paramMap
=
[];
/**
* Holds references to bound parameter values.
*
* This is a new requirement for PHP7's oci8 extension that prevents bound values from being garbage collected.
*
* @var mixed[]
*/
private
$boundValues
=
[];
/**
* Creates a new OCI8Statement that uses the given connection handle and SQL statement.
*
* @internal The statement can be only instantiated by its driver connection.
*
* @param resource $dbh The connection handle.
* @param string $query The SQL query.
*/
public
function
__construct
(
$dbh
,
$query
,
ExecutionMode
$executionMode
)
{
[
$query
,
$paramMap
]
=
(
new
ConvertPositionalToNamedPlaceholders
())(
$query
);
$stmt
=
oci_parse
(
$dbh
,
$query
);
assert
(
is_resource
(
$stmt
));
$this
->
_sth
=
$stmt
;
$this
->
_dbh
=
$dbh
;
$this
->
_paramMap
=
$paramMap
;
$this
->
executionMode
=
$executionMode
;
}
/**
* {@inheritdoc}
*/
public
function
bindValue
(
$param
,
$value
,
$type
=
ParameterType
::
STRING
)
{
return
$this
->
bindParam
(
$param
,
$value
,
$type
,
null
);
}
/**
* {@inheritdoc}
*/
public
function
bindParam
(
$param
,
&
$variable
,
$type
=
ParameterType
::
STRING
,
$length
=
null
)
{
if
(
is_int
(
$param
))
{
if
(
!
isset
(
$this
->
_paramMap
[
$param
]))
{
throw
UnknownParameterIndex
::
new
(
$param
);
}
$param
=
$this
->
_paramMap
[
$param
];
}
if
(
$type
===
ParameterType
::
LARGE_OBJECT
)
{
$lob
=
oci_new_descriptor
(
$this
->
_dbh
,
OCI_D_LOB
);
$class
=
'OCI-Lob'
;
assert
(
$lob
instanceof
$class
);
$lob
->
writetemporary
(
$variable
,
OCI_TEMP_BLOB
);
$variable
=&
$lob
;
}
$this
->
boundValues
[
$param
]
=&
$variable
;
return
oci_bind_by_name
(
$this
->
_sth
,
$param
,
$variable
,
$length
??
-
1
,
$this
->
convertParameterType
(
$type
)
);
}
/**
* Converts DBAL parameter type to oci8 parameter type
*/
private
function
convertParameterType
(
int
$type
)
:
int
{
switch
(
$type
)
{
case
ParameterType
::
BINARY
:
return
OCI_B_BIN
;
case
ParameterType
::
LARGE_OBJECT
:
return
OCI_B_BLOB
;
default
:
return
SQLT_CHR
;
}
}
/**
* {@inheritdoc}
*/
public
function
execute
(
$params
=
null
)
:
ResultInterface
{
if
(
$params
!==
null
)
{
foreach
(
$params
as
$key
=>
$val
)
{
if
(
is_int
(
$key
))
{
$this
->
bindValue
(
$key
+
1
,
$val
);
}
else
{
$this
->
bindValue
(
$key
,
$val
);
}
}
}
if
(
$this
->
executionMode
->
isAutoCommitEnabled
())
{
$mode
=
OCI_COMMIT_ON_SUCCESS
;
}
else
{
$mode
=
OCI_NO_AUTO_COMMIT
;
}
$ret
=
@
oci_execute
(
$this
->
_sth
,
$mode
);
if
(
!
$ret
)
{
throw
Error
::
new
(
$this
->
_sth
);
}
return
new
Result
(
$this
->
_sth
);
}
}
src/Driver/OCI8/Statement.php
View file @
8f9e9021
...
...
@@ -2,6 +2,158 @@
namespace
Doctrine\DBAL\Driver\OCI8
;
final
class
Statement
extends
OCI8Statement
use
Doctrine\DBAL\Driver\OCI8\Exception\Error
;
use
Doctrine\DBAL\Driver\OCI8\Exception\UnknownParameterIndex
;
use
Doctrine\DBAL\Driver\Result
as
ResultInterface
;
use
Doctrine\DBAL\Driver\Statement
as
StatementInterface
;
use
Doctrine\DBAL\ParameterType
;
use
function
assert
;
use
function
is_int
;
use
function
is_resource
;
use
function
oci_bind_by_name
;
use
function
oci_execute
;
use
function
oci_new_descriptor
;
use
function
oci_parse
;
use
const
OCI_B_BIN
;
use
const
OCI_B_BLOB
;
use
const
OCI_COMMIT_ON_SUCCESS
;
use
const
OCI_D_LOB
;
use
const
OCI_NO_AUTO_COMMIT
;
use
const
OCI_TEMP_BLOB
;
use
const
SQLT_CHR
;
final
class
Statement
implements
StatementInterface
{
/** @var resource */
protected
$_dbh
;
/** @var resource */
protected
$_sth
;
/** @var ExecutionMode */
private
$executionMode
;
/** @var string[] */
protected
$_paramMap
=
[];
/**
* Holds references to bound parameter values.
*
* This is a new requirement for PHP7's oci8 extension that prevents bound values from being garbage collected.
*
* @var mixed[]
*/
private
$boundValues
=
[];
/**
* Creates a new OCI8Statement that uses the given connection handle and SQL statement.
*
* @internal The statement can be only instantiated by its driver connection.
*
* @param resource $dbh The connection handle.
* @param string $query The SQL query.
*/
public
function
__construct
(
$dbh
,
$query
,
ExecutionMode
$executionMode
)
{
[
$query
,
$paramMap
]
=
(
new
ConvertPositionalToNamedPlaceholders
())(
$query
);
$stmt
=
oci_parse
(
$dbh
,
$query
);
assert
(
is_resource
(
$stmt
));
$this
->
_sth
=
$stmt
;
$this
->
_dbh
=
$dbh
;
$this
->
_paramMap
=
$paramMap
;
$this
->
executionMode
=
$executionMode
;
}
/**
* {@inheritdoc}
*/
public
function
bindValue
(
$param
,
$value
,
$type
=
ParameterType
::
STRING
)
{
return
$this
->
bindParam
(
$param
,
$value
,
$type
,
null
);
}
/**
* {@inheritdoc}
*/
public
function
bindParam
(
$param
,
&
$variable
,
$type
=
ParameterType
::
STRING
,
$length
=
null
)
{
if
(
is_int
(
$param
))
{
if
(
!
isset
(
$this
->
_paramMap
[
$param
]))
{
throw
UnknownParameterIndex
::
new
(
$param
);
}
$param
=
$this
->
_paramMap
[
$param
];
}
if
(
$type
===
ParameterType
::
LARGE_OBJECT
)
{
$lob
=
oci_new_descriptor
(
$this
->
_dbh
,
OCI_D_LOB
);
$class
=
'OCI-Lob'
;
assert
(
$lob
instanceof
$class
);
$lob
->
writetemporary
(
$variable
,
OCI_TEMP_BLOB
);
$variable
=&
$lob
;
}
$this
->
boundValues
[
$param
]
=&
$variable
;
return
oci_bind_by_name
(
$this
->
_sth
,
$param
,
$variable
,
$length
??
-
1
,
$this
->
convertParameterType
(
$type
)
);
}
/**
* Converts DBAL parameter type to oci8 parameter type
*/
private
function
convertParameterType
(
int
$type
)
:
int
{
switch
(
$type
)
{
case
ParameterType
::
BINARY
:
return
OCI_B_BIN
;
case
ParameterType
::
LARGE_OBJECT
:
return
OCI_B_BLOB
;
default
:
return
SQLT_CHR
;
}
}
/**
* {@inheritdoc}
*/
public
function
execute
(
$params
=
null
)
:
ResultInterface
{
if
(
$params
!==
null
)
{
foreach
(
$params
as
$key
=>
$val
)
{
if
(
is_int
(
$key
))
{
$this
->
bindValue
(
$key
+
1
,
$val
);
}
else
{
$this
->
bindValue
(
$key
,
$val
);
}
}
}
if
(
$this
->
executionMode
->
isAutoCommitEnabled
())
{
$mode
=
OCI_COMMIT_ON_SUCCESS
;
}
else
{
$mode
=
OCI_NO_AUTO_COMMIT
;
}
$ret
=
@
oci_execute
(
$this
->
_sth
,
$mode
);
if
(
!
$ret
)
{
throw
Error
::
new
(
$this
->
_sth
);
}
return
new
Result
(
$this
->
_sth
);
}
}
src/Driver/PDO/Statement.php
View file @
8f9e9021
...
...
@@ -2,8 +2,98 @@
namespace
Doctrine\DBAL\Driver\PDO
;
use
Doctrine\DBAL\Driver\PDOStatement
;
use
Doctrine\DBAL\Driver\Result
as
ResultInterface
;
use
Doctrine\DBAL\Driver\Statement
as
StatementInterface
;
use
Doctrine\DBAL\ParameterType
;
use
InvalidArgumentException
;
use
PDO
;
use
PDOException
;
use
PDOStatement
;
class
Statement
extends
PDOStatement
use
function
array_slice
;
use
function
func_get_args
;
class
Statement
implements
StatementInterface
{
private
const
PARAM_TYPE_MAP
=
[
ParameterType
::
NULL
=>
PDO
::
PARAM_NULL
,
ParameterType
::
INTEGER
=>
PDO
::
PARAM_INT
,
ParameterType
::
STRING
=>
PDO
::
PARAM_STR
,
ParameterType
::
BINARY
=>
PDO
::
PARAM_LOB
,
ParameterType
::
LARGE_OBJECT
=>
PDO
::
PARAM_LOB
,
ParameterType
::
BOOLEAN
=>
PDO
::
PARAM_BOOL
,
];
/** @var PDOStatement */
private
$stmt
;
/**
* @internal The statement can be only instantiated by its driver connection.
*/
public
function
__construct
(
PDOStatement
$stmt
)
{
$this
->
stmt
=
$stmt
;
}
/**
* {@inheritdoc}
*/
public
function
bindValue
(
$param
,
$value
,
$type
=
ParameterType
::
STRING
)
{
$type
=
$this
->
convertParamType
(
$type
);
try
{
return
$this
->
stmt
->
bindValue
(
$param
,
$value
,
$type
);
}
catch
(
PDOException
$exception
)
{
throw
Exception
::
new
(
$exception
);
}
}
/**
* @param mixed $column
* @param mixed $variable
* @param int $type
* @param int|null $length
* @param mixed $driverOptions
*
* @return bool
*/
public
function
bindParam
(
$column
,
&
$variable
,
$type
=
ParameterType
::
STRING
,
$length
=
null
,
$driverOptions
=
null
)
{
$type
=
$this
->
convertParamType
(
$type
);
try
{
return
$this
->
stmt
->
bindParam
(
$column
,
$variable
,
$type
,
...
array_slice
(
func_get_args
(),
3
));
}
catch
(
PDOException
$exception
)
{
throw
Exception
::
new
(
$exception
);
}
}
/**
* {@inheritdoc}
*/
public
function
execute
(
$params
=
null
)
:
ResultInterface
{
try
{
$this
->
stmt
->
execute
(
$params
);
}
catch
(
PDOException
$exception
)
{
throw
Exception
::
new
(
$exception
);
}
return
new
Result
(
$this
->
stmt
);
}
/**
* Converts DBAL parameter type to PDO parameter type
*
* @param int $type Parameter type
*/
private
function
convertParamType
(
int
$type
)
:
int
{
if
(
!
isset
(
self
::
PARAM_TYPE_MAP
[
$type
]))
{
throw
new
InvalidArgumentException
(
'Invalid parameter type: '
.
$type
);
}
return
self
::
PARAM_TYPE_MAP
[
$type
];
}
}
src/Driver/PDOStatement.php
deleted
100644 → 0
View file @
10357097
<?php
namespace
Doctrine\DBAL\Driver
;
use
Doctrine\DBAL\Driver\PDO\Exception
;
use
Doctrine\DBAL\Driver\PDO\Result
;
use
Doctrine\DBAL\Driver\Result
as
ResultInterface
;
use
Doctrine\DBAL\Driver\Statement
as
StatementInterface
;
use
Doctrine\DBAL\ParameterType
;
use
InvalidArgumentException
;
use
PDO
;
use
PDOException
;
use
function
array_slice
;
use
function
func_get_args
;
/**
* The PDO implementation of the Statement interface.
* Used by all PDO-based drivers.
*
* @deprecated Use {@link Statement} instead
*/
class
PDOStatement
implements
StatementInterface
{
private
const
PARAM_TYPE_MAP
=
[
ParameterType
::
NULL
=>
PDO
::
PARAM_NULL
,
ParameterType
::
INTEGER
=>
PDO
::
PARAM_INT
,
ParameterType
::
STRING
=>
PDO
::
PARAM_STR
,
ParameterType
::
BINARY
=>
PDO
::
PARAM_LOB
,
ParameterType
::
LARGE_OBJECT
=>
PDO
::
PARAM_LOB
,
ParameterType
::
BOOLEAN
=>
PDO
::
PARAM_BOOL
,
];
/** @var \PDOStatement */
private
$stmt
;
/**
* @internal The statement can be only instantiated by its driver connection.
*/
public
function
__construct
(
\PDOStatement
$stmt
)
{
$this
->
stmt
=
$stmt
;
}
/**
* {@inheritdoc}
*/
public
function
bindValue
(
$param
,
$value
,
$type
=
ParameterType
::
STRING
)
{
$type
=
$this
->
convertParamType
(
$type
);
try
{
return
$this
->
stmt
->
bindValue
(
$param
,
$value
,
$type
);
}
catch
(
PDOException
$exception
)
{
throw
Exception
::
new
(
$exception
);
}
}
/**
* @param mixed $column
* @param mixed $variable
* @param int $type
* @param int|null $length
* @param mixed $driverOptions
*
* @return bool
*/
public
function
bindParam
(
$column
,
&
$variable
,
$type
=
ParameterType
::
STRING
,
$length
=
null
,
$driverOptions
=
null
)
{
$type
=
$this
->
convertParamType
(
$type
);
try
{
return
$this
->
stmt
->
bindParam
(
$column
,
$variable
,
$type
,
...
array_slice
(
func_get_args
(),
3
));
}
catch
(
PDOException
$exception
)
{
throw
Exception
::
new
(
$exception
);
}
}
/**
* {@inheritdoc}
*/
public
function
execute
(
$params
=
null
)
:
ResultInterface
{
try
{
$this
->
stmt
->
execute
(
$params
);
}
catch
(
PDOException
$exception
)
{
throw
Exception
::
new
(
$exception
);
}
return
new
Result
(
$this
->
stmt
);
}
/**
* Converts DBAL parameter type to PDO parameter type
*
* @param int $type Parameter type
*/
private
function
convertParamType
(
int
$type
)
:
int
{
if
(
!
isset
(
self
::
PARAM_TYPE_MAP
[
$type
]))
{
throw
new
InvalidArgumentException
(
'Invalid parameter type: '
.
$type
);
}
return
self
::
PARAM_TYPE_MAP
[
$type
];
}
}
src/Driver/SQLSrv/SQLSrvStatement.php
deleted
100644 → 0
View file @
10357097
<?php
namespace
Doctrine\DBAL\Driver\SQLSrv
;
use
Doctrine\DBAL\Driver\Exception
;
use
Doctrine\DBAL\Driver\Result
as
ResultInterface
;
use
Doctrine\DBAL\Driver\SQLSrv\Exception\Error
;
use
Doctrine\DBAL\Driver\Statement
as
StatementInterface
;
use
Doctrine\DBAL\ParameterType
;
use
function
assert
;
use
function
is_int
;
use
function
sqlsrv_execute
;
use
function
sqlsrv_fetch
;
use
function
sqlsrv_get_field
;
use
function
sqlsrv_next_result
;
use
function
SQLSRV_PHPTYPE_STREAM
;
use
function
SQLSRV_PHPTYPE_STRING
;
use
function
sqlsrv_prepare
;
use
function
SQLSRV_SQLTYPE_VARBINARY
;
use
function
stripos
;
use
const
SQLSRV_ENC_BINARY
;
use
const
SQLSRV_PARAM_IN
;
/**
* SQL Server Statement.
*
* @deprecated Use {@link Statement} instead
*/
class
SQLSrvStatement
implements
StatementInterface
{
/**
* The SQLSRV Resource.
*
* @var resource
*/
private
$conn
;
/**
* The SQL statement to execute.
*
* @var string
*/
private
$sql
;
/**
* The SQLSRV statement resource.
*
* @var resource|null
*/
private
$stmt
;
/**
* References to the variables bound as statement parameters.
*
* @var mixed
*/
private
$variables
=
[];
/**
* Bound parameter types.
*
* @var int[]
*/
private
$types
=
[];
/**
* The last insert ID.
*
* @var LastInsertId|null
*/
private
$lastInsertId
;
/**
* Append to any INSERT query to retrieve the last insert id.
*/
private
const
LAST_INSERT_ID_SQL
=
';SELECT SCOPE_IDENTITY() AS LastInsertId;'
;
/**
* @internal The statement can be only instantiated by its driver connection.
*
* @param resource $conn
* @param string $sql
*/
public
function
__construct
(
$conn
,
$sql
,
?
LastInsertId
$lastInsertId
=
null
)
{
$this
->
conn
=
$conn
;
$this
->
sql
=
$sql
;
if
(
stripos
(
$sql
,
'INSERT INTO '
)
!==
0
)
{
return
;
}
$this
->
sql
.=
self
::
LAST_INSERT_ID_SQL
;
$this
->
lastInsertId
=
$lastInsertId
;
}
/**
* {@inheritdoc}
*/
public
function
bindValue
(
$param
,
$value
,
$type
=
ParameterType
::
STRING
)
{
assert
(
is_int
(
$param
));
$this
->
variables
[
$param
]
=
$value
;
$this
->
types
[
$param
]
=
$type
;
return
true
;
}
/**
* {@inheritdoc}
*/
public
function
bindParam
(
$column
,
&
$variable
,
$type
=
ParameterType
::
STRING
,
$length
=
null
)
{
assert
(
is_int
(
$column
));
$this
->
variables
[
$column
]
=&
$variable
;
$this
->
types
[
$column
]
=
$type
;
// unset the statement resource if it exists as the new one will need to be bound to the new variable
$this
->
stmt
=
null
;
return
true
;
}
/**
* {@inheritdoc}
*/
public
function
execute
(
$params
=
null
)
:
ResultInterface
{
if
(
$params
!==
null
)
{
foreach
(
$params
as
$key
=>
$val
)
{
if
(
is_int
(
$key
))
{
$this
->
bindValue
(
$key
+
1
,
$val
);
}
else
{
$this
->
bindValue
(
$key
,
$val
);
}
}
}
if
(
$this
->
stmt
===
null
)
{
$this
->
stmt
=
$this
->
prepare
();
}
if
(
!
sqlsrv_execute
(
$this
->
stmt
))
{
throw
Error
::
new
();
}
if
(
$this
->
lastInsertId
!==
null
)
{
sqlsrv_next_result
(
$this
->
stmt
);
sqlsrv_fetch
(
$this
->
stmt
);
$this
->
lastInsertId
->
setId
(
sqlsrv_get_field
(
$this
->
stmt
,
0
));
}
return
new
Result
(
$this
->
stmt
);
}
/**
* Prepares SQL Server statement resource
*
* @return resource
*
* @throws Exception
*/
private
function
prepare
()
{
$params
=
[];
foreach
(
$this
->
variables
as
$column
=>
&
$variable
)
{
switch
(
$this
->
types
[
$column
])
{
case
ParameterType
::
LARGE_OBJECT
:
$params
[
$column
-
1
]
=
[
&
$variable
,
SQLSRV_PARAM_IN
,
SQLSRV_PHPTYPE_STREAM
(
SQLSRV_ENC_BINARY
),
SQLSRV_SQLTYPE_VARBINARY
(
'max'
),
];
break
;
case
ParameterType
::
BINARY
:
$params
[
$column
-
1
]
=
[
&
$variable
,
SQLSRV_PARAM_IN
,
SQLSRV_PHPTYPE_STRING
(
SQLSRV_ENC_BINARY
),
];
break
;
default
:
$params
[
$column
-
1
]
=&
$variable
;
break
;
}
}
$stmt
=
sqlsrv_prepare
(
$this
->
conn
,
$this
->
sql
,
$params
);
if
(
$stmt
===
false
)
{
throw
Error
::
new
();
}
return
$stmt
;
}
}
src/Driver/SQLSrv/Statement.php
View file @
8f9e9021
...
...
@@ -2,6 +2,198 @@
namespace
Doctrine\DBAL\Driver\SQLSrv
;
final
class
Statement
extends
SQLSrvStatement
use
Doctrine\DBAL\Driver\Exception
;
use
Doctrine\DBAL\Driver\Result
as
ResultInterface
;
use
Doctrine\DBAL\Driver\SQLSrv\Exception\Error
;
use
Doctrine\DBAL\Driver\Statement
as
StatementInterface
;
use
Doctrine\DBAL\ParameterType
;
use
function
assert
;
use
function
is_int
;
use
function
sqlsrv_execute
;
use
function
sqlsrv_fetch
;
use
function
sqlsrv_get_field
;
use
function
sqlsrv_next_result
;
use
function
SQLSRV_PHPTYPE_STREAM
;
use
function
SQLSRV_PHPTYPE_STRING
;
use
function
sqlsrv_prepare
;
use
function
SQLSRV_SQLTYPE_VARBINARY
;
use
function
stripos
;
use
const
SQLSRV_ENC_BINARY
;
use
const
SQLSRV_PARAM_IN
;
final
class
Statement
implements
StatementInterface
{
/**
* The SQLSRV Resource.
*
* @var resource
*/
private
$conn
;
/**
* The SQL statement to execute.
*
* @var string
*/
private
$sql
;
/**
* The SQLSRV statement resource.
*
* @var resource|null
*/
private
$stmt
;
/**
* References to the variables bound as statement parameters.
*
* @var mixed
*/
private
$variables
=
[];
/**
* Bound parameter types.
*
* @var int[]
*/
private
$types
=
[];
/**
* The last insert ID.
*
* @var LastInsertId|null
*/
private
$lastInsertId
;
/**
* Append to any INSERT query to retrieve the last insert id.
*/
private
const
LAST_INSERT_ID_SQL
=
';SELECT SCOPE_IDENTITY() AS LastInsertId;'
;
/**
* @internal The statement can be only instantiated by its driver connection.
*
* @param resource $conn
* @param string $sql
*/
public
function
__construct
(
$conn
,
$sql
,
?
LastInsertId
$lastInsertId
=
null
)
{
$this
->
conn
=
$conn
;
$this
->
sql
=
$sql
;
if
(
stripos
(
$sql
,
'INSERT INTO '
)
!==
0
)
{
return
;
}
$this
->
sql
.=
self
::
LAST_INSERT_ID_SQL
;
$this
->
lastInsertId
=
$lastInsertId
;
}
/**
* {@inheritdoc}
*/
public
function
bindValue
(
$param
,
$value
,
$type
=
ParameterType
::
STRING
)
{
assert
(
is_int
(
$param
));
$this
->
variables
[
$param
]
=
$value
;
$this
->
types
[
$param
]
=
$type
;
return
true
;
}
/**
* {@inheritdoc}
*/
public
function
bindParam
(
$column
,
&
$variable
,
$type
=
ParameterType
::
STRING
,
$length
=
null
)
{
assert
(
is_int
(
$column
));
$this
->
variables
[
$column
]
=&
$variable
;
$this
->
types
[
$column
]
=
$type
;
// unset the statement resource if it exists as the new one will need to be bound to the new variable
$this
->
stmt
=
null
;
return
true
;
}
/**
* {@inheritdoc}
*/
public
function
execute
(
$params
=
null
)
:
ResultInterface
{
if
(
$params
!==
null
)
{
foreach
(
$params
as
$key
=>
$val
)
{
if
(
is_int
(
$key
))
{
$this
->
bindValue
(
$key
+
1
,
$val
);
}
else
{
$this
->
bindValue
(
$key
,
$val
);
}
}
}
if
(
$this
->
stmt
===
null
)
{
$this
->
stmt
=
$this
->
prepare
();
}
if
(
!
sqlsrv_execute
(
$this
->
stmt
))
{
throw
Error
::
new
();
}
if
(
$this
->
lastInsertId
!==
null
)
{
sqlsrv_next_result
(
$this
->
stmt
);
sqlsrv_fetch
(
$this
->
stmt
);
$this
->
lastInsertId
->
setId
(
sqlsrv_get_field
(
$this
->
stmt
,
0
));
}
return
new
Result
(
$this
->
stmt
);
}
/**
* Prepares SQL Server statement resource
*
* @return resource
*
* @throws Exception
*/
private
function
prepare
()
{
$params
=
[];
foreach
(
$this
->
variables
as
$column
=>
&
$variable
)
{
switch
(
$this
->
types
[
$column
])
{
case
ParameterType
::
LARGE_OBJECT
:
$params
[
$column
-
1
]
=
[
&
$variable
,
SQLSRV_PARAM_IN
,
SQLSRV_PHPTYPE_STREAM
(
SQLSRV_ENC_BINARY
),
SQLSRV_SQLTYPE_VARBINARY
(
'max'
),
];
break
;
case
ParameterType
::
BINARY
:
$params
[
$column
-
1
]
=
[
&
$variable
,
SQLSRV_PARAM_IN
,
SQLSRV_PHPTYPE_STRING
(
SQLSRV_ENC_BINARY
),
];
break
;
default
:
$params
[
$column
-
1
]
=&
$variable
;
break
;
}
}
$stmt
=
sqlsrv_prepare
(
$this
->
conn
,
$this
->
sql
,
$params
);
if
(
$stmt
===
false
)
{
throw
Error
::
new
();
}
return
$stmt
;
}
}
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