Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 27 additions & 16 deletions src/Statement.php
Original file line number Diff line number Diff line change
Expand Up @@ -209,28 +209,39 @@ protected function bindParametersFromContainer(): void
$args = [];

foreach ($parameters as $name => &$value) {
if ($this->parameterContainer->offsetHasErrata($name)) {
switch ($this->parameterContainer->offsetGetErrata($name)) {
case ParameterContainer::TYPE_DOUBLE:
$type .= 'd';
break;
case ParameterContainer::TYPE_NULL:
$value = null; // as per @see http://www.php.net/manual/en/mysqli-stmt.bind-param.php#96148
case ParameterContainer::TYPE_INTEGER:
$type .= 'i';
break;
case ParameterContainer::TYPE_STRING:
default:
$type .= 's';
break;
}
}
$args[] = &$value;

if (! $this->parameterContainer->offsetHasErrata($name)) {
$type .= 's';
continue;
}

switch ($this->parameterContainer->offsetGetErrata($name)) {
case ParameterContainer::TYPE_DOUBLE:
$type .= 'd';
break;
case ParameterContainer::TYPE_NULL:
$value = null; // as per @see http://www.php.net/manual/en/mysqli-stmt.bind-param.php#96148
case ParameterContainer::TYPE_INTEGER:
$type .= 'i';
break;
case ParameterContainer::TYPE_STRING:
default:
$type .= 's';
break;
}
}

if ($args) {
array_unshift($args, $type);
call_user_func_array([$this->resource, 'bind_param'], $args);
}
}

/** Perform a deep clone */
public function __clone(): void
{
$this->isPrepared = false;
$this->parameterContainer = clone $this->parameterContainer;
}
}
30 changes: 30 additions & 0 deletions test/integration/Mysqli/StatementResultTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,36 @@ public function bindsDoubleAndNullParameterTypes(): void
static::assertTrue($result->isQueryResult());
}

#[Test]
public function bindsMixedTypedAndUntypedParameters(): void
{
$container = new ParameterContainer();
$container->offsetSet('id', 1, ParameterContainer::TYPE_INTEGER);
$container->offsetSet('value', 'bar');

$result = $this->createDriver(false)
->createStatement('SELECT * FROM test WHERE id = ? AND value = ?')
->execute($container);

static::assertNotNull($result);
static::assertSame(['id' => 1, 'name' => 'foo', 'value' => 'bar'], $result->current());
}

#[Test]
public function bindsUntypedParametersAsStrings(): void
{
$container = new ParameterContainer();
$container->offsetSet('id', '1');
$container->offsetSet('value', 'bar');

$result = $this->createDriver(false)
->createStatement('SELECT * FROM test WHERE id = ? AND value = ?')
->execute($container);

static::assertNotNull($result);
static::assertSame(['id' => 1, 'name' => 'foo', 'value' => 'bar'], $result->current());
}

#[Test]
public function bufferAfterIterationStartedThrows(): void
{
Expand Down
28 changes: 28 additions & 0 deletions test/unit/StatementTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,47 @@

namespace PhpDbTest\Mysql;

use mysqli_stmt;
use PhpDb\Adapter\Driver\DriverInterface;
use PhpDb\Adapter\Exception\InvalidArgumentException;
use PhpDb\Adapter\ParameterContainer;
use PhpDb\Adapter\Profiler\ProfilerInterface;
use PhpDb\Mysql\Statement;
use PHPUnit\Framework\Attributes\CoversMethod;
use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;

#[CoversMethod(Statement::class, 'getProfiler')]
#[CoversMethod(Statement::class, 'setProfiler')]
#[CoversMethod(Statement::class, 'setDriver')]
#[CoversMethod(Statement::class, '__clone')]
#[Group('unit')]
final class StatementTest extends TestCase
{
#[Test]
public function cloneCopiesTheParameterContainer(): void
{
$container = new ParameterContainer(['id' => 1]);
$statement = new Statement($container);

$clone = clone $statement;

static::assertNotSame($container, $clone->getParameterContainer());
static::assertEquals($container, $clone->getParameterContainer());
}

#[Test]
public function cloneIsNotPrepared(): void
{
$statement = new Statement();
$statement->setResource($this->createStub(mysqli_stmt::class));

$clone = clone $statement;

static::assertFalse($clone->isPrepared());
}

#[Test]
public function profilerAccessors(): void
{
Expand Down
Loading