DataSet Update Status

Für Themen zu Datenbanken und Zugriff auf diese. Auch für Datenbankkomponenten.
Benutzeravatar
theo
Beiträge: 10872
Registriert: Mo 11. Sep 2006, 19:01

DataSet Update Status

Beitrag von theo »

Ich hab mal mit TBufDataSet gespielt.

Ich kann so eine Tabelle erstellen:

Code: Alles auswählen

procedure TForm1.FormCreate(Sender:TObject);
begin
  bd:=TBufDataset.Create(self);
  DataSource1.DataSet :=bd;
  bd.Close;
  bd.FieldDefs.Clear;
  bd.FieldDefs.Add('id',ftInteger);
  bd.FieldDefs.Add('text',ftString,20);
  bd.FieldDefs.Add('adate',ftDateTime);
  bd.CreateDataSet;
  bd.Open;
  bd.AppendRecord([1,'tester',now]);
  bd.AppendRecord([2,'theo',now]);
end;
Das funktioniert soweit.

Wenn ich nun aber das mache:

Code: Alles auswählen

bd.First;
  writeln(bd.UpdateStatus);
So wird mir angezeigt, dass der Datensatz den Status "usInserted" hat, was ja irgendwie auch stimmt.
Gibt es eine Möglichkeit, den Status zurückzusetzen, damit ich von nachfolgenden Veränderungen z.B. im Grid Wind bekomme?
Ich hab schon was mit bd.CancelUpdates probiert, aber das scheint's wohl nicht zu sein.

Benutzeravatar
theo
Beiträge: 10872
Registriert: Mo 11. Sep 2006, 19:01

Re: DataSet Update Status

Beitrag von theo »

Ich glaube ich hab's begriffen.

Eigentlich muss man ein ApplyUpdates machen.
Da TBufDataset das aber nicht implementiert hat, gab es bei dem Versuch einen Error.
Wenn ich das folgende auskommentiere, dann setzt es die Werte zurück.

Code: Alles auswählen

procedure TCustomBufDataset.ApplyRecUpdate(UpdateKind : TUpdateKind);
begin
//  raise EDatabaseError.Create(SApplyRecNotSupported);
end;
Nun kann ich ApplyRecUpdate wahrsch. überschreiben und den tatsächlichen Abgleich mit MySQL über PHP darin machen.
Wenn's jemand besser weiss: immer her damit! ;-)

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6780
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: DataSet Update Status

Beitrag von af0815 »

Dein 'Spiel' interessiert mich.

Willst du später von Connection oder Dataset ableiten ?! Wenn eine SQL-fäheige DB dahintersteht, so wäre doch der TSQLConnection der Ableitungspunkt, oder liehge ich da komlett falsch ?
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
theo
Beiträge: 10872
Registriert: Mo 11. Sep 2006, 19:01

Re: DataSet Update Status

Beitrag von theo »

af0815 hat geschrieben:Dein 'Spiel' interessiert mich.
Kannst gerne mitspielen. Bin immer noch in der Experimentierphase.
Im Moment versuche ich, dem XMLDatapacketReader die DatenTypen zu verklickern, die er von PHP erhält.
Das sind dann nicht unbedingt die MySQL Namen wie "bigint" sondern mysql_field_type->"int" / mysql_field_len ->20
af0815 hat geschrieben: Willst du später von Connection oder Dataset ableiten ?! Wenn eine SQL-fäheige DB dahintersteht, so wäre doch der TSQLConnection der Ableitungspunkt, oder liehge ich da komlett falsch ?
Nur auf TBufDataSet. Ich habe mir das trotz null Ahnung mal angeschaut. Das Problem ist, dass die TMySQLConnection die Records einzeln abholt. Das ist über PHP nicht wirklich möglich, da man die Connection nicht halten kann. Auch Transactions und sowas klappt prinzpiell nicht.
Deshalb muss das Query-Result in einem Rutsch rüber via XML.

Dies ist eine Beispiel Abfrage die ich mit PHP generiere. Ich bin jetzt wie gesagt dabei, in XMLDatapacketReader die Datentypen für Lazarus zu übersetzen. Im Grunde ist das unten aber das Format, welches XMLDatapacketReader lesen kann :

Code: Alles auswählen

<?xml version="1.0"?>
<DATAPACKET Version="2.0">
  <METADATA>
    <FIELDS>
      <FIELD fieldname="c_id" attrname="c_id" fieldtype="int" width="20"/>
      <FIELD fieldname="c_dep_id" attrname="c_dep_id" fieldtype="int" width="6"/>
      <FIELD fieldname="c_name" attrname="c_name" fieldtype="string" width="10"/>
      <FIELD fieldname="c_seal" attrname="c_seal" fieldtype="int" width="1"/>
      <FIELD fieldname="c_date_came" attrname="c_date_came" fieldtype="datetime" width="19"/>
      <FIELD fieldname="c_date_out" attrname="c_date_out" fieldtype="datetime" width="19"/>
      <FIELD fieldname="c_weight" attrname="c_weight" fieldtype="real" width="12"/>
      <FIELD fieldname="c_width" attrname="c_width" fieldtype="int" width="11"/>
      <FIELD fieldname="c_height" attrname="c_height" fieldtype="int" width="11"/>
      <FIELD fieldname="c_cost" attrname="c_cost" fieldtype="real" width="12"/>
      <FIELD fieldname="c_attributes" attrname="c_attributes" fieldtype="blob" width="65535"/>
    </FIELDS>
  </METADATA>
  <ROWDATA>
    <ROW c_id="1" c_dep_id="2" c_name="grainerthe" c_seal="1" c_date_came="2002-12-20 02:00:00" c_date_out="2002-12-20 02:00:00" c_weight="5000" c_width="" c_height="" c_cost="1769.4301" c_attributes=""/>
    <ROW c_id="2" c_dep_id="1" c_name="Paper" c_seal="2" c_date_came="2002-12-19 14:00:00" c_date_out="2002-12-23 00:00:00" c_weight="1000" c_width="10" c_height="10" c_cost="986.4700" c_attributes="#14#&#x91;®àâ2"/>
    <ROW c_id="3" c_dep_id="1" c_name="Wool" c_seal="0" c_date_came="2002-12-20 18:00:00" c_date_out="" c_weight="400" c_width="7" c_height="4" c_cost="643.1100" c_attributes=""/>
    <ROW c_id="4" c_dep_id="2" c_name="Suagra" c_seal="1" c_date_came="2002-12-21 10:20:00" c_date_out="2002-12-26 00:00:00" c_weight="2034" c_width="" c_height="" c_cost="1964.8700" c_attributes=""/>
  </ROWDATA>
</DATAPACKET>

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6780
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: DataSet Update Status

Beitrag von af0815 »

Hilft dir das: TConnectionName.MySQLDataType aus .....fpcsrc\packages\fcl-db\src\sqldb\mysql\mysqlconn.inc liegt in den fpcsourcen.

Code: Alles auswählen

function TConnectionName.MySQLDataType(AType: enum_field_types; ASize, ADecimals: Integer;
   var NewType: TFieldType; var NewSize: Integer): Boolean;
 
.....
 
    FIELD_TYPE_LONG, FIELD_TYPE_INT24:
      begin
      NewType := ftInteger;
      NewSize := 0;
      end;
{$ifdef mysql50}
    FIELD_TYPE_NEWDECIMAL,
{$endif}
    FIELD_TYPE_DECIMAL: if ADecimals < 5 then
                          begin
                          NewType := ftBCD;
                          NewSize := ADecimals;
                          end
                        else
                          begin
                          NewType := ftFloat;
                          NewSize := 0;
                          end;
    FIELD_TYPE_FLOAT, FIELD_TYPE_DOUBLE:
      begin
      NewType := ftFloat;
      NewSize := 0;
      end;
.......
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
theo
Beiträge: 10872
Registriert: Mo 11. Sep 2006, 19:01

Re: DataSet Update Status

Beitrag von theo »

af0815 hat geschrieben:Hilft dir das: TConnectionName.MySQLDataType aus .....fpcsrc\packages\fcl-db\src\sqldb\mysql\mysqlconn.inc liegt in den fpcsourcen.
Mal schauen, ich muss erst mal die Strings die PHP liefert in was sinnvolles umwandeln.
Merci.

Wenn du was machen möchtest: Man müsste die UPDATE INSERT DELETE Queries generieren.
Das könnte man ausgehend von ApplyRecUpdate machen (siehe unten).
TXMLMySQLDataSet ist eine Ableitung von TCustomBufDataset. Ausser dem TestCode da, kann die noch nichts.
In UpdateKind siehst du, was zu tun ist. Anhand von Fields.DataType findest du raus du wie der Value für SQL darzustellen ist.
Man kann natürlich alles updaten, noch besser wäre, man würde nur die geänderten Felder updaten.
Ich weiss aber nicht wirklich, wie man das rausfinden kann. Es gibt den OldValue, der wohl darauf hindeutet, das was geändert wurde.
Wenn der aber leer ist, kriege ich immer SIGSEGV, auch mit VarIsNull oder VarIsEmpty. Das wäre auch noch rauszutüfteln.

Code: Alles auswählen

procedure TXMLMySQLDataSet.ApplyRecUpdate(UpdateKind: TUpdateKind);
begin
  writeln(UpdateStatus);
  if UpdateStatus<>usUnmodified then
  begin
   writeln(Fields[0].AsString);
   writeln(Fields[1].AsString);
   writeln(Fields[2].AsString);
  end;
//  if not variants.VarIsNull(Fields[1].OldValue) then ;
end;
Nur falls du Lust hast.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6780
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: DataSet Update Status

Beitrag von af0815 »

theo hat geschrieben:Nur falls du Lust hast.
Werd mal hineinsehen und das mit den SIGSEGV untersuchen.

Hast du einen Tip für mich, wie ich am besten diesen FCL Teil mit debugsymbolen erzeuge ? Ich will ja nicht den ganzen fpc mit debugsymbolen bauen.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
theo
Beiträge: 10872
Registriert: Mo 11. Sep 2006, 19:01

Re: DataSet Update Status

Beitrag von theo »

af0815 hat geschrieben:
theo hat geschrieben:Nur falls du Lust hast.
Werd mal hineinsehen und das mit den SIGSEGV untersuchen.

Hast du einen Tip für mich, wie ich am besten diesen FCL Teil mit debugsymbolen erzeuge ? Ich will ja nicht den ganzen fpc mit debugsymbolen bauen.
Wenn du die DB Units meinst: Ich habe die einfach in mein Projektverzeichnis kopiert und leicht anders benannt.
xmldatapacketreader_t.pp
bufdataset_t.pas

Am besten gleich die neuen von SVN: http://svn.freepascal.org/cgi-bin/viewv ... ortby=date" onclick="window.open(this.href);return false;

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6780
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: DataSet Update Status

Beitrag von af0815 »

theo hat geschrieben: Wenn du die DB Units meinst: Ich habe die einfach in mein Projektverzeichnis kopiert und leicht anders benannt.
...........
Am besten gleich die neuen von SVN: http://svn.freepascal.org/cgi-bin/viewv ... ortby=date" onclick="window.open(this.href);return false;
Ich habe mir gestern einen aktuellen FPC aus dem SVN erstellt und dazu gleich Lazarus ebenfalls aus dem SVN. Werde mir also auch den Zweig aus der FCL rauslösen und mit Debugsymbolen neu erstellen.

Kannst du den PHP Teil auch posten ?
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
theo
Beiträge: 10872
Registriert: Mo 11. Sep 2006, 19:01

Re: DataSet Update Status

Beitrag von theo »

af0815 hat geschrieben: Kannst du den PHP Teil auch posten ?
Noch nicht, ich muss das anders machen.
Problem: mysql_field_type gibt nur die PHP Typen zurück. Da ist alles z.B. int, egal ob tinyint, smallint etc.
Die wirklichen MySQL Typen kriege ich mit "describe tablename" zurück.
Dazu muss ich aber eine extra query machen. Den Tabellenamen für jedes Feld (das Resultset kann ja auch aus versch. Tables zusammengesetzt sein) erhalte durch mysql_field_table. Ich muss das irgendwie zwischenspeichern, damit ich nicht für jede Feldbeschreibung ein "describe" ausführen muss.

Weiss eigentlich jemand zuverlässig, was mit den Feldlängen in MySQL wirklich gemeint ist?
z.B. bigint(20)
Ich nehme an, bei Strings ist es die Zeichenanzahl, also der benötige Speicher. Aber was ist es bei Integers?
Die Länge der Dezimalrepresentation als String? Brauchen wir das?

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6780
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: DataSet Update Status

Beitrag von af0815 »

theo hat geschrieben: Weiss eigentlich jemand zuverlässig, was mit den Feldlängen in MySQL wirklich gemeint ist?
z.B. bigint(20)
Ich nehme an, bei Strings ist es die Zeichenanzahl, also der benötige Speicher. Aber was ist es bei Integers?
Die Länge der Dezimalrepresentation als String? Brauchen wir das?
Muß mir das in der Doku noch ansehen - 11.2. Numerische Datentypen
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
theo
Beiträge: 10872
Registriert: Mo 11. Sep 2006, 19:01

Re: DataSet Update Status

Beitrag von theo »

Ja, da steht's.
Eine andere Erweiterung wird von MySQL zur optionalen Spezifizierung der Anzeigebreite eines Integer-Werts unterstützt. Die Angabe erfolgt auf das Schlüsselwort für den Datentyp folgend in Klammern (z. B. INT(4)). Diese optionale Angabe der Anzeigebreite wird verwendet, um die Anzeige von Werten, die eine geringere als die für die Spalte festgelegte Breite aufweisen, nach links mit Leerzeichen aufzufüllen.
Ob, und wie wir das brauchen können, ist mir allerdings noch nicht ganz klar.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6780
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: DataSet Update Status

Beitrag von af0815 »

theo hat geschrieben: Ich weiss aber nicht wirklich, wie man das rausfinden kann. Es gibt den OldValue, der wohl darauf hindeutet, das was geändert wurde.
Wenn der aber leer ist, kriege ich immer SIGSEGV, auch mit VarIsNull oder VarIsEmpty. Das wäre auch noch rauszutüfteln.
Der interene bufferzeiger ist #0 deshalb der SIGSEGV. Den genauen Mechanismus dahinter muß ich mir noch genauer heraussuchen. Vor allen wo bei der Initialisierung da eingegriffen werden muß/soll.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6780
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: DataSet Update Status

Beitrag von af0815 »

Ich glaube es muß nur einem Kinde des 'TDataPacketReader' dein XML-File nahegebracht werden, dann wäre einiges leichter.

Edit: Jetzt begreife ich, wieso 'xmldatapacketreader'. Ok, zurück an den Start.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
theo
Beiträge: 10872
Registriert: Mo 11. Sep 2006, 19:01

Re: DataSet Update Status

Beitrag von theo »

Ich hab dir mal die "Baustelle" hier hochgeladen: http://www.theo.ch/lazarus/xmlmysql.zip" onclick="window.open(this.href);return false;
Du brauchst noch Synapse zum kompilieren. Das hat jetzt auch ein *.lpk in trunk.

Es sollte jetzt prinzipiell möglich sein Queries auf dem PHP Script auszuführen.

Im PHP Script ganz oben musst du DB und USER/PASS hardcoden.

Wenn's nicht klappt musst du wahrsch. in XMLMySQLDatapacketReader.pas
die MySQLTypeStrings ergänzen eventuell auch in function MySQLDataType.

Es gibt noch viel zu tun. Upgedatet wird noch gar nichts. Auch Primary Keys, AutoInc etc. werden noch nicht gehandelt.
Du kannst aber INSERT UPDATE etc. Queries in den Editor eintippen. Das müsste klappen.
In der Demo wir aber der Grid erst nach nochmaligem SELECT upgedatet.

Du siehst dann schon, was noch nicht klappt.
Aber damit kannst du vielleicht mitarbeiten.

Viel Spass!

EDIT: Jetzt wird auch experimentell upgedatet. Nur String und Integer Typen und unter der Annahme, dass Feld1 der Primärschlüssel ist. Wie definiere ich Primarschlüssel im Dataset?

Antworten