Prosím o otestování nette/database 3.2
- David Grudl
- Nette Core | 8218
Prosím o otestování Database 3.2.0 RC
composer require nette/database:^3.2.0-RC2
Minimální vyžadovaná verze PHP je 8.1, pro kterou byl kód vylepšen a byly doplněny všechny typehinty. Změny jsou jen drobné:
- MySQL: nulové datum
0000-00-00
vrací jakonull
- MySQL: decimal bez desetinných míst vrací jako int místo float
- typ
time
vrací jako DateTime s datumem1. 1. 0001
místo aktuálního data
Tedy nasazení by mělo být zcela hladké.
- Hikikomori
- Člen | 1
Jedna maličkost, Selection::select()
má typehint
string|array $columns
které jsou předané do
SqlBuilder::addSelect()
kde je ale pouze
string $columns
.
Možná zapomenutý implode?
- Pavel Kravčík
- Člen | 1194
Datumy fungují ok, ale rozhodilo to sandál souboru, který volá transakce (při beginTransaction to hlásí neini PDO), příští týden zkusíme víc prověřit.
- Kacer_Bob
- Člen | 7
Bylo by možné doplnit v MySQL driveru také podporu pro typ boolean?
MariaDB ani MySQL nemají nativní typ BOOLEAN, ale místo toho používají
TINYINT(1).
https://mariadb.com/kb/en/boolean/
https://dev.mysql.com/…a-types.html
Je to analogický případ jako převod decimal na integer.
- David Grudl
- Nette Core | 8218
To by šlo. Snad to nezpůsobí nějaké nečekané nekompatibility. Vydal jsem to jako v3.2.0-RC2
- Marek Bartoš
- Nette Blogger | 1260
int lze předat do float, ale int do bool ne
Bylo by fajn takové změny dělat pod feature flagem, protože každou
typovanou aplikaci se zapnutými strict types změna z 1/0 na true/false
rozbije.
- Pavel Kravčík
- Člen | 1194
Pavel Kravčík napsal(a):
Datumy fungují ok, ale rozhodilo to sandál souboru, který volá transakce (při beginTransaction to hlásí neini PDO), příští týden zkusíme víc prověřit.
Nevím proč, ale tohle přestalo fungovat. Příklad jsem zjednodušil, používáme ten callback na zápis entit v ORM například.
$array1 = [];
$array1['name'] = 'test1';
$array1['active'] = 1;
$array2 = [];
$array2['name'] = 'test2';
$array2['active'] = 1;
$array = [];
$array[] = $array1;
$array[] = $array2;
$this->database->getConnection()->transaction(function() use ($array)
{
foreach($array as $row)
{
$this->database->table('xxx')->insert($row);
}
});
- 3.1 funguje
- 3.2 →
Typed property Nette\Database\ResultSet::$pdoStatement must not be accessed before initialization
- Tomáš Vodička
- Člen | 28
V projektu mi po upgradování verze na 3.2.0
začal phpstan
hlásit chyby typu
Parameter $Database of method SomeClass::__construct() has invalid type Nette\Database\Explorer
Property SomeClass::$Database has unknown class Nette\Database\Explorer as its type
Call to method fetchAll() on an unknown class Nette\Database\ResultSet
Ve vendoru ty třídy jsou a kód po spuštění funguje.
Pokud phpstan spustím na verzi 3.1.9
, tak proběhne bez
chyby – vůbec mě nenapadá, čím by to mohlo být
- Marek Bartoš
- Nette Blogger | 1260
@TomášVodička To se děje, pokud máš v PHPStanu nastavenou nízkou verzi PHP. Hlásí pak neexistující třídy, i když jen nejsou kompatibilní s aktuální PHP verzí
- Tomáš Vodička
- Člen | 28
Super, se správně nastavenou verzí už to funguje – díky, to by mě asi jen tak nenapadlo.
- h4kuna
- Backer | 740
Ahoj, zkusil jsem větev v3.2.x-dev 73b0cc7, abych potvrdil issue a narazil
jsem na to, že třídy s autowired: off
jsou pomocí search také
nalezeny. Viz tento komit.
Nějak tomu nerozumí, co bylo motivací? Celkem toho hojně využívám a
přišlo mi logické, že pokud si registruju třídu nastavím ji autowired:
off, tak ji Search nenajde. Takto mi to vyhazuje výjimky: Multiple
services of type Garage\Model\Blinds\Blind\Pauseable found: protože
mám několik implementací s tímto interface
Garage\Model\Blinds\Blind\Pauseable. Všechny implementace tedy
musí dát do ignorace pro Search.
Ale pak se nemohu dostat přes stejnou hlášku s tím, že tentokrát mám službu pro Presenter.
Service of type Garage\Presenters\V1Module\GaragePresenter: Service of type Garage\Model\PiGpio\Pin required by $garageButton in GaragePresenter::__construct() not found.
services:
- Garage\Presenters\V1Module\GaragePresenter(@garagePin)
garagePin:
factory: @pin.write.factory::create(Garage\Model\Relay1::PIN_GARAGE) # vytváří Garage\Model\PiGpio\Pin
autowired: no
final class GaragePresenter extends BasePresenter
{
public function __construct(private readonly Pin $garageButton)
{
parent::__construct();
}
}
Ve stable 3.2 toto funguje.
Editoval h4kuna (20. 2. 8:09)
- David Grudl
- Nette Core | 8218
@h4kuna čtu to asi po desáté, ale stále nechápu. Zkus ten příklad prosím zjednodušit.
- h4kuna
- Backer | 740
Dobře,
zjednodušil jsem ten první případ co jsem popisoval, definuji si několik implementací jednoho rozhraní. Pak mám accessor, který má logiku a vybírá mi instanci implementace. A tu konkrétní instanci pak přijímá nějaká třída.
ve verzi 3.2.0, toto funguje dostanu v App\Foo\MyClass
objekt
App\Foo\FooA
.
ve verzi v3.2.x-dev 73b0cc7 Service of type App\Foo\MyClass: Multiple services of type App\Foo\BarInterface found: 01, 010, 011 (required by $a in MyClass::__construct())
services:
a:
factory: App\Foo\FooA
autowired: false
b:
factory: App\Foo\FooB
autowired: false
- App\Foo\FooAccessor()::get('a')
- App\Foo\MyClass
namespace App\Foo;
interface BarInterface
{
function run(): void;
}
namespace App\Foo;
final class FooA implements BarInterface
{
function run(): void
{
}
}
namespace App\Foo;
final class FooB implements BarInterface
{
function run(): void
{
}
}
namespace App\Foo;
final class MyClass
{
public function __construct(private BarInterface $a)
{
}
}
namespace App\Foo;
use Nette\DI\Container;
class FooAccessor
{
public function __construct(private Container $container)
{
}
public function get(string $name): BarInterface
{
// if (condition)
return $this->container->createService($name);
}
}
Úplně „easy“ :D
EDIT:
Aby mi to fungovalo ve 3.2-dev musím do neonu přidat
search:
- in: %appDir%
exclude:
classes:
- App\Foo\FooB
- App\Foo\FooA
- zapomněl jsem Accessor třídu
@DavidGrudl je to takto už srozumitelné a v pořádku?
Editoval h4kuna (23. 2. 12:25)
- kminekmatej
- Generous Backer | 38
Hlásím že ve verzi 3.2.3 se mi opět objevila asi již opravovaná chyba:
Typed property Nette\Database\ResultSet::$pdoStatement must not be accessed before initialization
Verze 3.1.9 to nedělá (protože types)
Stack trace je následovný:
$explorer->beginTransaction();
zavolá
->query('::beginTransaction')
Query který začíná na :: v ResultSet konstruktoru neinituje
private readonly ?\PDOStatement $pdoStatement
.
Nicméně v ConnectionPanel::logQuery()
se volá
$result->getRowCount()
.
Tam to spadne na:
return $this->pdoStatement ? $this->pdoStatement->rowCount() : null;
Můžu zítra připravit PR s opravou na
return isset($this->pdoStatement) ? $this->pdoStatement->rowCount() : null;
(Nevím jestli obdobně neupravit ještě getColumnCount()
)
Editoval kminekmatej (20. 8. 17:16)
- kminekmatej
- Generous Backer | 38
Aha, koukám že v master branchi je to už předělané z PDOStatement na Result. Tak to neřešim, počkám si na release. To půjde do 4.0 ?