Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Hilfe zu Synopse SQLite3 (https://www.delphipraxis.net/151390-hilfe-zu-synopse-sqlite3.html)

AnCorr 15. Mai 2010 23:52

Datenbank: SQLite3 • Version: 3.6 • Zugriff über: Synopse SQLite3 Framework

Hilfe zu Synopse SQLite3
 
Hallo zusammen

Leider hat mir die Suchfunktion zu 'Synopse SQLite3' keine Treffer angezeigt. Deshalb wende ich mich jetzt an euch.

Das Framework scheint ja sehr interessant zu sein, leider gibt es keine Dokumentation dazu und die Beispiele sind alles andere als 'brauchbar'. Der Blog dazu gibt auch gar nichts her. Das Framework ist fuer mich deshalb interessant, da man damit ohne die sonst verwendete externe sqlite3.dll auskommt.

Worum geht's?
Ich habe eine kleine SQLite3 Datenbank mit einigen Tabellen. Nun moechte ich aus einer der Tabellen bestimmte Datensaetze auslesen.
Der SQL Befehl wuerde dann z. B. so lauten: "Select * From Mp3Record Where Genre = 'Asian Music'"
Als Ergebnis muesste dann ein oder mehrere Records zurueckkommen (sofern entsprechende Datensaetze gefunden werden).

Kennt jemand von euch das Framework? Weiss jemand, wie ich das realisieren kann?

Vom Autor des Frameworks bekam ich folgende Antwort(leider etwas abwertent auf meine Anfrage hin):

Zitat:

For such low level SQLite3 work, take a look at TSQLRequest.Execute methods, and see how to loop through all rows.

Delphi-Quellcode:
var
  R: TSQLRequest;
  value: Int64;
  res: integer;
begin
  try
    R.Prepare(aDB,'Select * From Mp3Table Where Genre=''Asian Music'';'); // note the '' double quotes inside the ' string '
    repeat
      res := R.Step;
      if res=SQLITE_ROW then
      begin // we got some data
        value := sqlite3_column_int64(R.Request,0);
        // use other low level functions to get your data
      end;
    until res=SQLITE_DONE;
  finally
    R.Close; // always release statement
  end;
end;
With the framework, you should better create a TSQLRecord descendant class with the appropriate fields corresponding to your database, then use a Client/Server approach as shown in the supplied samples.
Das grosse Problem fuer mich hier ist die Variable 'aDB'. Laut Funktion in der Datei SQLite3.pas muss 'aDB' vom Typ TSQLHandle sein.
Leider habe ich damit noch nie etwas zu tun gehabt. Was ist denn ein TSQLHandle?
In der Datei SQLite3.pas ist der Typ so deklariert:

/// internaly store the SQLite3 database handle
TSQLHandle = type cardinal;

Wie definiere ich in meinem Programm 'aDB' (oder auch einen anderen Namen) so, dass sie als TSQLHandle verwendet wird?
Wo stelle ich die Beziehung zu meiner Datenbankdatei her?


Waere schoen, wenn mir jemand helfen koennte.
Danke schon im voraus!

Gruss
AnCorr

Luckie 16. Mai 2010 00:45

Re: Hilfe zu Synopse SQLite3
 
Beim Herstellen der Verbindung zur Datenbank, wirst du wohl irgendwo ein Handle zurückbekommen. Und ich denke mal, das wird dann an dieser Stelle gebraucht.

Aber wo ist die Antwort abwertend? Du hast sogar kompletten Quellcode für dein Problem bekommen.

H4ndy 16. Mai 2010 02:41

Re: Hilfe zu Synopse SQLite3
 
Das DB-Handle referenziert deine Datenbank-"Verbindung".
Einfach global (unsauber aber schnell) eine Variable deklarieren vom Typ TSQLHandle und dann der Funktion uebergeben.
Das Handle wird wahrscheinlich dann fuer weitere Operationen auf der Datenbank oder zumindest zum schliessen der Verbindung benoetigt.
(allgemeine Antwort, ich hab kein Wissen zu SQLLite oder diesem Framework)

mschaefer 16. Mai 2010 09:24

Re: Hilfe zu Synopse SQLite3
 
Da ist nichts abwertend: Das 'low level' bezieht sich auf die untere Zugriffsebene ohne Komponenten und ist hier als sachliche Codeeinordnung zu sehen . . .

AnCorr 16. Mai 2010 11:10

Re: Hilfe zu Synopse SQLite3
 
Hallo

Erst mal Danke fuer die schnellen Antworten.
O.k., wahrscheinlich habe ich das 'For such low level' etwas zu persoenlich genommen. :-)
Ich assoziierte das 'such low level' mit 'solch einfachen' - sprich, wie kannst Du nur solche Fragen stellen. :-D

Nun aber zum Problem.
Ich weiss noch immer nicht, wie ich die Verbindung von Datenbank zum Handle herstelle.

Wenn ich mit dem Framework eine Datenbank erstelle, dann geht das z. B. folgendermassen:
Delphi-Quellcode:
Database: TSQLRest; // Database object Synopse SQLite3 
Mp3Model: TSQLModel; // 'Model' for database
Mp3Model := CreateMp3Model;
Database := TSQLRestServerDB.Create(Mp3Model, MediaPath);
Das 'Model' ist eine Unit, welches einen Record und ein paar Methoden zur Verfuegung stellt.
'MediaPath' ist der Pfad inkl. Dateiname zur Datenbank. Z. B.: G:\Data\Media\Media.db3

In der Funktion
Delphi-Quellcode:
  R.Prepare(aDB,'Select * From Mp3Table Where Genre=''Asian Music'';');
kann ich 'aDB' nicht durch Database ersetzen, da hier ja das Handle erwartet wird. Ich hatte auch schon versucht den Aufruf so zu gestallten:
Delphi-Quellcode:
  R.Prepare([Database], 'Select * From Mp3Table Where Genre=''Asian Music'';');
Aber das hat natuerlich auch nicht funktioniert.

Vielleicht findet sich ja noch jemand, der mir hier weiter helfen kann.

Gruss
AnCorr

H4ndy 16. Mai 2010 15:41

Re: Hilfe zu Synopse SQLite3
 
Zitat:

Zitat von AnCorr
In der Funktion
Delphi-Quellcode:
  R.Prepare(aDB,'Select * From Mp3Table Where Genre=''Asian Music'';');
kann ich 'aDB' nicht durch Database ersetzen, da hier ja das Handle erwartet wird. Ich hatte auch schon versucht den Aufruf so zu gestallten:
Delphi-Quellcode:
  R.Prepare([Database], 'Select * From Mp3Table Where Genre=''Asian Music'';');

Du hast dir deine Frage doch schon selbst beantwortet - du brauchst einfach nur eine Variable vom Typ TSQLHandle, ist doch nicht schwer ^^

Delphi-Quellcode:
var
  DatabaseHandle: TSQLHandle; // global
...
begin
  R.Prepare(DatabaseHandle, 'Select * From Mp3Table Where Genre=''Asian Music'';');
Und immer wenn nach einem TSQLHandle gefragt wird, gibst du DatabaseHandle rein.
Ein Handle ist nix weiter als eine Referenz oder ein Pointer. Du musst da nix selbst reinschreiben, da uebernimmt das Framework fuer dich.
Es muss diesen Wert nur wahrscheinlich nach aussen geben, damit intern nicht irgendwas komisch gespeichert werden muss.

AnCorr 16. Mai 2010 17:34

Re: Hilfe zu Synopse SQLite3
 
Hallo H4ndy

Na ja, ganz so einfach scheint es wohl nicht zu sein.
Ich habe nun ein TSQLHandle deklariert wie Du es angegeben hast.
Danach habe ich der Funktion 'Prepare' das Handle uebergeben.

Ich erhalte dann folgenden Laufzeitfehler:
Invalid SQLite3 database handle (14)

Ich frage mich immer noch, wie die 'Beziehung' (Assoziation) vom Handle auf die eigentliche Datenbank erfolgen soll. Letztendlich muss doch irgendwo klar sein, auf welche Datenbank die verschiedenen Funktionen zugreifen muessen.

Gruss
AnCorr

mkinzler 16. Mai 2010 17:38

Re: Hilfe zu Synopse SQLite3
 
Das Handle sollte bei der Verbindung zur DB erzeugt und zurückgegeben werden

AnCorr 16. Mai 2010 18:11

Re: Hilfe zu Synopse SQLite3
 
Hallo mkinzler

Zum Erstellen der Datenbank lautet der Befehl:
Delphi-Quellcode:
Database := TSQLRestServerDB.Create(Mp3Model, MediaPath);
Da wird leider keine Handle zurueckgegeben.

Ich habe mir die komplette SQLite3.pas durchgesehen. Es gibt dort auch keine Funktion (ausser 'function TSQLRequest.FieldValue(Col: integer): TSQLHandle;'), welche ein TSQLHandle zurueckgibt.
Es gibt auch keine 'Bind' oder 'Open' Funktion, die mich hier weiterbringen wuerde.

Gruss
AnCorr

Luckie 16. Mai 2010 21:38

Re: Hilfe zu Synopse SQLite3
 
Zitat:

Zitat von AnCorr
Hallo mkinzler

Zum Erstellen der Datenbank lautet der Befehl:
Delphi-Quellcode:
Database := TSQLRestServerDB.Create(Mp3Model, MediaPath);
Da wird leider keine Handle zurueckgegeben.

Und was macht dich so sicher, dass der Rückgabewert des Konstruktors nicht das benötigte Handle ist? Hast du mal versucht die Variable Database als Handle einzusetzen? Mach das doch einfach mal.

AnCorr 16. Mai 2010 21:59

Re: Hilfe zu Synopse SQLite3
 
Hallo Luckie

Ja, das habe ich schon probiert.
Da erhalte ich schon von der IDE die Fehlermeldung, dass die Typen TSQLRest (das ist die Datenbank - Database) und TSQLHandle (das wird von der Funktion erwartet) inkompatibel sind.

Gruss
AnCorr

Luckie 16. Mai 2010 22:12

Re: Hilfe zu Synopse SQLite3
 
Aber TSQLRestServerDB.Create klingt auch nicht, als ob man damit eine Verbindung zur Datenbank aufbauen würde. Du musst doch irgendwo eine Connect-Methode haben. Zeige doch mal deinen ganzen Code.

AnCorr 16. Mai 2010 22:37

Re: Hilfe zu Synopse SQLite3
 
Liste der Anhänge anzeigen (Anzahl: 2)
Hallo Luckie

Bisher habe ich mit dem Framework nur eine Datenbank erstellt.
Das war auch nicht so schwer, da es hier zum Glueck ein paar kleine Beispiele gab.
Allerdings haben die Beispiele maximal einen Datensatz ausgelesen. Das ist auch nicht so schwer.
Moechte man aber einen etwas 'komplexeren' SQL Befehl absetzen, dann wird es 'etwas' komplizierter. Und hierzu gibt es keinerlei Beispiele etc.

Den ganzen Code hier einzubringen, waere etwas zu umfangreich, da allein die 'Hauptunit' etwa 3600 Zeilen hat.
Ich haenge mal die SQLite3.pas und SQLite3Commons.pas aus dem Framework an. Ueber diese soll ja alles laufen. Das Framework besteht noch aus viel mehr 'Teilen', aber davon benoetige ich fuer meine Zwecke nur diese beiden.
Das Erstellen einer Datenbank laeuft etwa so ab:

Delphi-Quellcode:
var
  Database: TSQLRest; // Database object Synopse SQLite3
  Mp3Model: TSQLModel; // 'Model' for database
begin
  Mp3Model := CreateMp3Model;
  Database := TSQLRestServerDB.Create(Mp3Model, MediaPath);
  TSQLRestServerDB(Database).CreateMissingTables;
  ...
  //Hinzufuegen von Daten in die Datenbank
  ...
  Database.Free;
  Mp3Model.Free;
end;
Da ich das Einlesen bisher mit dem Framework nicht hinbekommen habe, habe ich hierzu einen Wrapper fuer die sqlite3.dll genutzt.
Da ich aber auch weiss, dass es mit dem Framework auch geht (gehen muss), moechte und koennte ich somit auf die sqlite3.dll verzichten. Deshalb habe ich dieses Thema hier erstellt.


Gruss
Micha

mkinzler 17. Mai 2010 08:10

Re: Hilfe zu Synopse SQLite3
 
Auf die Dll wirst du wohl nicht verzichten könne, da sie auch das eigentliche "DBMS" enthält.
Gibt es kein Beispiel des Herstellers des Framworks?

AnCorr 17. Mai 2010 11:36

Re: Hilfe zu Synopse SQLite3
 
Hallo mkinzler

Doch, die DLL wird nicht benoetigt, wenn man das Framework einsetzt. Das Framework ist vollstaendig in Delphi geschrieben, und hat den gleichen (oder groesseren) Umfang wie die DLL.

Die verfuegbaren Beispiele sind fuer 'meine Belange' leider nicht brauchbar, da sie nur die 'einfachsten' Funktionen zeigen.
Mittlerweile bin ich mit dem Autor des Frameworks in Kontakt. Leider hat er es bisher nicht geschafft, mir mal ein passendes und funktionierendes Beispiel zu liefern.
Mal sehen, vielleicht klappt's ja noch. :-)

Gruss
AnCorr

AnCorr 17. Mai 2010 22:41

Re: Hilfe zu Synopse SQLite3
 
Hallo zusammen

Ich habe mein Problem nun endlich zusammen mit dem Entwickler des Frameworks loesen koennen.
Der Thread kann somit geschlossen werden.

Vielen Dank fuer die rege Teilnahme und den Versuchen mir zu helfen.
Mit dem gewonnenen Wissen kann ich nun auf den Einsatz der 'sqlite3.dll' verzichten.

Sollte sich jemand dafuer interessieren, hier ist der Link dazu:
Synopse SQLite3 Framework

Vielleicht kann ich ja dann dem einen oder anderen auch einmal helfen.


Gruss
AnCorr

Hier ein kleines Testprogramm:
Delphi-Quellcode:
unit Main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Mp3Data, SQLite3Commons, SQLite3;

type
  TMainform = class(TForm)
    Ed_DBPath: TEdit;
    Btn_Open: TButton;
    Btn_List: TButton;
    Odlg_DB: TOpenDialog;
    Lb_Result: TListBox;
    procedure Btn_ListClick(Sender: TObject);
    procedure Btn_OpenClick(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Mainform: TMainform;

   MediaPath: String;
 
implementation

{$R *.dfm}

procedure TMainform.Btn_OpenClick(Sender: TObject);
begin
   if Odlg_DB.Execute then
  begin
    if Odlg_DB.FileName <> '' then
    begin
       MediaPath := Odlg_DB.FileName;
      Ed_DBPath.Text := MediaPath;
    end;
  end;
end;

procedure TMainform.Btn_ListClick(Sender: TObject);
var
  Client: TSQLRestClient;
  Table: TSQLTable;
  Mp3Model: TSQLModel; // 'Model' for database
  Mp3Record: TSQLMp3Record; // Record for database

begin
  if MediaPath <> '' then
  begin
    Mp3Model := TSQLModel.Create([TSQLMp3Record], 'root');
    Mp3Record := TSQLMp3Record.Create;
    Client := TSQLRestClientDB.Create(Mp3Model, MediaPath);
    Table := Client.List([TSQLMp3Record], '*', 'Genre = "Asian Music"');
    if Table <> nil then // = nil on any error
    try
      Mp3Record.FillPrepare(Table);
      while Mp3Record.FillOne do
      begin
        Lb_Result.Items.Add(Mp3Record.Title);
      end;
    finally
      Table.Free;
    end;

    Mp3Model.Free;
    Mp3Record.Free;
  end;
end;

end.
Die Unit 'Mp3Data' definiert einen Record und eine Funktion zum Erzeugen.
Delphi-Quellcode:
unit Mp3Data;

interface

uses
  SQLite3Commons;

type

  TSQLMp3Record = class(TSQLRecord)
  private
    fPath: RawUTF8;
    fFilename: RawUTF8;
    fTitle: RawUTF8;
    fArtist: RawUTF8;
    fAlbum: RawUTF8;
    fGenre: RawUTF8;
    fTrack: RawUTF8;
    fYear: RawUTF8;
    fBitrate: RawUTF8;
    fSampleRate: RawUTF8;
    fDuration: RawUTF8;

  published
    property Path: RawUTF8 read fPath write fPath;
    property Filename: RawUTF8 read fFilename write fFilename;
    property Title: RawUTF8 read fTitle write fTitle;
    property Artist: RawUTF8 read fArtist write fArtist;
    property Album: RawUTF8 read fAlbum write fAlbum;
    property Genre: RawUTF8 read fGenre write fGenre;
    property Track: RawUTF8 read fTrack write fTrack;
    property Year: RawUTF8 read fYear write fYear;
    property Bitrate: RawUTF8 read fBitrate write fBitrate;
    property SampleRate: RawUTF8 read fSampleRate write fSampleRate;
    property Duration: RawUTF8 read fDuration write fDuration;
  end;

function CreateMp3Model: TSQLModel;

implementation

function CreateMp3Model: TSQLModel;
begin
  Result := TSQLModel.Create([TSQLMp3Record]);
end;

end.
Aus dem Framework werden fuer das kleine Programm nur folgende Dateien benoetigt:
sqlite3.obj
sqlite3.pas
sqlite3commons.pas
sqlite3fts3.obj


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:07 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz