Inserting false
into a boolean column yields an error ONLY when the column name includes an underscore. Passing true
or null
works. Also, if the column name does not include an underscore, the error does not occur.
I’m using the docker dev repo.
Error message
Using mysql
An exception occurred while executing a query: SQLSTATE[22007]: Invalid datetime format: 1366 Incorrect integer value: '' for column `nextcloud`.`oc_test_foos`.`bar_baz` at row 1
Using pgsql
An exception occurred while executing a query: SQLSTATE[22P02]: Invalid text representation: 7 ERROR: invalid input syntax for type boolean: \"\"\nCONTEXT: unnamed portal parameter $1 = ''
Example code
Migration
<?php
declare(strict_types=1);
namespace OCA\Test\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\DB\Types;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version010000Date20240926220000 extends SimpleMigrationStep
{
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options)
{
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
if (!$schema->hasTable('test_foos')) {
$table = $schema->createTable('test_foos');
$table->addColumn('id', Types::BIGINT, ['autoincrement' => true]);
$table->addColumn('bar_baz', Types::BOOLEAN, ['notnull' => false, 'default' => false]);
$table->setPrimaryKey(['id']);
}
return $schema;
}
}
Entity
<?php
declare(strict_types=1);
namespace OCA\Test\Db;
use JsonSerializable;
use OCP\AppFramework\Db\Entity;
/**
* @method bool getBarBaz()
* @method void setBarBaz(bool $barBaz)
*/
class Foo extends Entity implements JsonSerializable
{
/** @var bool */
protected $barBaz;
public function __construct()
{
$this->addType('bar_baz', 'boolean');
}
public function jsonSerialize(): mixed
{
return [
'id' => $this->id,
'bar_baz' => $this->barBaz,
];
}
}
Mapper
<?php
declare(strict_types=1);
namespace OCA\Test\Db;
use OCP\AppFramework\Db\QBMapper;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
class FooMapper extends QBMapper
{
public function __construct(IDBConnection $db)
{
parent::__construct($db, 'test_foos', Foo::class);
}
public function create(bool $barBaz): Foo
{
$foo = new Foo();
$foo->setBarBaz($barBaz);
return $this->insert($foo);
}
}
Controller
<?php
declare(strict_types=1);
namespace OCA\Test\Controller;
use OCA\Test\Db\FooMapper;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\Attribute\FrontpageRoute;
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
use OCP\AppFramework\Http\Attribute\NoCSRFRequired;
use OCP\AppFramework\Http\DataResponse;
use OCP\IRequest;
use Throwable;
class FooController extends Controller
{
public function __construct(
string $appName,
IRequest $request,
private FooMapper $fooMapper,
) {
parent::__construct($appName, $request);
}
#[NoAdminRequired]
#[NoCSRFRequired]
#[FrontpageRoute(verb: 'POST', url: '/foos')]
public function create(bool $bar_baz): DataResponse
{
try {
return new DataResponse($this->fooMapper->create($bar_baz));
} catch (Throwable $th) {
return new DataResponse(['error' => $th->getMessage()], Http::STATUS_BAD_REQUEST);
}
}
}