Refractoring DatabaseConnection layer

Im Entwickler-Forum können Implementierungsdetails sowie Alternativen der Umsetzung diskutiert werden. // Here, developers can discuss implementation details of features of their projects.
Antworten
dingsda
Beiträge: 49
Registriert: 03.02.2014, 04:00:36

Refractoring DatabaseConnection layer

Beitrag von dingsda » 08.04.2014, 23:57:55

Ich hoffe es ist ok, dass ich hier ein Thema dazu starte. im Forum find ichs schöner zu schreiben als im Bugtracker. Wollte hier mal meine ersten Ergenisse zum thema 0000160: Refactoring database connection layer zur diskussion vorzeigen.

große Änderungen:
  • der executeTextStatement() kann als zusätzlichen Parameter ein array mit den Parametern zum binden übergeben werden. man kann bei executeTextStatement und executeStatement zusätzlich noch angeben, ob dazu prepared Statements benutz werden sollen oder wie bisher bei executeStatement einfach nur ersetzen. das soll auch über einen schalter in der connections.ini gemacht werden können (letzteres hab ich noch nicht eingebaut). außerdem kann man auch die art der platzhalter bestimmen (soll ebenfalls noch über die ini festlegbar sein).
    • Problem bei executeTextStatement ist, dass die reihenfolge der übergebenen parameter sich nun geändert hat. um es ähnlich wie executeStatement zu halten wird das array mit den zu ersetzenden parametern vor dem $logStatement übergeben

      Code: Alles auswählen

      // vorher
      executeTextStatement($statement,$logStatement);
      //jetzt
      executeTextStatement($statement,$params,$logStatement);
       
    • vorteil ist, dass damit die methoden executeTextBindStatement und executeBindStatemt unnötig geworden sind und man über einen einfachen schalter auch seine ganze application von prepared-Statements zu pseudo-prepared-Statements umschalten kann. oder einzellne komponenten. so könnte man den gorm umbauen, dass er prepared Statements nutzt und wer das nicht will müsste einfach nur beim gorm dann ne einstellung wie 'usePreparedStatements=false' setzen oder so.
  • es gibt nun noch die Methoden prepareTextStatement und prepareStatement, die analog zu den execute*-methode entweder ein statement aus einer datei laden und vorbereiten oder ein als text übergebenes Statement vorbereiten mittels prepare.
    • kleineres Problem ist auch hier ein konflikt zu vorher. prepareStatement gab es schon beim pdoHandler aber es bereitet ein TextStatement vor und lädt keines aus einer datei. um es ähnlich wie die execute* methoden zu halten hab ich das daher umbenannt.
    • auch hier kann man übrigens die platzhalter wählen
    • allerdings kann man hier nicht zwischen pseudo-prepare und echtem prepare wählen. sollte man meiner meinung nach auch nicht :D
  • allgemein kurz zu den platzhaltern. nutzen kann man ?, [parameter] und :parameter. letzteres kennt man von PDO welches auch der grund war, warum ich die platzhalter-wahl eingebaut hab. ich dachte dann könnte man beim pdo-händler gänzlich auf die platzhalter-ersetzung verzichten, weil pdo das ja schon macht. allerdings hab ich festgestellt, dass pdo keine doppelten platzhalter zulässt, was ich blöd finde. daher werden auch beim pdo-händler die platzhalter erstmal in ? ersetzt.
  • wie man sieht hab ich die handler aufgeteilt. es gibt die interfaces DatabaseConnection, StatementHandler und ResultHandler. zum einen find ich das übersichtlicher beim arbeiten damit. zum anderen war es sonst schwieriger das ganze zu bauen. ich hab weitestgehend versucht die alten methoden aber drin zu behalten und nur mit deprecated zu markieren, sodass man nicht sofort seinen ganzen code umschreiben muss. so sind z.b. für fetchData beide folgenden codes möglich

    Code: Alles auswählen

    // alte vorgehensweise
    $result=$driver->executeTextStatement('select ...');
    $data=$driver->fetchData($result);
    // neue vorgehensweise
    $result=$driver->executeTextStatement('select ...');
    $data=$result->fetchData();
     
auch beim mysqliHandler kann man nun die prepared Statements genau so nutzen wie bei PDO:

Code: Alles auswählen

$prepare = $driver->prepareTextStatemt('select * from ent_user where UserID=:id and Username=:name');

// variablen binden, dann execute
$prepare -> bindParam('id',$id)
         -> bindParam('name',$name);
$id=3;
$name='dingsda';
$result=$prepare->execute();

// werte binden, dann execute
$prepare -> bindValue('id',3)
         -> bindValue('name','dingsda');
$result=$prepare->execute();

// werte als array übergeben im execute
$array=array('name'=>'dingsda','id'=>3);
$prepare -> execute($array);
 

Code: Alles auswählen

$prepare = $driver->prepareTextStatemt('select * from ent_user where UserID=? and Username=?');
$result=$prepare -> execute(array('dingsda',3));
$data=$result=fetchAll();
 
Wer zeit und lust hat kann ja mal reinschnuppern in den code und mir sagen, ob ich völligen quatsch zusammengeschustert habe :mrgreen:
änderungsvorschläge sind gerne gesehen. ist auch wie gesagt nur ein erster entwurf und noch einiges zu tun.

lg, dingsda
Dateianhänge
database.zip
(15.96 KiB) 75-mal heruntergeladen

Benutzeravatar
dr.e.
Administrator
Beiträge: 4555
Registriert: 04.11.2007, 16:13:53

Re: Refractoring DatabaseConnection layer

Beitrag von dr.e. » 09.04.2014, 13:09:56

Hallo dingsda,

vielen Dank für deine Arbeit. Ich schaue mir die Änderungen an sobald ich die GIT-Migration abgeschlossen habe und wieder arbeitsfähig bin.
Viele Grüße,
Christian

dingsda
Beiträge: 49
Registriert: 03.02.2014, 04:00:36

Re: Refractoring DatabaseConnection layer

Beitrag von dingsda » 09.04.2014, 15:25:20

jap. lass dir ruhig zeit. ich komm die nächsten tage wahrscheinlich sowieso nicht dazu richtig dran weiter zu arbeiten und hab es deshalb gestern abend noch hier hochgeladen, damit schonmal bischen input kommt, wenn ich mich irgendwo in ne ganz falsche richtung bewege.

Benutzeravatar
dr.e.
Administrator
Beiträge: 4555
Registriert: 04.11.2007, 16:13:53

Re: Refractoring DatabaseConnection layer

Beitrag von dr.e. » 04.05.2014, 22:00:18

Hallo dingsda,

habe lokal angefangen deine Änderungen auf den aktuellen master-Branch zu portieren. Ergebnisse publiziere ich auf GitHub sobald ich fertig bin.
Viele Grüße,
Christian

dingsda
Beiträge: 49
Registriert: 03.02.2014, 04:00:36

Re: Refractoring DatabaseConnection layer

Beitrag von dingsda » 04.05.2014, 22:10:14

das war eigentlich nur als erster versuch gedacht, um rückmeldung zu bekommen, ob ich in die richtige richtung unterwegs bin :lol:

warte wenn es geht noch ein bischen mit dem portieren. hab mir das ganze nochmal angeschaut und bin grad dabei es nochmal zu ändern.

edit: werde dann auch direkt auf github den pull-request machen, jetzt wo ich weiß wie leicht das funktioniert :)

Benutzeravatar
dr.e.
Administrator
Beiträge: 4555
Registriert: 04.11.2007, 16:13:53

Re: Refractoring DatabaseConnection layer

Beitrag von dr.e. » 04.05.2014, 22:11:35

Zu spät, bin schon 90% fertig! ;) An sich aber auch nicht tragisch, denn ich hatte schon verstanden, dass das ein erster Wurf war und daher daher ich habe ich auch einen Feature-Branch erstellt.
Viele Grüße,
Christian

dingsda
Beiträge: 49
Registriert: 03.02.2014, 04:00:36

Re: Refractoring DatabaseConnection layer

Beitrag von dingsda » 04.05.2014, 22:15:30

ok. dann werd ich mir den feature-branch nochmal holen sobald der da ist und die änderungen dadrauf nochmal machen.

dingsda
Beiträge: 49
Registriert: 03.02.2014, 04:00:36

Re: Refractoring DatabaseConnection layer

Beitrag von dingsda » 04.05.2014, 22:50:56

meine änderungen betreffen vor allem das erkennen der platzhalter.

so wie es jetzt ist werden die placeholder immer gefunden. so würde ein query wie

Code: Alles auswählen

select * from `tabellen:name` where `irgendwas` = 'bla:blub' and `etwas`=:platzhalter;
zu fehlern führen, weil neben :platzhalter auch :name und :blub erkannt werden.

außerdem wird es nach meiner änderung nicht mehr nötig sein irgendwo anzugeben, welche art von platzhalter man nutzt.

Benutzeravatar
dr.e.
Administrator
Beiträge: 4555
Registriert: 04.11.2007, 16:13:53

Re: Refractoring DatabaseConnection layer

Beitrag von dr.e. » 04.05.2014, 23:03:24

Schau mal unter https://github.com/AdventurePHP/code/tr ... efactoring, dort habe ich die Änderungen eingebaut.
Viele Grüße,
Christian

Antworten

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast