https://github.com/itype7/boltdb/tree/dev
Pod powyższym linkiem znajduje się kod inicjacyjny dla biblioteki do obsługi bazy danych, którą tworzę. Po co? Żeby poćwiczyć niektóre rzeczy.
Na razie działa tylko budowa prostego SELECTa poprzez klasy Select i SelectAbstract z odpowiednich namespaców.
Chciałbym, żeby ktoś rzucił na to okiem (głównie namespace
Hehe... Dobrze że dałeś tego readma...
Powiem Ci że jakieś to przekombinowane strasznie Za chusteczki nie wiedziałbym jak tego używać. Mało intuicyjne.
Zerknij nawet w Laravela jak to mają ogarnięte: https://laravel.com/docs/5.4/queries#selects
Widzę tam singletony dla tabel. Zastanawiałem się właśnie nad takim rozwiązaniem, dodając jakąś konfigurację albo automatyczne wykrywanie struktury (kierowałbym się ku konfiguracji, bo automatyka obciążałaby pewnie mocno skrypt). Ale póki co na razie chcę ogarnąć Query Buildera dla co najmniej podstawowych zapytań. Joiny z tego, co widzę, przyjmują mniejszą ilość parametrów, niż u mnie - tu wystarczy nazwa tabeli i warunek, a - jak się domyślam - lista pól uzupełniana jest z automatu lub przez dodanie listy. Ja tego chciałem uniknąć - wymusiłem listę pól (ale można użyć klasy \BoltDb\Query\Expression, by przemycić wildcarda '*'). Zrobiłem tak, ponieważ nie lubię systemów, gdzie jest zbyt dużo automatyki (stąd też podział na fromTable i fromQuery - także join*). Dodatkowo, listy pól przypisane są głównie do tabel lub podzapytań z nimi powiązanych (ale można użyć pól, które nie są z niczym powiązane, po użyciu Select::selectFields()).
Całe skomplikowanie dotyczy chyba właśnie podziału na klasy abstrakcyjne i interfejsy dla obiektów dotyczących pobrania danych - FromTable, FromQuery, JoinTable, JoinQuery - i przyszłych...
/** * @param Connection $connection * @dataProvider providerConnection */ public function testConnection(Connection $connection) { $this->assertInstanceOf(Connection::class, $connection); }
Czym to się ma różnic od zend db bo nawet nazwy niektórych klas są identyczne
Zdecydowanie popracuj najpierw nad interfejsem, a dopiero potem bierz się za implementację. Dla Ciebie pewnie jest to intuicyjne, ale ja jestem przerażony tym co widzę, a to dopiero zwykły select
Jak juz zauwazyl markuz to twoje testy so cudne Przekazujesz true i sprawdzasz czy to true. Ciezko o sytuacjie, gdy to nie przejdzie testu
Co do klasy: a po co jest to cale Connection? Z przykladu w readme wynika ze do niczego, bo
Najpierw dla connection ustawiam obiekt PDO, ktory sam tworze
$pdo = new PDO('mysql:dbname=my_database;host=127.0.0.1;port=3306', 'username', 'password');
$connection->connect($pdo);
a potem by wykonac query to musze to $pdo, ktore sam ustawilem, pobrac i dopiero moge wykonac query
$result = $connection->getConnection()->query($select->toString());
Czemu poprostu nie moge zrobic
$result = $pdo->query($select->toString());
i ominac to cale $connection?
Na chwilę obecną wrzucenie $select->toString() prosto do PDO nie będzie problemem. W sumie jeśli będę kontynuował rozwój tego skryptu to wątpię, żeby w ogóle nim było. Ale obszywanie w klasę Connection miało na celu łatwiejsze zarządzanie później dodanymi klasami (których oczywiście jeszcze nie ma). Na razie mamy tylko BoltDb\Engine\MySql, więc nie ma problemu, ale co, gdy dojdzie np. PostgreSQL? Connection i jego klasy podrzędne miałyby wtedy określić, z jakich zapytań mogę skorzystać, jakich konstrukcji użyć, itp.
Na razie jednak zastanawiam się nad sensem rozwijania tego skryptu - parę osób wspomniało, że jest zbyt skomplikowany.
Cześć,
Z góry powiem, że nie patrzyłem w kod i moje rady są na podstawie README.md.
1. Chłopaki mają racje popracuj nad api. Może nawet zacznij od niego.
$connection = new \BoltDb\Connection(); $pdo = new PDO('mysql:dbname=my_database;host=127.0.0.1;port=3306', 'username', 'password'); $connection->connect($pdo); $select->fromTable(['alias' => 'name_field', new \BoltDb\Query\Expression('tbl.*')], 'data', 'tbl', 'my_schema');
$select->joinTable(['other_alias' => 'second_field'], 'sec_table', 'stbl.id = tbl.foreign_id', \BoltDb\Engine\Query\Block\http://www.php.net/join\JoinBlock::TYPE_LEFT, 'stbl', 'my_schema');
$result = $connection->getConnection()->query($select->toString());
$result = $select->getResult() $result->cached() ->onSucces(function($rows){ }) ->onError(function(){ http://www.php.net/echo "Błąd"; }) $resutl->getOrThrowException(new Exception())
Metody dot. FROM i JOIN mają obowiązkowo 2 parametry - reszta to opcja.
Fluent wykluczony ze względu na to, że metody dodające bloki FROM i JOIN mają w przyszłości zwracać konfigurowalne bloki.
A jak inaczej to rozwiązać? Publiczne settery na zwracanych obiektach? Według mnie to jeszcze gorsze niż 6-7 parametrów do fabryki.
var userTable = Table::of("user") ->schema("schema") ->primaryKey("id") $select->jouinTable(Table $userTable, "alias") ->joinTable($table, "userId")
$select->leftJoinTable("schema.userTable","alias") ->on("alias.id", "someTable.userId") ->leftJoinTable("schema.games","alias") >on("alias.id", "someTable.gameId");
Najlepiej byłoby się skłonić ku opcji pierwszej, ale nadal trzeba dodać parametry takie, jak lista pól. W moim założeniu powinno to być pogrupowane, dlatego u mnie jest to parametr metody fromTable/joinTable. W sumie mógłbym operować na obiektach klas zwracanych przez te metody...
Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)