Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - DB an VirtualStringTree anbinden


NOS1971 - Sa 05.04.14 19:39
Titel: DB an VirtualStringTree anbinden
Hallo zusammen,

ich versuche meine DB an einen VST anzubinden ... habe nun eine klasse die die URL enthält anhand der ich den datensatz aus der db auslesen möchte ...

hier nun meine routine die einen fehler nach dem anderen schmeisst ... "Ungültige Zeigeroperation" und "Zu wenig Arbeitsspeicher" etc. ...

Was mache ich falsch ?



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:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
procedure TfrmMTWS.vstWebSpiderResultsGetText(Sender: TBaseVirtualTree;
  Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
  var CellText: string);
var
 Data: TUrlNodeTreeData;
 CurrentAnalyseItem: TSQLDataSet;
begin
 CurrentAnalyseItem := TSQLDataSet.Create(nil);
 CurrentAnalyseItem.SQLConnection := MultiThreadedWebAnalyser.AnalyserResultDataBaseConnecton;
 if (Node <> nilthen
 begin
  Data := Sender.Get<TUrlNodeTreeData>(Node);
  if (Data <> niland (Data is TUrlNodeTreeData) then
  begin
   try
    CurrentAnalyseItem.CommandText := 'SELECT * FROM ResultURLTable WHERE URL = "' + TUrlNodeTreeData(Data).URL + '";';
    CurrentAnalyseItem.Open;
    if not CurrentAnalyseItem.IsEmpty then
    begin
     // item found
     CurrentAnalyseItem.First;
     case Column of
      0begin
       if CurrentAnalyseItem.FieldList.IndexOf('STATUS') <> - 1 then
       begin
        case TField(CurrentAnalyseItem.FieldByName('STATUS')).AsInteger of
         asNotAnalysed : CellText := sStatusNotAnalysed;
         asPending     : CellText := sStatusPending;
         asAnalysed    : CellText := sStatusAnalysed;
        end;
       end;
      end;
      1begin
       if CurrentAnalyseItem.FieldList.IndexOf('URL') <> - 1 then
       begin
        Celltext := TField(CurrentAnalyseItem.FieldByName('URL')).AsString;
       end;
      end;


     end;
    end;
   except
    on E: Exception do
    begin
     // send progress event to actualize the site
     PostMessage(frmMTWS.Handle, WSM_MESSAGE_ERROR_LOG, 0, Integer('Exception raised with message: Get item data from DB for VST - ' + TUrlNodeTreeData(Data).URL + ' - ' + E.Message));
    end;
   end;
  end;
 end;
 CurrentAnalyseItem.Close;
 CurrentAnalyseItem.Free;


Ich hoffe Ihr könnt helfen ...

Grüße und Danke,
Andreas


jaenicke - So 06.04.14 13:52

Da sehe ich erst einmal nichts Auffälliges. Die Meldungen deuten aber darauf hin, dass du Objekte nicht sauber verwaltest. Sprich dass du diese entweder z.B. doppelt freigibst oder diese in mehreren Threads parallel nutzt.
Für letzteres ist die Connection ein Kandidat. Kann es sein, dass du die selbe Connection in mehreren Threads nutzt? Das wird wohl kaum funktionieren.

Bei solchen Fehlern hilft oft FastMM.

Ich würde auch nicht jedesmal das ganze TSQLDataSet neu erstellen. Das dauert gerade im OnGetText unnötig lange. Eine Möglichkeit wäre, damit nicht zu viel im Speicher liegt, zumindest nur eine TSQLDataSet mit der gleichen SQLConnection zu nutzen.


NOS1971 - So 06.04.14 14:29

Du hast recht ... ich nutze eine connection für alle threads
das funzt auch super beim scheiben ... wenn ich aber dann anfange aus dem hauptthread zu lesen ist vorbei mit lustig

dann baue ich das mal um auf eine connection per thread in der hoffnung das das nicht probleme gibt ... :-)


NOS1971 - So 06.04.14 16:20

Also ich habe nun in jedem Thread eine TSQLConnection aber schon beim schreiben in die db bekomme ich einen "database is locked" nach dem anderen ... mit einer zentralen connection für alles threads geht das problemlos ... mache ich gedanklich einen fehler was die db sachen anbelangt ?


jaenicke - So 06.04.14 17:53

Dann benutzt du eine Datenbank, die nur eine Verbindung verträgt, ich habe in deinen Threads nochmal nachgeschaut und gesehen, dass es SQLite ist, oder?
Du wirst daher nicht umhin kommen die Zugriffe abzusichern. Das macht es zwar relativ langsam, aber wie ich schon in dem anderen Thread seinerzeit geschrieben habe, wirklich schnell ist nur ein echter Server.

Firebird kann glaube ich in der aktuellen Version auch in der Embedded mit mehreren Zugriffen parallel umgehen.

Ein echter MS SQL Server wäre aber trotzdem am sinnvollsten. Wenn du das nicht möchtest und Firebird Embedded auch nicht klappt, bleibt dir nichts anderes übrig als nur eine Connection zu benutzen und alle Zugriffe threadsicher zu machen, sprich mit TMonitor.Enter..TMonitor.Exit abzusichern... eben auf Kosten der Performance.


NOS1971 - So 06.04.14 19:20

hmmm ...

also es soll schon bei einer software bleiben für die ich keinen server installen muss ... oder sagen wir so .. ich sollte den server irgendwann komerziell nutzen können ohne das ich für jede version lizenzgebühren oder sowas bezahlen muss ... mit optionen zu sqlite aus ?
... wie gesagt ... das schreiben aus allen threads gleichzeitig läuft super dadurch ... also kann ich so aber nicht den VST befüllen zur analysezeit ... richtig ?


jaenicke - So 06.04.14 19:33

user profile iconNOS1971 hat folgendes geschrieben Zum zitierten Posting springen:
oder sagen wir so .. ich sollte den server irgendwann komerziell nutzen können ohne das ich für jede version lizenzgebühren oder sowas bezahlen muss ...
Wir nutzen auch MS SQL Express kommerziell. Das ist kostenlos, solange du nicht über 10 GiB pro Datenbank mit allen Tabellen darin kommst.
Und es gibt auch noch genug andere SQL Server, die kostenlos sind.


NOS1971 - So 06.04.14 20:40

Ok ... also stelle ich nun alles in die richtung um wenn ich das recht sehe ... gibt es da gute tutorials für delphi ?


jaenicke - So 06.04.14 21:09

Da du mit deiner Professional dafür weder FireDAC noch dbExpress nutzen können wirst (es sei denn mit C/S Pack), kann ich dir da leider nicht so gut weiterhelfen.

Ich denke einmal ZEOS ist dafür das richtige, aber selbst kenne ich das kaum und habe es seit Jahren nicht benutzt:
http://sourceforge.net/projects/zeoslib/


NOS1971 - Sa 03.05.14 18:19

So ...

nun habe ich mir RAD Studio XE6 Enterprise gekauft und auch alle anderen Compos entsprechend lauffähig auf XE6 ... nun sollte ich ja gewappnet sein :-) ... Welchen SQL Express Server nimmt man denn nun ? 2012 ist der letzte ... macht es Sinn den letzten zu nutzen ? Nehme ich dann FireDAC zum Connecten ?

Grüßle,

Andreas