SQLite3 auch unter Linux an Programm binden?

Für Themen zu Datenbanken und Zugriff auf diese. Auch für Datenbankkomponenten.
Uwe_9988
Beiträge: 30
Registriert: Fr 14. Jan 2011, 11:02

SQLite3 auch unter Linux an Programm binden?

Beitrag von Uwe_9988 »

Hallo zusammen,

ich passe gerade einige SQLite3-Units an (Wrapper und ein paar nützliche Klassen), die ich unter Delphi verwendet habe und die ich um Funktionen erweitert habe, die ein linken der sqlite3.dll als Resource ermöglichen. Zur Laufzeit werden die Funktionen der dll dann direkt im Speicher ausgeführt.

Man kann also die Funktionen der dll verwenden ohne die dll im Programmverzeichnis entpacken oder überhaupt mitgeben zu müssen. Außerdem muss man sich nicht um dll-Versionen kümmern, weil automatisch die richtige dll verwendet wird.

Unter Windows funktioniert das schon für Win32 sowohl mit Delphi als auch mit Lazarus.

Meine Frage ist jetzt, ob es sinnvoll/möglich ist das ganze auch an Linux anzupassen oder ob sich diese Problematik unter Linux gar nicht so stellt. (Dass es sqlite3 schon für Lazarus gibt, ist mir bewusst. Es geht eher um den Gedanken eine dynamische Library statisch an ein Programm zu binden. ;))


Grüße,
Uwe

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

Re: SQLite3 auch unter Linux an Programm binden?

Beitrag von theo »

Würde ich nicht machen. Das ist ja je nach Installer als Abhängigkeit auch schnell gedownloadet und installiert, wenn es nicht bereits vorhanden ist.

Uwe_9988
Beiträge: 30
Registriert: Fr 14. Jan 2011, 11:02

Re: SQLite3 auch unter Linux an Programm binden?

Beitrag von Uwe_9988 »

Hallo Theo,

der ganze Ansatz ist sicherlich etwas paradox. :) Wenn ich noch C programmieren würde, dann würde ich einfach die SQLite3-Sourcen als Object kompilieren und dazulinken. Aber für Delphi war der Umweg damals so einfacher zu realisieren.

Es ging ja auch darum immer die aktuellen dlls bei der Entwicklung verwenden zu können ohne immer wieder Anpassungen (für Delphi) an den Sourcen machen zu müssen.

Praktisch ist das schon, wenn alle Sachen, die ein Programm braucht, schon fix dabei sind. :)

Also prinzipiell wäre es machbar, oder?

Oder gibt es unter Linux einen C-Compiler, der objectkompatibel zu FPC ist? Dann wäre ja der Weg über .dll/.so hinfällig.


Grüße,
Uwe

creed steiger
Beiträge: 957
Registriert: Mo 11. Sep 2006, 22:56

Re: SQLite3 auch unter Linux an Programm binden?

Beitrag von creed steiger »

Ich muss Theo beipflichten.Unter Windows mag das noch sinnvoll sein.
Aber Linux ist da ein bissl anders.
Im Paket als Abhängigkeit definieren und der Paketmanager erledigt den Rest.
Ist eigentlich ein ganz normaler Vorgang.

(aber lass dich in deinem Forscherdrang nicht aufhalten ;))

Hitman
Beiträge: 512
Registriert: Mo 25. Aug 2008, 18:17
OS, Lazarus, FPC: ArchLinux x86, WinVista x86-64, Lazarus 0.9.29, FPC 2.4.1
CPU-Target: x86
Wohnort: Chemnitz

Re: SQLite3 auch unter Linux an Programm binden?

Beitrag von Hitman »

Uwe_9988 hat geschrieben:Oder gibt es unter Linux einen C-Compiler, der objectkompatibel zu FPC ist? Dann wäre ja der Weg über .dll/.so hinfällig.

Öhm ja, GCC ;-)
Das ist ja das schöne an FPC.

Geht übrigens auch unter Windows, aber so oder so ist statisches Linken relativ tricky, da meist noch erheblich mehr Libraries dranhängen.

Uwe_9988
Beiträge: 30
Registriert: Fr 14. Jan 2011, 11:02

Re: SQLite3 auch unter Linux an Programm binden?

Beitrag von Uwe_9988 »

Danke schonmal für eure Antworten. :)

Im Paket als Abhängigkeit definieren und der Paketmanager erledigt den Rest.
Ist eigentlich ein ganz normaler Vorgang.

Bestimmt, wenn man es schon ein paar mal gemacht hat. ;)

Im Moment sitze ich vor meinem CentOS 5.5 (32bit) und versuche SQLite3 in der neuesten Version darauf zu bekommen. Im Packetmanager wird mir die leicht angestaubte Version sqlite-devel-3.3.6.5 angeboten, wenn das überhaupt das gewünschte ist. "Entwicklungswerkzeuge für sqlite3..."

Habe gerade mal aus einem rpm-Package eine libsqlite3.so rausgepult und in das Projektverzeichnis kopiert aber das geht wohl ein wenig anders unter Linux, oder? :oops: LoadLibrary hat jedenfalls nicht funktioniert...

Der SQLite3-Wrapper, den ich verwende, stammt ursprünglich von:

Code: Alles auswählen

{
  Simplified interface for SQLite.
  Updated for Sqlite 3 by Tim Anderson (tim@itwriting.com)
  Adapted from file created by Pablo Pissanetzky (pablo@myhtpc.net)
  which was based on SQLite.pas by Ben Hochstrasser (bhoc@surfeu.ch)
}
und scheint schonmal für Linux angepasst worden zu sein.

Ich habe nur leider keine Ahnung ob der Code auch funktioniert. Der Teil, der die Library lädt, sieht im Moment so aus und funktioniert in der Windowswelt:

Code: Alles auswählen

const
{$IF Defined(MSWINDOWS)}
  SQLiteDLL = 'sqlite3.dll';
{$ELSEIF Defined(DARWIN)}
  SQLiteDLL = 'libsqlite3.dylib';
{$LINKLIB libsqlite3}
{$ELSEIF Defined(UNIX)}
  SQLiteDLL = 'sqlite3.so';
{$IFEND}
 
var
  libsqlite_handle: HMODULE = 0;
  {$IFDEF WIN32}
  libsqlite_mem_handle: PBTMemoryModule = nil;
  {$ENDIF}
  libsqlite_mem_buffer: Pointer;
  libsqlite_in_memory: boolean;
 
.
.
.
 
 
 
procedure libsqlite_fast_load(name: PChar);
begin
  libsqlite_in_memory := False;
  if libsqlite_handle = 0 then // nur neu laden, wenn noch nicht vorhanden...
  begin
    libsqlite_free;
    if name = nil then
      name := SQLiteDLL;
    libsqlite_handle := LoadLibrary(name); // hier passiert im Moment unter Linux rein gar nichts...
    if libsqlite_handle = 0 then
    begin
      internal_libsqlite_status := LIBSQLITE_MISSING;
      showmessage(Format(ELibraryNotFound, [name]));
      Halt;
    end
    else
    begin
      internal_libsqlite_ClientVersion := SQLite3_Version();
      if internal_libsqlite_ClientVersion >= sqlite_not_compatible_version then
      begin
        internal_libsqlite_status := LIBSQLITE_INCOMPATIBLE;
        showmessage(Format(sLibSQLite_Version_Incompatible, [SQLite3_Version]));
        Halt;
      end
      else
        internal_libsqlite_status := LIBSQLITE_READY;
    end;
  end;
end;


Scheint so als ob sqlite3.so im Anwendungsverzeichnis stehen soll.

Über den Wrapper ist noch eine Unit gestülpt, mit der man den eigentlichen Zugriff auf die DB macht. Wenn es einfacher ist, könnte ich also auch diese Unit mit dem verheiraten, was schon bei Lazarus dabei ist. Hat Lazarus denn einen SQLite3-Wrapper oder nur die SQLite3-DB-Kompo?

Habt ihr noch ein paar Tipps, wie ich jetzt vorgehen sollte? Muss ich die Library über ein rpm installieren oder muss ich sie mit den Sourcen selber bauen? Fragen über Fragen...


Grüße,
Uwe

creed steiger
Beiträge: 957
Registriert: Mo 11. Sep 2006, 22:56

Re: SQLite3 auch unter Linux an Programm binden?

Beitrag von creed steiger »

Zuerst: .so rumkopieren ist böse ;)

sqlite3 und sqlite-devel übers Paketmanagment installieren
sqlite3laz Package in Lazarus hinzufügen
(Package-installierte Packages einrichten)
dann sollte das unter Data Access auftauchen
http://wiki.lazarus.freepascal.org/Laza ... und_SQLite

Socke
Lazarusforum e. V.
Beiträge: 3158
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: SQLite3 auch unter Linux an Programm binden?

Beitrag von Socke »

Unter Linux gibt es kein "Anwendungsverzeichnis". Alle Bibliotheken stehen in der Regel allen Programmen zur Verfügung und sind unter /usr/lib/ oder /usr/local/lib/ oder wo anders (Distributionsabhängig) gespeichert.
Du kannst auch die Umgebungsvariable LD_LIBRARY_PATH auf dein "Anwendungsverzeichnis" setzen, dann wird dies auch nach einer passenden Bibliothek durchsucht (ansonsten nicht).

Am Besten ist, wenn du die SQLite-Bibliothek über deine Paketverwaltung installierst; dann kannst du sie auch ganz bequem darüber updaten.

Für die Bibliothek gibt es nur die reine API-Unit und das Dataset. Da ich selber auch lieber mit der API arbeite habe ich mir einen eigenen Wrapper für die Basis-Funktinen geschrieben, der sehr nah an der API bleibt -- nur eben objektorientiert.

Ich finde das schon recht merkwürdig, dass in dem von dir zitierten Quelltext im Fehlerfall eine Meldung an den Benutzer mit ShowMessage() ausgegeben wird. Ich denk eine Exception wäre der besser Weg, da die Unit dann auch für nicht Desktop-Anwendungen genutzt werden könnte. Die vom FPC mitgelieferte sqlite3.pas unterstützt -- soweit ich das dort gelesen habe -- auch das late binding; vielleicht schaust du sie dir mal an.
Dateianhänge
sqlite3obj.pas
OOP-Wrapper für sqlite3
(21.42 KiB) 161-mal heruntergeladen
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Uwe_9988
Beiträge: 30
Registriert: Fr 14. Jan 2011, 11:02

Re: SQLite3 auch unter Linux an Programm binden?

Beitrag von Uwe_9988 »

Hallo zusammen,

dank eurer Hilfe funktioniert jetzt schonmal der "normale" Zugriff.

Ich habe die Sourcen von http://www.sqlite.org heruntergeladen und kompiliert.

Eine Umgebungsvariable LD_LIBRARY_PATH habe ich gar nicht unter CentOS. Ist das normal?

Im Wrapper habe ich dann den Namen der Library von sqlite3.so auf libsqlite3.so geändert und seither funktioniert der Wrapper.

Late binding ist die Syntax mit den Parametern (Fragezeichen und so...) im SQL-String, oder? Das kann die drüberliegende Unit auch. Hänge ich mal dran, falls es jemanden interessiert.

creed steiger hat geschrieben:Zuerst: .so rumkopieren ist böse ;)


Ok, soll man also nicht machen. :D Aber .so ist grundsätzlich nur ein Link auf die echte Library. Seh' ich das richtig?

Und LoadLibrary durchsucht also selber den Librarypfad. Macht die Windowsversion, denke ich, auch.

Mit MySQL wird sich das Thema ja dann wohl ähnlich gestalten.

Es wird ja langsam... ;)


Grüße,
Uwe
Dateianhänge
SQLite3.pas
(42.58 KiB) 159-mal heruntergeladen

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6208
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: SQLite3 auch unter Linux an Programm binden?

Beitrag von af0815 »

Uwe_9988 hat geschrieben:Und LoadLibrary durchsucht also selber den Librarypfad. Macht die Windowsversion, denke ich, auch.

Bei Windows ist meine Erfahrung: Während Laufzeit im Verzeichnis des Programmes, bei der Entwicklung zusätzlich im Pfad von Lazarus. Ist zwar gegen die Meinung mancher Leute (Securityprobleme möglich bei misverwendeten XP), funktioniert bei mir allerdings immer.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

carli
Beiträge: 657
Registriert: Sa 9. Jan 2010, 17:32
OS, Lazarus, FPC: Linux 2.6.x, SVN-Lazarus, FPC 2.4.0-2
CPU-Target: 64Bit

Re: SQLite3 auch unter Linux an Programm binden?

Beitrag von carli »

Hast du schon mal versucht, bei Loadlibrary den globalen Pfad anzugeben?

Uwe_9988
Beiträge: 30
Registriert: Fr 14. Jan 2011, 11:02

Re: SQLite3 auch unter Linux an Programm binden?

Beitrag von Uwe_9988 »

Bei Windows ist meine Erfahrung: Während Laufzeit im Verzeichnis des Programmes, bei der Entwicklung zusätzlich im Pfad von Lazarus.


Also Windows sucht erstmal im aktuellen Pfad und dann noch in den Systemverzeichnissen. Also wenigstens %Windows%\system32. Soweit ich weiß auch in %Windows%\system. Kann man aber in der msdn nachlesen, wenn man's findet. ;)

Edit: Nee falsch. Ich glaube es sucht in allen Verzeichnissen, die in PATH stehen.

Socke
Lazarusforum e. V.
Beiträge: 3158
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: SQLite3 auch unter Linux an Programm binden?

Beitrag von Socke »

Uwe_9988 hat geschrieben:Eine Umgebungsvariable LD_LIBRARY_PATH habe ich gar nicht unter CentOS. Ist das normal?

Code: Alles auswählen

man ld.so

Uwe_9988 hat geschrieben:Ok, soll man also nicht machen. :D Aber .so ist grundsätzlich nur ein Link auf die echte Library. Seh' ich das richtig?

Die .so-Dateien (so = shared object) sind das direkte Äquivalent zu den Windows-dlls (dynamic link library). Oft werden symbolische Links mit verschiedenen Namen auf eine einzige .so-Datei erstellt, damit die Bibliothek unter allen Namen bzw. immer die aktuellste unter dem gleichen Namen verfügbar ist (einfach einmal ls -lA /usr/lib ausführen und die Ausgabe analysieren).
Uwe_9988 hat geschrieben:Late binding ist die Syntax mit den Parametern (Fragezeichen und so...) im SQL-String, oder? Das kann die drüberliegende Unit auch. Hänge ich mal dran, falls es jemanden interessiert.

Es gibt drei Möglichkeiten eine Bibliothek in dein Programm zu linken:
  1. Die Objekt-Dateien (.o) mit ins Programm linken (statisch)
  2. Die Funktionen aus einer Bibliothek (.so/.dll/.dynlib) bei Programmstart linken (dynamisch; early binding)
  3. Die Bibliothek erst über LoadLibrary(), GetProcAddress() laden, wenn sie benötigt wird (dynamisch; late binding)
Das was du meinst

Code: Alles auswählen

SELECT * FROM "mytable" WEHRE "rowa"=?1;
nennt sich prepared statement und hat mit Bibliotheken nur so viel zu tun, als dass die benötigten Funktionen oft in Bibliotheken zu finden sind.
af0815 hat geschrieben:Bei Windows ist meine Erfahrung: Während Laufzeit im Verzeichnis des Programmes, bei der Entwicklung zusätzlich im Pfad von Lazarus.

Das kann man darauf reduzieren: Bibliothek ins Anwendungsverzeichnis, da zur Designtime Lazarus die Anwendung ist. Brauchst du aber nur, wenn du grafische Komponenten hast, die darauf zurückgreifen.
Uwe_9988 hat geschrieben:Mit MySQL wird sich das Thema ja dann wohl ähnlich gestalten.

Wenn du wirklich verschiedene SQL-Datenbanken in einer Anwendung ansprechen möchtest, solltest du auf jeden Fall eine Abstraktionsschicht verwenden, damit du im eigentlichen Programmquelltext nicht immer mit den verschiedenen API-Funktionen hantieren musst. Entweder du erstellst dir eine eigene oder du verwendest ZEOS oder SQLdb (von Lazarus).
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Uwe_9988
Beiträge: 30
Registriert: Fr 14. Jan 2011, 11:02

Re: SQLite3 auch unter Linux an Programm binden?

Beitrag von Uwe_9988 »

Halle Socke,

ah ja, stimmt. Das mit Prep Statements habe ich verwechselt.

Danke für die Erläuterungen. ;)

Das Problem mit dynamischen Bibliotheken ist, dass man nie sicher sein kann, dass die auf dem System vorhandenen zum Programm passen. Das ist bei Windows und Linux ein und dasselbe.

Theoretisch kann man sein Programm natürlich dagegen absichern aber in der Praxis passiert es halt doch immer wieder, dass es beim Aufruf knirscht.

Das ist eigentlich der hauptsächliche Grund, weswegen ich die DDLs unter Windows an die EXE linke. Das funktioniert und die verwendeten DLLs kommen garantiert keiner anderen Anwendung in die Quere. Dass die EXE dann etwas größer ist, stört heutzutage niemanden mehr. ;)

ZEOS sind diese DB-Kompos, oder? Sorry, aber von DB-Komponenten halte ich gar nichts. Sowas mag für einfache DB-Anwendungen ja noch ganz nützlich sein, aber wenn es zeitkritisch wird, sind mir die Teile zu lahm.

Mehrere Datenbanken? Klar, kommt schonmal vor. In der Arbeit verwende ich MySQL, wo es geht aber da gibt es noch 'ne firmenweite Anwendung, die auf Access basiert und auch ein MSSQL-Server läuft für ein paar Anwendungen. Das Büro verwendet sehr viel "exotische" Software und da passiert es immer mal wieder, dass man ein Auswertungsprogramm oder irgendwelche Konverter schreiben muss.

Kürzlich habe ich ein dafür geeignetes Projekt mit SQLite3 realisiert. Hatte was mit Multithreading zu tun und hat sehr gut mit SQLite3 funktioniert. Fand ich sehr praktisch und schnell und deshalb werde ich wohl künftig zumindest Configsachen oder temporäre Tabellen in einer SQLite-DB ablegen. Habe aber auch mit riesigen Textdateien zu tun, die man auch mit SQLite besser durchsuchen könnte.

Glaube aber kaum, dass ich solche Anwendungen auf Linux portieren muss. :mrgreen: Konverter aber mit Sicherheit.
Dabei geht es zum Beispiel darum Ausgabedaten eines Simulationsprogramms in Textform umzuformen/umzurechnen und ein anderes Programm damit zu füttern. Perfekt für SQLite3 geeignet.

Ist jetzt aber eigentlich ein bissel OT. ;)

Fazit: Würde man eine .so unter Linux als Ressource an ein Lazarusprogramm binden und für eine entsprechende LoadLibrary-Funktion sorgen, wäre der gleiche Mechanismus möglich, wie ich ihn schon für Win32 habe. :)

Grüße,
Uwe

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6208
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: SQLite3 auch unter Linux an Programm binden?

Beitrag von af0815 »

Uwe_9988 hat geschrieben:Fazit: Würde man eine .so unter Linux als Ressource an ein Lazarusprogramm binden und für eine entsprechende LoadLibrary-Funktion sorgen, wäre der gleiche Mechanismus möglich, wie ich ihn schon für Win32 habe. :)

Ich würde es weder unter Windows, noch unter Linux IN die exe einbinden. Je nach BS mit dem Installer mitzubinden oder als required beim Installer einkonfigurieren. Was auch noch hilft, ist den Benutzer mit der richtigen Information versorgen wenn etwas nicht geht, fehlt oder die falsche Version ist.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Antworten