Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Zwei Records vergleichen ?


Terra - Di 18.12.12 22:43
Titel: Zwei Records vergleichen ?
Servuz,

Arbeite für ein neues Projekt von mir erstmals mit Typen und sonstigen Krimskrams, wo ich mich erst richtig einarbeiten muss. Für eine Auto-Update Routine habe ich mir bereits einige Komponenten angeschaut aber keine gefunden, die für mein Projekt das Aufweist, was ich suche. Darum hab ich mich dranngemacht eine eigene Update Routine zu schreiben.

Im Grunde soll es was relativ Simples sein, was aber meinen Anforderungen entsprechen würde.
Es gibt eine XML Datei im Internet, die mit seinem Inhalt auf die einzelnen Dateien hinweist (ink. Versionsnummer)
Eine 2. XML befindet sich im Programmordner.
Beide XML Dateien werden eingelesen und in das TWebUpdateFile (Array) geschrieben. Klappt bis hierhin alles super.

Folgender Code sollte selbsterklärend sein:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
type
  TUpdateFile = record
    Filename  : string;
    Version   : double;
  end;
TWebUpdateFile = Array of TUpdateFile;

type
  TStartForm = class(TForm)
-
-
-
  procedure StartUpdate(NewUpdates, OldUpdates: TWebUpdateFile);
end;

var
  UpdateFile, UpdateFileOld : TWebUpdateFile;


procedure TStartForm.StartUpdate(NewUpdates, OldUpdates: TWebUpdateFile);
begin
  // Hier soll der vergleich rein.
end;


Jetzt stehe ich aber vor dem Problem, das in der Procedure "StartUpdate" beide Typen verglichen werden sollen.
Und zwar, so:

1. - Ist Filename in Neu auch in Alt -> Vergleiche Version <else> Lade diese File herunter.
2. - Ist Version von gleichen Filename ungleich -> Lade neue File herunter.

Könnt ihr mir ein Ansatz geben, wie man das am elegantesten Lösen kann?
Zuzüglich muss ja auch darauf geachtet werden, das die Liste erst weiter abgearbeitet werden darf, wenn die Update-Datei erfolgreich heruntergeladen wurde.

LG,
Terra


bummi - Di 18.12.12 23:05


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
Function NeedsUpdate(New:TUpdateFile;oldArray:TWebUpdateFile):Boolean;
var
 i:Integer;
begin
  result := true;
  for I := Low(oldArray) to High(oldArray) do
    begin
        if (oldArray[i].Filename=New.Filename) and (oldArray[i].Version>=New.Version) then
          begin
             Result := false;
             break;
          end;
    end;
end;

procedure TStartForm.StartUpdate(NewUpdates, OldUpdates: TWebUpdateFile);
var
 i:Integer;
begin
   for I := Low(NewUpdates) to High(NewUpdates) do
     if NeedsUpdate(NewUpdates[i],OldUpdates) then
        begin
           //  >> Deine Updateroutine
        end;
end;


Terra - Di 18.12.12 23:53

Das passt ja, wie *popo* auf Eimer !

Vielen, vielen Dank dafür.
Zwar hatte ich kleine Anfangsschwierigkeiten, da ich unwissentlich die XML in die Records falsch geschrieben habe aber nun klappt das. Jetzt kommt aber noch der große Brocken aber das werde ich auch hinbekommen. Damit wäre dann der 1. Teil des Programms fertig.

Vielen Dank noch mal.
Man lernt ja nie aus.

Warum fällt es euch eigentlich immer so leicht solche Sachen aus den Ärmel zu schütteln? Würde ich auch gerne können.

LG Terra


jaenicke - Mi 19.12.12 09:50

// EDIT:
Oder gleich so:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
type
  TUpdateFile = record
    Filename  : string;
    Version   : double;
    class operator GreaterThanOrEqual(const Data1, Data2: TUpdateFile): Boolean;
  end;

  TWebUpdateFile = record
    Value: array of TUpdateFile;
    class operator LessThan(const Data1: TUpdateFile; const Data2: TWebUpdateFile): Boolean;
  end;

// ...

procedure TStartForm.StartUpdate(NewUpdates, OldUpdates: TWebUpdateFile);
var
  Current: TUpdateFile;
begin
  for Current in NewUpdates.Value do
    if Current < OldUpdates then
    begin
      //  >> Deine Updateroutine
    end;
end;

class operator TUpdateFile.GreaterThanOrEqual(const Data1, Data2: TUpdateFile): Boolean;
begin
  Result := (Data1.Filename = Data2.Filename) and (Data1.Version >= Data2.Version);
end;

class operator TWebUpdateFile.LessThan(const Data1: TUpdateFile; const Data2: TWebUpdateFile): Boolean;
var
  Current: TUpdateFile;
begin
  Result := True;
  for Current in Data2.Value do
    if Current >= Data1 then
      Exit(False);
end;


Terra - Mi 19.12.12 13:29

Boah... :shock:

Das übersteigt z.Z. mein Horizont.
Ich behalte mir aber den Letzten Post mal im Hinterkopf, da es echt Edel und schön mit den Class und so aussieht. :D

Welchen Vorteil ergibt sich aus deinem Script im Gegensatz zu dem von Bummi ?

Danke für eure Mühen.

Terra


jaenicke - Mi 19.12.12 15:07

user profile iconTerra hat folgendes geschrieben Zum zitierten Posting springen:
Welchen Vorteil ergibt sich aus deinem Script im Gegensatz zu dem von Bummi ?
Dass die Vergleichslogik in den Records selbst gekapselt wird. Da kann man natürlich auch noch mehr Operatoren implementieren und die Records natürlich der Übersicht halber in eine andere Unit auslagern.
Bei der Verwendung musst du dann die Logik nicht mehr kennen, sondern schaust einfach, ob die neue Version größer als die alte ist.