AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Projekte TSQLiteDatabase: A SQLite3 Database Wrapper
Thema durchsuchen
Ansicht
Themen-Optionen

TSQLiteDatabase: A SQLite3 Database Wrapper

Ein Thema von HalloDu · begonnen am 17. Sep 2009 · letzter Beitrag vom 11. Nov 2016
Antwort Antwort
Seite 1 von 3  1 23      
HalloDu
Registriert seit: 24. Apr 2006
TSQLiteDatabase: A SQLite3 Database Wrapper
Kompatible SQLite3 Version: 3.6.16
TSQLiteDatabase ist ein nahezu vollständiger OOP-Wrapper um die SQLite3.dll. Er wurde erstellt da ich für eine Anwendung in Delphi 2009 ein kleine, freie Datenbank brauchte nd ich mich für SQLite entschieden hatte. Da ich aber für den Zugriff eine kleine, schlanke Klasse brauchte und mir die im Internet gefundenen Lösungen nicht gefallen haben, habe ich kurzerhand selbst einen Wrapper geschrieben. Zur Nutzung wird die SQLite3.dll benötigt

Features
Verbinden mit einer SQLite3 kompatiblen Datenbank
Ausführen von SQL-Statments
Bindings in den Statments
Erzeugen von Collations, Aggregaten und Funktionen
Fortschrittsereignis bei längeren Prozessen
Autorisieren von bestimmten SQL-Aktionen
Blob-Zugriff als Stream
Weiterarbeiten mit SQLite-internen Werten
Limits setzen
In Delphi 2009: Unicode
NoVCL kompatibel

Beispiele zur Benutzung
Zur Datenbank verbinden und ein "INSERT" ausführen
Delphi-Quellcode:
var DB: TSQLiteDatabase;
begin
  DB := TSQLiteDatabase.Create('test.db');
  DB.Execute('INSERT INTO TEST (TEST) VALUES ("TEST");');
  DB.Free;
end;
Ein "INSERT" mit Binding
Delphi-Quellcode:
var DB: TSQLiteDatabase;
    Command: TSQLiteCommand;
begin
  DB := TSQLiteDatabase.Create('test.db');
  Command := DB.Command('INSERT INTO TEST (TEST) VALUES (?);');
  Command.Binding[1].AsString := 'Test';
  Command.Execute;
  Command.Free;
  DB.Free;
end.
Auflisten der Daten einer Tabelle
Delphi-Quellcode:
var DB: TSQLiteDatabase;
    Query: TSQLiteQuery;
begin
  DB := TSQLiteDatabase.Create('test.db');
  Query := DB.Query('SELECT * FROM TEST');
  while Query.Next do
    begin
      WriteLn(Query[0].AsString);
    end;
  Query.Free;
  DB.Free;
end.
Beispiel mit vielen "INSERT"s
Delphi-Quellcode:
var DB: TSQLiteDatabase;
    Command: TSQLiteCommand;
begin
  DB := TSQLiteDatabase.Create('test.db');
  DB.Execute('BEGIN TRANSACTION'); // Damit nicht so viele Festplattenzugriffe gemacht werden müssen
  Command := DB.Command('INSERT INTO TEST (TEST) VALUES (?);');
  For I := 1 to 200 do
    begin
      Command.Reset;
      Command.Binding[1].AsString := 'Test'+IntToStr(I);
      Command.Execute;
    end;
  Command.Free;
  DB.Execute('END TRANSACTION');
  DB.Free;
end.
Getestet mit...
Delphi 2009 größtenteils, da ich es im Moment in einem Projekt einsetze
Delphi 7 rudimentär

SVN: svn://delphidev.net/public/SQLiteDatabase

Wäre klasse, wenn sich das wer von euch mal ansehen oder sogar ein bisschen testen könnte
Angehängte Dateien
Dateityp: zip sqlitedatabase_573.zip (48,1 KB, 363x aufgerufen)
 
Benutzerbild von xZise
xZise

 
Delphi 2009 Professional
 
#2
  Alt 17. Sep 2009, 20:05
Moin,
also es gibt ja den "Simple SQLite Wrapper for Delphi". Und was mich da stört ist, dass Objekte zurückgegeben werden. Stattdessen (finde ich), sollten Objekte immer übergeben werden:
Delphi-Quellcode:
type
  TA = class;
  TB = class
  public
    procedure Query(A : TA);
  end;

var
  A : TA;
  B : TB;
begin
  A := TA.Create;
  B := TB.Create;
  try
    TB.Query(A);
  finally
    A.Free;
    B.Free;
  end;
end.
Außerdem vermisse ich das man nachträglich eine/die Datenbank lädt. Zum Beispiel, wenn man die Klasse in einer Klasse kapselt und man erst nachträglich die Datenbank laden will, aber die Klasse halt vorher erstellt, dann ist das immer relativ unschön.

Und was ich auch noch implementieren musste ist eine Möglichkeit Werte zu verschlüsseln und zu entschlüsseln. Übrigens (ich habe es mir nicht angeguckt ehrlich gesagt) wie gehst du mit Strings um? Weil der Simple Wrapper der speichert das als "Binary" sozusagen als Input, statt UTF8/UTF16 zu nehmen (also Input in UTF8 umwandeln und dann UTF8 rausholen und in Ansi-/Unicodestring beim auslesen umwandeln.

Und wie verhält es sich mit verschiedenen Datentypen pro Zelle? Weil in der Dokumentation steht so weit ich weiß, dass die Werte pro Zelle selbst innerhalb einer Spalte verschiedenen sein können/dürfen.

Und auch eine ganz wichtige Frage: Und zwar sind bei dir alle Aufrufe mit UTF8/UTF16? Weil die andere Implementation übergibt einen AnsiString statt einen UTF8String Das macht natürlich Probleme mit dem Auslesen.

MfG
xZise
Fabian
  Mit Zitat antworten Zitat
HalloDu

 
Delphi 2009 Professional
 
#3
  Alt 17. Sep 2009, 20:11
Naja, wer möchte kann sich seine TSQLiteQuery und TSQLiteCommand auch selbst instanzieren.

Ja, die Sache mit dem AnsiString ist tatsächlich noch zu überarbeiten, hatte aber im Moment nicht absolute Priorität, da ich in Delphi 2009 damit keine Probleme hatte.

Ganz abgesehen davon, das die ganze Geschichte auch keine schlechte Übung war und zu viel Verständnis für SQLite geführt hat.
Frederic H.
  Mit Zitat antworten Zitat
Benutzerbild von xZise
xZise

 
Delphi 2009 Professional
 
#4
  Alt 17. Sep 2009, 20:15
Zitat von HalloDu:
Naja, wer möchte kann sich seine TSQLiteQuery und TSQLiteCommand auch selbst instanzieren.[...]
Und dann? Du sagst doch "Result := <Klasse>.Create(...)" in "TSQLiteDatabase.Command". Und tada ein Speicherleck

Ich sage natürlich nicht das deine Arbeit schlecht war ^^ aber genau diese Dinge habe im Simple SQLite Wrapper vermisst Und ich finde eigentlich gehört sich sowas wie in TSQLiteDatabase.Command nicht, aber das ist natürlich Geschmackssache.

Und ich bin eigentlich daran in gewisser weise interessiert.

MfG
xZise
Fabian
  Mit Zitat antworten Zitat
HalloDu

 
Delphi 2009 Professional
 
#5
  Alt 17. Sep 2009, 20:45
Mal sehen, ob ich am Wochende dazu komme das umzusetzen. Im Übrigen ist Kritik natürlich immer erwünscht. Die macht das Endprodukt ja nur besser.
Frederic H.
  Mit Zitat antworten Zitat
Elvis

 
Delphi 2010 Professional
 
#6
  Alt 17. Sep 2009, 22:58
Würdest du in den Factories (DB.Create, ...) Interfaces zurückgeben, gäbe es gar kein Problem.
Die werden durch Referenzzählung autom. freigeben. Dadurch sieht der Code nicht so grausam aus mit all den verschachtelten try-finally-Blöcken, die Delphi sonst so braucht. (kotz!)

Deine normalen Klassen (Command etc) würden diese Interfaces implementieren und alles wäre in Butter.
Robert Giesecke
  Mit Zitat antworten Zitat
Benutzerbild von Mithrandir
Mithrandir
 
#7
  Alt 29. Sep 2009, 16:14
Sowas habe ich gesucht, super!

*gleich mal testen*

Nachtrag: Hmm... Wäre eigentlich ganz praktisch, wenn mir die Klasse n Feedback geben würde, ob die DB-Datei schon existiert oder nicht
米斯蘭迪爾
  Mit Zitat antworten Zitat
Benutzerbild von Mithrandir
Mithrandir
 
#8
  Alt 2. Okt 2009, 09:44


Das Dingens gefällt mir mittlerweile richtig gut, die Bedienung ist simpel und einfach, und dank nonVCL-Fähigkeiten auch für solche Programme geeignet. Dennoch ist mir die Geschwindigkeit negativ aufgefallen. Folgendes Konstrukt:

Delphi-Quellcode:
  procedure TDatabase.AddFile(FileSpecs: TFileSpecs);
  var
    FileCmd: TSQLiteCommand;
  begin
    FileCmd := fDB.Command('INSERT INTO FILES (FILE_PATH, FILE_EXT, FILE_TITLE, FILE_ARTIST, FILE_ALBUM, FILE_YEAR, FILE_GENRE, FILE_LENGTH) ' +
                        'VALUES ( ? , ? , ? , ? , ? , ? , ? , ? );');
    FileCmd.Binding[1].AsString := FileSpecs.fFilePath;
    FileCmd.Binding[2].AsString := FileSpecs.fFileExtType;
    FileCmd.Binding[3].AsString := FileSpecs.fTitle;
    FileCmd.Binding[4].AsString := FileSpecs.fArtist;
    FileCmd.Binding[5].AsString := FileSpecs.fAlbum;
    FileCmd.Binding[6].AsString := FileSpecs.fYear;
    FileCmd.Binding[7].AsString := FileSpecs.fGenre;
    FileCmd.Binding[8].AsInteger := FileSpecs.fLength;
    FileCmd.Execute;
    FileCmd.Free;
  end;
~100 Einträge hinzuzufügen dauert fast 10 Sekunden, imho zu langsam. Ich habe schon, wie von Zeos gewohnt, das Erstellen das Objekts "FileCmd" ausgelagert, und nur noch den Teil mit "FileCmd.Binding[n].AsXYZ" sowie den Execute-Teil drin gelassen. Dann rennt er da zwar durch, aber fügt auch nichts zur DB hinzu. Mache ich irgendwas falsch?
米斯蘭迪爾
  Mit Zitat antworten Zitat
HalloDu

 
Delphi 2009 Professional
 
#9
  Alt 6. Okt 2009, 21:42
Ich muss mich der ganzen Kiste mal über nächstes Wochenende annehmen. Im Moment habe ich leider keine Zeit mich mit dem Problem näher zu beschäftigen. Es freut mich aber das es dir gefällt.

PS: Auch die Sache mit den Interfaces werde ich mir dann mal ansehen.
Frederic H.
  Mit Zitat antworten Zitat
Benutzerbild von Mithrandir
Mithrandir
 
#10
  Alt 6. Okt 2009, 21:49
Ok, cool.
米斯蘭迪爾
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:48 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