[Gelöst] SQLDB SQLite

Für Themen zu Datenbanken und Zugriff auf diese. Auch für Datenbankkomponenten.
Antworten
charlytango
Beiträge: 351
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz 2.0 fixes FPC 3.2 fixes
CPU-Target: Win 32Bit, 64bit
Wohnort: Wien

[Gelöst] SQLDB SQLite

Beitrag von charlytango »

HI,
üblicherweise verwende ich ZEOS, nun wollte ich SQLDB testen und laufe gleich in irgend eine Falle.
Wenn ich die graphischen Komponenten nehme gelingt die Verbindung mit SQLite problemlos.
Versuche ich das zur Laufzeit geht es schief.
Namentlich wird ein falscher Connector-Type angemeckert. Ich setze

Code: Alles auswählen

SQLConnector1.ConnectorType:='SQLite3';
genau wie in der IDE mittels Combobox. Genauer gesagt weise ich eine Konstante mit Inhalt 'SQLite3' zu.

Was ist falsch ? :(
Zuletzt geändert von charlytango am Di 4. Mai 2021, 16:23, insgesamt 1-mal geändert.

wp_xyz
Beiträge: 3684
Registriert: Fr 8. Apr 2011, 09:01

Re: SQLDB SQLite

Beitrag von wp_xyz »

Ich muss zu meiner Schande eingestehen, dass ich noch nie einen SQLConnector gebraucht habe. Verwechselst du ihn evtl. mit der SQLite3Connection?

Ein Laufzeit-Beispiel findest du unter https://wiki.freepascal.org/TSQLite3Connection.

charlytango
Beiträge: 351
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz 2.0 fixes FPC 3.2 fixes
CPU-Target: Win 32Bit, 64bit
Wohnort: Wien

Re: SQLDB SQLite

Beitrag von charlytango »

wp_xyz hat geschrieben:
So 2. Mai 2021, 19:03
Verwechselst du ihn evtl. mit der SQLite3Connection?
Ich glaube nicht -- bin da (von ZEOS kommend) etwas blauäugig herangegangen und hab TSQLConnector so verwendet wie eine TZConnection -- quasi als allgemeine Zugriffskomponente auf verschiedene Datenbanktypen die mittels ConnectorType auf die unterschiedlichen Datenbanken eingestellt wird.

Dieser Text gibt mir irgendwie recht:

Code: Alles auswählen

https://www.freepascal.org/docs-html/fcl/sqldb/tsqlconnector.html
und als graphische Komponenten klappt es ja --- nur wenn ich zur Laufzeit (an den zur Laufzeit erzeugten TSQLConnector) den ConnectorType 'SQLite3' zuweise wird gemeckert.

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

Re: SQLDB SQLite

Beitrag von af0815 »

https://www.freepascal.org/docs-html/fc ... ctors.html

Sagt das, das du die Type über die funktion GetConnectionlist machen musst und über die die möglichen Connectionsstring bekommst. Die kannst du dann setzen, wenn der Connector nicht aktiv ist.

Vielleicht sind die möglichen Namen etwas anders als du bisher verwenden willst. Lass dir mal die Liste ausgeben.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

charlytango
Beiträge: 351
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz 2.0 fixes FPC 3.2 fixes
CPU-Target: Win 32Bit, 64bit
Wohnort: Wien

Re: SQLDB SQLite

Beitrag von charlytango »

af0815 hat geschrieben:
So 2. Mai 2021, 19:51
https://www.freepascal.org/docs-html/fc ... ctors.html

Sagt das, das du die Type über die funktion GetConnectionlist machen musst und über die die möglichen Connectionsstring bekommst. Die kannst du dann setzen, wenn der Connector nicht aktiv ist.

Vielleicht sind die möglichen Namen etwas anders als du bisher verwenden willst. Lass dir mal die Liste ausgeben.
Die Liste ist leer (GetConnectionlist) -- irgendwie hab ich nicht verstanden wie SQLDB funktioniert. Offensichtlich brauche ich da pro Datenbanktyp einen eigene n TSQLConnection Descendant (Zb. TSQLite3Connection) was das ganze eher unhandlich macht wenn man zwischen DB-Typen umschalten will.

Aber wenn ich einen eigenen Descendant brauche, warum gibts dann TSQLConnector als eigene graphische Komponente ... und warum funktioniert es mit grafischen Komponenten und nicht mit zur Laufzeit erzeugten?

Verstehe das Konzept nicht.


PS: hab in den Examples das sqlTutorial3 gefunden, wo die Objekte auch zur Laufzeit erzeugt werden.
Interessanterweise hab bekomme ich auch dort die Fehlermeldung wenn ich auch SQLite umschalte
Zuletzt geändert von charlytango am So 2. Mai 2021, 21:27, insgesamt 1-mal geändert.

Socke
Lazarusforum e. V.
Beiträge: 2915
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: SQLDB SQLite

Beitrag von Socke »

SQLdb liefert für jeden Verbindungstyp eigene *Connection-Komponenten. Diese können jeweils mit einer Datenbank sprechen.

TSQLConnector ist nur ein Proxy zu diesen jeweiligen Connection-Komponenten. Damit dies zur Laufzeit funktioniert, musst du die gewünschten Connection-Units ebenfalls einbinden.
Am einfachsten setzt du eine TSQLite3Connection auf dein Formular und löscht diese hinterher wieder vom Formular. Die Unit SQLite3Conn verbleibt dann im Uses-Abschnitt.

Zur Designzeit funktioniert dies, da diese ganzen Connection-Units in Lazarus gelinkt werden.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

charlytango
Beiträge: 351
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz 2.0 fixes FPC 3.2 fixes
CPU-Target: Win 32Bit, 64bit
Wohnort: Wien

Re: SQLDB SQLite

Beitrag von charlytango »

Socke hat geschrieben:
So 2. Mai 2021, 21:21
SQLdb liefert für jeden Verbindungstyp eigene *Connection-Komponenten. Diese können jeweils mit einer Datenbank sprechen.

TSQLConnector ist nur ein Proxy zu diesen jeweiligen Connection-Komponenten.

Damit dies zur Laufzeit funktioniert, musst du die gewünschten Connection-Units ebenfalls einbinden.
Am einfachsten setzt du eine TSQLite3Connection auf dein Formular und löscht diese hinterher wieder vom Formular. Die Unit SQLite3Conn verbleibt dann im Uses-Abschnitt.

Zur Designzeit funktioniert dies, da diese ganzen Connection-Units in Lazarus gelinkt werden.
Danke, damit ist zumindest mal für mich geklärt warum es manchmal funktioniert hat und warum nicht.

Interessant ist auch dass zur Designzeit nicht nur der TSQLConnector sondern auch die TSQLQuery-Komponente eine Transaction zugewiesen bekommen muss damit es klappt -- bzw die automatisch eingetragen wird wenn eine Transaction-Komponente vorher auf dem Formular ist.

Wie dieser TSQLConnector als Proxy arbeitet, in welchen Verzeichnissen nach DLLs gesucht wird hab ich noch nicht herausbekommen können.

Zudem ist mir auch die Funktion des TSQLDBLibraryLoader der außer eines ConnectionType scheinbar keine Verbindung zum TSQLConnector zu haben scheint unklar.

Wenn ich mehrere Datenbanktypen unterstützen will/muss sieht mir ZEOS (langjährig genutzt) charmanter aus. Ich wollte für mein Projekt mit Applikationseinstellungen eine Lösung mit "Bordmitteln" versuchen. Bis jetzt hab ich noch nicht kapiert wie alle SQLDB Komponenten zusammen arbeiten.
Habe im Code rumgegraben und einiges entdeckt aber wirklich erhellend war das nicht.

Gibts irgendwo Text/Doku dazu? Bei den üblichen Verdächtigen (Wiki, Forum) hab ich nix tiefergehendes gefunden.

Ich gebe dem Teil nochmal bis zum Wochenende, dann nehm ich ZEOS.

Socke
Lazarusforum e. V.
Beiträge: 2915
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: SQLDB SQLite

Beitrag von Socke »

charlytango hat geschrieben:
Di 4. Mai 2021, 09:20
Interessant ist auch dass zur Designzeit nicht nur der TSQLConnector sondern auch die TSQLQuery-Komponente eine Transaction zugewiesen bekommen muss damit es klappt -- bzw die automatisch eingetragen wird wenn eine Transaction-Komponente vorher auf dem Formular ist.
Die Transaction wird zumindest aus anderen verknüpften Komponenten übernommen. Bsp: Die Transaction ist der Verbindung zugewiesen. Wenn du jetzt die Verbindung an die Query zuweist, wird die Transaction automatisch übernommen.
charlytango hat geschrieben:
Di 4. Mai 2021, 09:20
Wie dieser TSQLConnector als Proxy arbeitet, in welchen Verzeichnissen nach DLLs gesucht wird hab ich noch nicht herausbekommen können.

Zudem ist mir auch die Funktion des TSQLDBLibraryLoader der außer eines ConnectionType scheinbar keine Verbindung zum TSQLConnector zu haben scheint unklar.
Sofern du den Library Loaded nicht verwendest, werden die Standardbibliothektsnamen (siehe Units) in den Standardsuchverzeichnissen des Betriebssystems verwendet. Bei SQLite3 geht die Referenz im Quelltext so: Unit SQLITe3Conn stelllt die Verbindungsklasse bereit. Sie nutzt über die Unit sqlite3dyn eine dynamisch geladene SQLite3-Bibliothek. In der Unit ist für Windows sqlite3.dll bzw. für alle aneren libsqlite3.so als Bibliotheksnamen vorgegeben.

Der TSQLDBLibraryLoader funktioniert über das selbe Prinzip des ConnectionTypes wie der TSQLConnector. Als Voraussetzung müssen daher die einzelnen Connection-Units (z.B. SQLite3conDann kannst du in der Eigenschaft "ConnectionType" den gewünschten Typen auswählen (SQLite3), in "Libraryname" den Dateiname (mit oder ohne Pfad) eintragen.
Anschließend setzt du "Enabled" auf True. Der Library Loaded lädt dann die Datenbank-DLL mit dem angepassten Pfad. Erst danach darfst du deine TSQLConnection bzw. den Connector verbinden/öffnen.

Daraus folgt:
  • Öffnest du eine TSQLConnection bevor die Bibliothek geladen wurde, wird die Standardinitializierung mit Standardbiliotheksnamen/-pfad durchgeführt
  • Du kannst maximal eine DLL pro Verbindungstyp nutzen. Es ist nicht möglich, für verschiedene Verbindungen unterschiedliche DLLs zu laden (z.B. verschiedene SQLite3-Versionen).
charlytango hat geschrieben:
Di 4. Mai 2021, 09:20
Gibts irgendwo Text/Doku dazu? Bei den üblichen Verdächtigen (Wiki, Forum) hab ich nix tiefergehendes gefunden.
Leider kenne ich aus dem Wiki auch nur die Standardbeispiele. Die Quelltexte sind aber halbwegs gut zu lesen.
Eine Dokumentation, ob und welche Verbindungen ein echtes Parameter-Binding und nicht SQL-Formattierung unterstützen bzw. wie dieses im Code umzusetzen wäre habe ich auch noch nicht gefunden.
Ebenso fehlt mir im Fall von SQLite3 das Mapping zwischen SQLite3-Datentypen und SQLDB-Datentypen. Zu letzteren fehlt insgesamt eine aussagekräftige Beschreibung. Was unterscheidet ein AutoInc von den verschiedenen Integer-Typen? Embarcadero kann das aber auch gut: Ab wann ist ftBCD zu klein und ich muss auf ftFMTBcd ausweichen?
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

charlytango
Beiträge: 351
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz 2.0 fixes FPC 3.2 fixes
CPU-Target: Win 32Bit, 64bit
Wohnort: Wien

Re: SQLDB SQLite

Beitrag von charlytango »

Socke hat geschrieben:
Di 4. Mai 2021, 10:47
Die Quelltexte sind aber halbwegs gut zu lesen.
Für mich nicht ganz sooo leicht ;)


So...ich hab es dank der Tips von Socke erstaunlicherweise hin gebracht.
Meine Lösung/Erkenntnisse für den geneigten Suchenden festgehalten:
  • Der Gamechanger war die Information dass die Units der SQL-Verbindungstypen die man unterstützen will/muss in der uses-Klausel vorkommen müssen.

Code: Alles auswählen

uses .... , SQLDB, SQLDBLib .....
reicht nicht

da muss zb für SQLite eingebunden werden.

Code: Alles auswählen

uses .... , SQLDB, SQLDBLib, SQLite3Conn, ....
Und es reicht das Erwähnen in der Uses-Klausel. Sonst wird eine Fehlermeldung erscheinen mit irgendwas wie "SQLite3 Connection nicht gefunden" was ich fälschlicherweise so interpretiert habe dass der ConnectionType "SQLite3" unbekannt wäre. Tatsächlich scheint wirklich die TSQLite3Connection gemeint zu sein.

Die zweite wichtige Info war die Reihenfolge in der die Klassen geöffnet werden müssen.
Zuerst dem TLDBLibraryLoader den Pfad zur DLL und den Connectortyp zuweisen, dann quasi Einschalten

Code: Alles auswählen

myLibLoader:TLDBLibraryLoader;
myConnector:TSQLConnector;
myTransaction:TSQLTransaction;
myQuery:TSQLQuery;
myLibLoader:TSQLDBLibraryLoader;
....
....

......//Im Create des Objektes:

  myConnector:= TSQLConnector.Create(nil);
  myTransaction:=TSQLTransaction.Create(nil);
  myQuery:= TSQLQuery.Create(nil);
  myLibLoader:=TSQLDBLibraryLoader.create(nil);

  //Verbindungen der Objekte herstellen
  myConnector.Transaction:=FSQLTransaction;
  myQuery.Database:=FSQLConnector;

....

//Dll laden
myLibLoader.Enabled:=false;  //löst intern ein UnloadLibrary aus.
myLibLoader.LibraryName:='<Pfad zur DLL samt dll Name>';
myLibLoader.ConnectionType:='SQLite3';  //exemplarisch für SQLite
myLibLoader.Enabled:=true;  //löst intern ein LoadLibrary aus.

//erst danach Verbindung zur Datenbank aufbauen
// TSQLDBConnector je nach Datenbank Attribute zuweisen
// wie username, Datenbankname ,passwort, Connectiontype etc etc.. 
//danach
myConnector.Open;

....
//um Daten auszulesen
myQuery.SQL.Text:='select xy from xyTablename';
myQuery.Open;
Danke für eure Hilfe - case closed

Socke
Lazarusforum e. V.
Beiträge: 2915
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: SQLDB SQLite

Beitrag von Socke »

charlytango hat geschrieben:
Di 4. Mai 2021, 16:23
Und es reicht das Erwähnen in der Uses-Klausel. Sonst wird eine Fehlermeldung erscheinen mit irgendwas wie "SQLite3 Connection nicht gefunden" was ich fälschlicherweise so interpretiert habe dass der ConnectionType "SQLite3" unbekannt wäre. Tatsächlich scheint wirklich die TSQLite3Connection gemeint zu sein.
Hier noch ein Hinweis: Jede Connection-Unit registriert beim Programmstart automatisch eine ConnectionTypeDef. Diese Informationen stehen dann zur Laufzeit zur Verfügung und sind z.B. für den LibraryLoader oder SQLConnector auswertbar.
Man kann darauf auch selbst zugreifen:

Code: Alles auswählen

uses Classes, Sysutils, SQLDB (* und weitere Units: z.B. SQLite3conn *);
var
  ListOfConnectors: TStrings;
  ConnectorTypeName: String;
  ConnectorDefinition: TConnectionDef;
begin
  ListOfConnectors := TStringList.Create;
  for ConnectorTypeName in ListOfConnectors do
  begin
    ConnectorDefinition := GetConnectionDef(ConnectorTypeName);
    WriteLn(ConnectorDefinition.TypeName);
    WriteLn(ConnectorDefinition.Description);
    WriteLn(ConnectorDefinition.DefaultLibraryName);
  end;
  ListOfConnectors.Destroy;
end.
Auch für den Objektinspektor wird darauf zugegriffen, wenn du z.B. den ConnectionType des TSQLDBConnector änderst.
Das ist dann in der Klasse TSQLDBConnectorTypePropertyEditor in der Unit \lazarus\components\sqldb\registersqldb.pas geregelt (diese Unit ist Teil von Lazarus, während SQLDB vom FPC ausgeliefert wird).
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Antworten