[Erledigt] Objektlisten erstellen

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut

[Erledigt] Objektlisten erstellen

Beitragvon MacWomble » 13. Jan 2019, 13:10 [Erledigt] Objektlisten erstellen

Dank eurer Hilfe bin ich nun schon recht weit gekommen. Ich habe Klassen für einige meiner Tabellen erstell und diese getestet. So weit bin ich nun sehr zufrieden.
Die nächste Schritte, wo ich aus den Informationen im allwissenden Netz nichts wirklich passendes gefunden habe Liste der Objekte einer Klasse ('SELECT * FROM ArtikelGruppen') erstelle mit Create und Destroy (Ich kapiere das einfach nicht :oops: - oder ich finde nicht die richtige Anleitung dafür )

Da ich sicher nicht der Einzige bin, der sich am Anfang mit OOP schwer tut, halte ich das ganze etwas ausführlicher. Mit eurer Unterstützung entsteht dann eine Nachschlagewerk. :twisted:

Code: Alles auswählen
unit uartikelgruppe;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, LazLoggerBase, DBCtrls, dtm_basis;
 
type
 
  { TArtikelgruppe }
 
  TArtikelgruppe = class(TObject)
  private
    fIsChanged: boolean;
    fID: integer;
    fIDColor: integer;
    fArtikelgruppe: string;
  public
    constructor Create;
    destructor Destroy;
 
    procedure SetIDColor(const aValue: integer);
    procedure SetArtikelgruppe(const aValue: string);
 
    procedure Init;
    procedure ReadByID(ID: integer);
    procedure WriteData;
    procedure ReadData(Query: string);
  published
    // idartikelgruppe, artikelgruppe, fk_color
    property IsChanged: boolean read fIsChanged write fIsChanged default False;
    property ID: integer read fID write fID default -1;
    property IDColor: integer read fIDColor write SetIDcolor default 0;
    property Artikelgruppe: string read fArtikelgruppe write SetArtikelgruppe;
  end;
// ... und hier hänge ich erneut und benötige euer Wissen:
  TArtikelgruppenListe = class()  // Dachte das sollte TObjectlist sein, aber das geht nicht
    FArtikelgruppen: array of TArtikelgruppe;
  public
    constructor Create;
    destructor Destroy; override;
  end;
 
implementation
 
procedure TArtikelgruppe.SetIDColor(const aValue: integer);
begin
  if fIDColor = aValue then
    exit;
  fIDColor := aValue;
  IsChanged := True;
end;
 
procedure TArtikelgruppe.SetArtikelgruppe(const aValue: string);
begin
  if fArtikelgruppe = aValue then
    exit;
  fArtikelgruppe := aValue;
  IsChanged := True;
end;
 
 
constructor TArtikelgruppe.Create;
begin
  inherited Create;
  Init;
end;
 
procedure TArtikelgruppe.Init;
begin
  fID := -1;
  fIDColor := 0;
  fArtikelgruppe := '';
end;
 
procedure TArtikelgruppe.ReadByID(ID: integer);
begin
  ReadData('Select * from ArtikelGruppen where idartikelgruppe = ' + IntToStr(ID));
end;
 
procedure TArtikelgruppe.WriteData;
begin
  debugln('TArtikelgruppe.WriteData: ');
  if fIsChanged then
  begin
    fIsChanged := False;
    with dtmBasis.qrySQL do
    begin
      if fID < 0 then
      begin
        SQL.Clear;
        SQL.Add('Insert Into ArtikelGruppen');
        SQL.Add('(fk_color, artikelgruppe)');
        SQL.ADD('VALUES');
        SQL.ADD('(:fk_color, :artikelgruppe);');
        Prepare;
      end
      else
      begin  //Update
        DebugLn('  Datensatz ' + IntToStr(fid) + ' wird aktualisiert');
        SQL.Clear;
        SQL.ADD('UPDATE ArtikelGruppen SET');
        SQL.ADD('fk_color = :fk_color,');
        SQL.ADD('artikelgruppe = :artikelgruppe');
        SQL.ADD('WHERE idartikelgruppe = :idartikelgruppe;');
        Params.ParamByName('idartikelgruppe').AsInteger := fID;
      end;
      Params.ParamByName('fk_color').AsInteger := fIDColor;
      Params.ParamByName('artikelgruppe').AsString := fArtikelgruppe;
      try
        ExecSQL;
        DebugLn('  Gespeichert!');
        if fID = -1 then
        begin
          SQL.Text := 'SELECT * FROM view_lastid';
          Open;
          fID := FieldByName('LastID').AsInteger;
          debugLn('  Neue ID ist: ' + IntToStr(fID));
          Close;
        end;
      except
        On E: Exception do
          debugln(' ' + E.Message);
      end;
    end;
  end
  else
    DebugLn('  Nicht gespeichert: Datensatz aktuell');
end;
 
procedure TArtikelgruppe.ReadData(Query: string);
begin
  debugln('TArtikelgruppe.ReadData: ');
  with dtmBasis.qrySQL do
  begin
    try
      SQL.Text := Query;
      Open;
      fID := FieldByName('idartikelgruppe').AsInteger;
      fIDColor := FieldByName('fk_color').AsInteger;
      fArtikelgruppe := FieldByName('artikelgruppe').AsString;
      Close;
    except
      On E: Exception do
        debugln(' ' + E.Message)
    end;
  end;
end;
 
destructor TArtikelgruppe.Destroy;
begin
  inherited;
end;
 
 
end.
Zuletzt geändert von MacWomble am 14. Jan 2019, 08:34, insgesamt 1-mal geändert.
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.
MacWomble
Lazarusforum e. V.
 
Beiträge: 794
Registriert: 17. Apr 2008, 00:59
Wohnort: Freiburg
OS, Lazarus, FPC: Mint 19.1 Cinnamon / CodeTyphon LAB Version 6.90 / FP 3.3.1 Rev 42237 | 
CPU-Target: Intel i7 64/32 Bit
Nach oben

Beitragvon pluto » 13. Jan 2019, 14:01 Re: Objektlisten erstellen

ich mache das immer so:
Hinweis: für TObjectList musst du die Unit: Contnrs mit einbinden.
Code: Alles auswählen
 
{ TPLNoteManagerDirectoryItemList }
  TPLNoteManagerDirectoryItemList = class
  private
    function GetCount: Integer;
    function GetItem(const aIndex: Integer): TPLNoteManagerDirectoryItem;
 
  protected
 
  public
    Items:TObjectList;
    constructor Create;
    destructor Destroy; override;
 
    procedure AddItem(aDirectoryItem:TPLNoteManagerDirectoryItem);
 
    property Count:Integer read GetCount;
    property Item[const aIndex:Integer]:TPLNoteManagerDirectoryItem read GetItem; default;
  published
  end; // TPLNoteManagerDirectoryItemList       
 
...
 
function TPLNoteManagerDirectoryItemList.GetCount: Integer;
begin
  result:=items.Count
end; // TPLNoteManagerDirectoryItemList.GetCount
 
function TPLNoteManagerDirectoryItemList.GetItem(const aIndex: Integer): TPLNoteManagerDirectoryItem;
begin
  result:=items[aIndex] as TPLNoteManagerDirectoryItem
end; // TPLNoteManagerDirectoryItemList.GetItem
 
MFG
Michael Springwald
Aktuelles Projekt: PlutoArduino
pluto
Lazarusforum e. V.
 
Beiträge: 7006
Registriert: 19. Nov 2006, 12:06
Wohnort: Oldenburg/Oldenburg
OS, Lazarus, FPC: Linux Mint 18.3 | 
CPU-Target: AMD
Nach oben

Beitragvon MacWomble » 13. Jan 2019, 14:11 Re: Objektlisten erstellen

Das muss ich mir genauer anschauen.

Ich habe es inzwischen so versucht:
Code: Alles auswählen
 
uses ...Contnrs;
...
  TArtikelgruppenListe = class(TObjectList)
  private
    class var FItemClass: TArtikelgruppe;
  protected
    procedure SetItems(i: integer; const AValue: TArtikelgruppe);
    function GetItems(i: integer): TArtikelgruppe;
  public
    property Items[i: integer]: TArtikelgruppe read GetItems write SetItems;
    procedure Add(AObject: TArtikelgruppe);
    procedure Read;
    procedure Save;
    class property ItemClass: TArtikelgruppe read FItemClass write FItemClass;
    function FindByID(const AID: string): integer;
  end;     


Zuerst lesen, dann fragen :oops:
Du hast mir die Antwort ja geliefert, warum TObjectlist nicht ging.

Habe nun:
uartikelgruppe.pas(22,16) Warning: An inherited method is hidden by "destructor Destroy;"
uartikelgruppe.pas(65,13) Error: identifier idents no member "SetItems"
uartikelgruppe.pas(70,24) Error: identifier idents no member "GetItems"
Zuletzt geändert von MacWomble am 13. Jan 2019, 14:27, insgesamt 1-mal geändert.
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.
MacWomble
Lazarusforum e. V.
 
Beiträge: 794
Registriert: 17. Apr 2008, 00:59
Wohnort: Freiburg
OS, Lazarus, FPC: Mint 19.1 Cinnamon / CodeTyphon LAB Version 6.90 / FP 3.3.1 Rev 42237 | 
CPU-Target: Intel i7 64/32 Bit
Nach oben

Beitragvon MacWomble » 13. Jan 2019, 14:26 Re: Objektlisten erstellen

Ok, wenn ich es an deine Lösung anpasse, sind die Fehler weg :oops: - weitere Fragen in Kürze ... :roll:
Zuletzt geändert von MacWomble am 13. Jan 2019, 14:44, insgesamt 2-mal geändert.
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.
MacWomble
Lazarusforum e. V.
 
Beiträge: 794
Registriert: 17. Apr 2008, 00:59
Wohnort: Freiburg
OS, Lazarus, FPC: Mint 19.1 Cinnamon / CodeTyphon LAB Version 6.90 / FP 3.3.1 Rev 42237 | 
CPU-Target: Intel i7 64/32 Bit
Nach oben

Beitragvon pluto » 13. Jan 2019, 14:34 Re: Objektlisten erstellen

Code: Alles auswählen
property Items[i: integer]: TArtikelgruppe read GetItems write SetItems;

Hier reicht eigentlich ein read getItems.... Selten wird ein SetItems gebraucht....

Code: Alles auswählen
destructor TArtikelgruppe.Destroy;
begin
  inherited;
end;

Das würde ich vielleicht so machen:
Code: Alles auswählen
destructor TArtikelgruppe.Destroy;
begin
  inherited Destroy;
end;
MFG
Michael Springwald
Aktuelles Projekt: PlutoArduino
pluto
Lazarusforum e. V.
 
Beiträge: 7006
Registriert: 19. Nov 2006, 12:06
Wohnort: Oldenburg/Oldenburg
OS, Lazarus, FPC: Linux Mint 18.3 | 
CPU-Target: AMD
Nach oben

Beitragvon MacWomble » 13. Jan 2019, 14:51 Re: Objektlisten erstellen

Danke!
Ich habe jetzt:
Code: Alles auswählen
TArtikelgruppenListe = class
  private
    function GetCount: integer;
    function GetItem(const aIndex: integer): TArtikelgruppe;
  protected
 
  public
    Items: TObjectList;
    constructor Create;
    destructor Destroy; override;
 
    procedure AddItem(aItem: TArtikelgruppe);
 
    property Count: integer read GetCount;
    property Item[const aIndex: integer]: TArtikelgruppe read GetItem; default;
  published
  end;
 
implementation
 
{ TArtikelgruppenListe }
 
function TArtikelgruppenListe.GetCount: integer;
begin
  Result := items.Count;
end;
 
function TArtikelgruppenListe.GetItem(const aIndex: integer): TArtikelgruppe;
begin
  Result := items[aIndex] as TArtikelgruppe;
end;
 
constructor TArtikelgruppenListe.Create;
begin
  inherited Create;
end;
 
destructor TArtikelgruppenListe.Destroy;
begin
  inherited Destroy;
end;
 
procedure TArtikelgruppenListe.AddItem(aItem: TArtikelgruppe);
begin
   inherited Add(aItem);
end;


Wie kommen die Daten aus der DB-Tabelle in die Liste?

Ich muss da ja eine Query mit 'SELECT * FROM ArtikelGruppen' absetzen. Dafür Dachte ich an eine procedure ReadAll, in welcher ich die DB öffne und Datensatz für Datensatz irendwie (mit AddItem?) in die ArtikelGruppenListe übernehme. Oder muß ich die einzeln anhand der ID dann in die TArtikelGruppe einlesen und dann mit AddItem übernehmen? Oder ganz anders?

Ich sehe Bäume, aber keinen Wald :oops:
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.
MacWomble
Lazarusforum e. V.
 
Beiträge: 794
Registriert: 17. Apr 2008, 00:59
Wohnort: Freiburg
OS, Lazarus, FPC: Mint 19.1 Cinnamon / CodeTyphon LAB Version 6.90 / FP 3.3.1 Rev 42237 | 
CPU-Target: Intel i7 64/32 Bit
Nach oben

Beitragvon pluto » 13. Jan 2019, 15:24 Re: Objektlisten erstellen

Ich sehe Bäume, aber keinen Wald

Das ist ganz einfach, du fügst sie hinzu.... Zum Beispiel so:
Code: Alles auswählen
 
procedure TPLNoteManager2.LoadDirectoryTableFromDB();
var
  Dir_Items:TObjectList;
 
  procedure BuildTreeNode(const aDirectoryID:Integer; aItems:TObjectList; aDirectoryItem:TPLNoteManagerDirectoryItem; const aLevel:Integer = 0);
  var
    i:integer;
    DirectoryItem:TPLNoteManagerDirectoryItem;
 
    TempDirectoryItem:TPLNoteManagerDirectoryItem;
  begin
    TempDirectoryItem:=nil;
    for i:=0 to aItems.Count-1 do begin
      DirectoryItem:=aItems[i] as TPLNoteManagerDirectoryItem;
      if (aDirectoryID = DirectoryItem.ParentID) then begin
        if (aLevel = DirectoryItem.Level) then begin
          if not Assigned(TempDirectoryItem) then
            TempDirectoryItem:=aDirectoryItem.AddItem(DirectoryItem)
          else
            TempDirectoryItem:=TempDirectoryItem.AddItem(DirectoryItem);
          BuildTreeNode(DirectoryItem.DirectoryID,aItems,TempDirectoryItem,aLevel+1);
          TempDirectoryItem:=TempDirectoryItem.Parent;
        end
      end;
 
    end; // for i
  end; // BuildTreeNode
var
  str:string;
  x:Integer;
  DirectoryItem:TPLNoteManagerDirectoryItem;
begin
  writeln('TEST');
  str:='select * from DirectoryTable;';
  MariaDB.Query.SQL.Text:=str;
  MariaDB.Query.ExecSQL;
  MariaDB.Query.Open;
 
  Dir_Items:=TObjectList.Create(false);
 
  if MariaDB.Query.RecordCount >= 0 then begin
    MariaDB.Query.First;
    while not MariaDB.Query.Eof do begin // not Query.Eof
      DirectoryItem:=TPLNoteManagerDirectoryItem.Create;
      for x:=0 to MariaDB.Query.Fields.Count-1 do begin
        if MariaDB.Query.FieldDefs[x].Name = 'id' then
          DirectoryItem.ID:=MariaDB.Query.Fields[x].AsInteger;
 
        if MariaDB.Query.FieldDefs[x].Name = 'DirectoryID' then
          DirectoryItem.DirectoryID:=MariaDB.Query.Fields[x].AsInteger;
 
        if MariaDB.Query.FieldDefs[x].Name = 'ParentID' then
          DirectoryItem.ParentID:=MariaDB.Query.Fields[x].AsInteger;
 
        if MariaDB.Query.FieldDefs[x].Name = 'Level' then
          DirectoryItem.Level:=MariaDB.Query.Fields[x].AsInteger;
 
        if MariaDB.Query.FieldDefs[x].Name = 'Name' then
          DirectoryItem.Name:=MariaDB.Query.Fields[x].AsString;
 
        if MariaDB.Query.FieldDefs[x].Name = 'CreatedateTime' then
          DirectoryItem.CreatedateTime:=MariaDB.Query.Fields[x].AsDateTime;
 
        if MariaDB.Query.FieldDefs[x].Name = 'LastReadDateTime' then
          DirectoryItem.LastReadDateTime:=MariaDB.Query.Fields[x].AsDateTime;
 
        if MariaDB.Query.FieldDefs[x].Name = 'LastwriteDateTime' then
          DirectoryItem.LastwriteDateTime:=MariaDB.Query.Fields[x].AsDateTime;
      end; // for x
 
      Dir_Items.Add(DirectoryItem);
      MariaDB.Query.Next;
    end; // while not
    BuildTreeNode(0,Dir_Items,DirectoryItemlist,0);
  end;
 
end; // TPLNoteManager2.LoadDirectoryTableFromDB
 


Das ist eine ganz besondere Proceduere, die kann aus der DirectoryTable eine Objekt Baum erzeugen, mit der man einfacher und schneller Arbeiten kann.
Diese Tabelle wird jetzt komplett eingelesen. Einmal beim Starten... und daraus wird dann der Objekt Baum erzeugt...
Aber ich denke, du siehst wie es gehen kann...

Es gibt bestimmt noch andere, vielleicht bessere Möglichkeiten.... Der Code stammt jetzt aus meinem Aktuellen Projekt... Aus dem Datenbaum möchte ich z.b. ein JSONEN Code erzeugen und an meine rest-clients versenden....
MFG
Michael Springwald
Aktuelles Projekt: PlutoArduino
pluto
Lazarusforum e. V.
 
Beiträge: 7006
Registriert: 19. Nov 2006, 12:06
Wohnort: Oldenburg/Oldenburg
OS, Lazarus, FPC: Linux Mint 18.3 | 
CPU-Target: AMD
Nach oben

Beitragvon MacWomble » 13. Jan 2019, 15:30 Re: Objektlisten erstellen

OK, das ist jetzt auch klar, Tabelle schrittweise einlesen und jeweils Objekt Der Artikelgruppe erstellen und in die Liste hinzufügen.

OffTopic: Die zweite Zeile kannst du doch weglassen.

Code: Alles auswählen
  MariaDB.Query.SQL.Text:=str;
  MariaDB.Query.ExecSQL; //wozu?
  MariaDB.Query.Open;
 
Zuletzt geändert von MacWomble am 13. Jan 2019, 15:35, insgesamt 1-mal geändert.
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.
MacWomble
Lazarusforum e. V.
 
Beiträge: 794
Registriert: 17. Apr 2008, 00:59
Wohnort: Freiburg
OS, Lazarus, FPC: Mint 19.1 Cinnamon / CodeTyphon LAB Version 6.90 / FP 3.3.1 Rev 42237 | 
CPU-Target: Intel i7 64/32 Bit
Nach oben

Beitragvon pluto » 13. Jan 2019, 15:33 Re: Objektlisten erstellen

OffTopic: Die zweite Zeile kannst du doch weglassen.

Damit der SQL Befehl auch ausgeführt wird.... Ich weiß nicht ob ich ihn weglassen kann. Ich mache immer beides:
ExecSQL
und dann wenn gebraucht ein Open... weil ich brauche nicht immer ein Open...

EDIT: Ich habe den Soruce-Code von SQL eben angeschaut(nur grob), ich glaube nicht, dass man ExecSQL weglassen kann.
ExecSQL und Open haben ja nichts gemeinsam....
MFG
Michael Springwald
Aktuelles Projekt: PlutoArduino
pluto
Lazarusforum e. V.
 
Beiträge: 7006
Registriert: 19. Nov 2006, 12:06
Wohnort: Oldenburg/Oldenburg
OS, Lazarus, FPC: Linux Mint 18.3 | 
CPU-Target: AMD
Nach oben

Beitragvon MacWomble » 13. Jan 2019, 15:36 Re: Objektlisten erstellen

Aber da du ja auf die Query anschließend zugreifst, brauchst du ein Open. Mit ExecSQL führst du den Befehl vorher schon aus (im Nirvana), machst also zwei mal den Zugriff auf die DB.
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.
MacWomble
Lazarusforum e. V.
 
Beiträge: 794
Registriert: 17. Apr 2008, 00:59
Wohnort: Freiburg
OS, Lazarus, FPC: Mint 19.1 Cinnamon / CodeTyphon LAB Version 6.90 / FP 3.3.1 Rev 42237 | 
CPU-Target: Intel i7 64/32 Bit
Nach oben

Beitragvon pluto » 13. Jan 2019, 15:44 Re: Objektlisten erstellen

Aber da du ja auf die Query anschließend zugreifst, brauchst du ein Open. Mit ExecSQL führst du den Befehl vorher schon aus (im Nirvana), machst also zwei mal den Zugriff auf die DB.

glaube ich nicht, dass ich zwei mal den Zugriff mache, ich werde es aber bei nächster Gelegenheit testen.... Ich habe mir angeschaut was im Open Passiert, da steht nichts davon das dort ein ExecSQL..

Wenn ich mich täusche, werde ich es natürlich sofort umbauen...... sogar im FPC-Wiki steht es so drin.... alle andere machen es ähnlich(soweit ich weiß).
erst ein ExecSQL und dann ein Open....
MFG
Michael Springwald
Aktuelles Projekt: PlutoArduino
pluto
Lazarusforum e. V.
 
Beiträge: 7006
Registriert: 19. Nov 2006, 12:06
Wohnort: Oldenburg/Oldenburg
OS, Lazarus, FPC: Linux Mint 18.3 | 
CPU-Target: AMD
Nach oben

Beitragvon pluto » 13. Jan 2019, 15:47 Re: Objektlisten erstellen

Du hast recht, es geht auch ohne "ExecSQL", habe ich eben ausprobiert... hätte ich jetzt nicht erwartet... Danke für den Hinweis...
MFG
Michael Springwald
Aktuelles Projekt: PlutoArduino
pluto
Lazarusforum e. V.
 
Beiträge: 7006
Registriert: 19. Nov 2006, 12:06
Wohnort: Oldenburg/Oldenburg
OS, Lazarus, FPC: Linux Mint 18.3 | 
CPU-Target: AMD
Nach oben

Beitragvon af0815 » 13. Jan 2019, 16:33 Re: Objektlisten erstellen

Faustregel:
ExecSQL wenn man kein Recordset zurück erwartet. Zb. Create... Insert, update, delete.
Open wenn ein Recordset erwartet wird. Normalerweise bei einem Select. Natürlich bei visuellen Komponenten nötig, da diese ja immer an ein Recordset gebunden sind.

Btw, Recordset ist nicht gleich Query.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
af0815
 
Beiträge: 3691
Registriert: 7. Jan 2007, 10:20
Wohnort: Niederösterreich
OS, Lazarus, FPC: FPC 3.2 Lazarus 2.0 per fpcupdeluxe | 
CPU-Target: 32Bit (64Bit)
Nach oben

Beitragvon pluto » 13. Jan 2019, 16:43 Re: Objektlisten erstellen

Faustregel:

war mir so nicht bewusst. Ich hatte es aus irgendwelchen Beispielen von fpc-wiki übernommen...
MFG
Michael Springwald
Aktuelles Projekt: PlutoArduino
pluto
Lazarusforum e. V.
 
Beiträge: 7006
Registriert: 19. Nov 2006, 12:06
Wohnort: Oldenburg/Oldenburg
OS, Lazarus, FPC: Linux Mint 18.3 | 
CPU-Target: AMD
Nach oben

Beitragvon MmVisual » 13. Jan 2019, 17:04 Re: Objektlisten erstellen

Ich habe jetzt nicht alles gelesen ... aber:
Code: Alles auswählen
str:='select * from DirectoryTable;';


Schreibe immer die Tabellennamen in Kleinbuchstaben, denn sollte es mal ein Linux-Server sein, dann geht das sonst nicht mehr.
MmVisual
 
Beiträge: 1059
Registriert: 10. Okt 2008, 22:54
OS, Lazarus, FPC: Winux (L 1.6 FPC 3) | 
CPU-Target: 32/64Bit
Nach oben

» Weitere Beiträge siehe nächste Seite »
Nächste

Zurück zu Freepascal



Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast

porpoises-institution
accuracy-worried