Files in eine SQLite und MySQL datenbank ablegen?

Für Themen zu Datenbanken und Zugriff auf diese. Auch für Datenbankkomponenten.
TT73GP7
Beiträge: 238
Registriert: Di 29. Mär 2016, 20:45

Files in eine SQLite und MySQL datenbank ablegen?

Beitrag von TT73GP7 »

Hallo zusammen,

ja ich weiß es macht überhaupt keinen sinn.
aber ich bin grade soein bissel in spiel trieb

kann ich PDF's und Bilder, Word Datei und anderen Datenschrott eigentlich direkt in eine Datenbank speichern?
ich weiß das es bei Bildern geht
aber bei PDF Dateien?


wenn ja wie geht das genau?
habt ihr Beispiele?

kann man das auch in eine SQLite Datenbank speichern?

Viele Grüße
:)

relocate
Beiträge: 61
Registriert: Di 24. Jan 2012, 11:47
OS, Lazarus, FPC: Win (L- FPC 2.4.4 + 2.6.4)
CPU-Target: 32Bit

Re: Files in eine SQLite und MySQL datenbank ablegen?

Beitrag von relocate »

Würde ich die Dinge so wie alle anderen machen, hätte ich so manche Probleme nicht.

Aber das wäre langweilig.

TT73GP7
Beiträge: 238
Registriert: Di 29. Mär 2016, 20:45

Re: Files in eine SQLite und MySQL datenbank ablegen?

Beitrag von TT73GP7 »

hmm und wie bekomme ich dann die Dateien da rein?

wenn ich z.b. ein file habe

cPfad := 'c:\test.pdf'


und wie kann ich daraus wieder ein File machen?

mit Select * From Tabelle wird es ja nicht :D

MacWomble
Lazarusforum e. V.
Beiträge: 999
Registriert: Do 17. Apr 2008, 01:59
OS, Lazarus, FPC: Mint 21.1 Cinnamon / FPC 3.2.2/Lazarus 2.2.4
CPU-Target: Intel i7-10750 64Bit
Wohnort: Freiburg

Re: Files in eine SQLite und MySQL datenbank ablegen?

Beitrag von MacWomble »

ganz so einfach geht das auch nicht, so wird nur der Pfad, nicht die Datei gespeichert,

Schau mal z.B. hier;
http://forum.lazarus.freepascal.org/ind ... pic=7890.0
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.

TT73GP7
Beiträge: 238
Registriert: Di 29. Mär 2016, 20:45

Re: Files in eine SQLite und MySQL datenbank ablegen?

Beitrag von TT73GP7 »

jap genau das war ja mein Stolperstein ;)

na gut so speichert man schonmal JPG
die kann man ja auch mit dem DBImage anzeigen lassen

aber wenn ich jetzt eine beliebige Datei speichern will?
gibt es da eine alternative für das Jpg: TJpegImage; ?

ach und ich habe so gesehen sogar einen sinn für das Thema bei mir gefunden

wenn bei uns eine Prüfung aufgemacht wird
fallen viele Dokumente an

diese können ideal in einer sqlite Datei abgelegt werden und dann muss nur noch die sqlite abgelegt / verschickt werden :D
wie soeine art Projekt Mappe

MacWomble
Lazarusforum e. V.
Beiträge: 999
Registriert: Do 17. Apr 2008, 01:59
OS, Lazarus, FPC: Mint 21.1 Cinnamon / FPC 3.2.2/Lazarus 2.2.4
CPU-Target: Intel i7-10750 64Bit
Wohnort: Freiburg

Re: Files in eine SQLite und MySQL datenbank ablegen?

Beitrag von MacWomble »

Die anderen Dateien sind ja wahrscheinlich nicht geeignet, direkt in der Anwendung angezeigt zu werden. Hierfür gibt es folglich auch kein Control wie tjpegimage.
Sinnvoll ist es hier, die Datei (z.B. temporär) wieder anzulegen und dann mit dem passenden Programm öffnen zu lassen.
Google doch mal selbst nach 'Dateien in Blob schreiben und lesen mit lazarus'
Es gibt einige Beispiele zu Streams (darum geht es nämlich), analog sind auch die Delphi-Beispiele nutzbar.
Alle sagten, dass es unmöglich sei - bis einer kam und es einfach gemacht hat.

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

Re: Files in eine SQLite und MySQL datenbank ablegen?

Beitrag von wp_xyz »

Im Anhang findest du eine kleine Anwendung, wie du beliebige Dateien als BLOB in der Datenbank speicherst: Nach dem ersten Start des Programms wird eine leere SQLite3-Datenbank erzeugt, mit zwei Feldern für den Dateinamen (String) und den Dateiinhalt (BLOB). Wähle eine Datei aus (oder nimm die vorschlagene exe-Datei des Programms) und klicke auf "In DB schreiben". Damit die Datei in das Blob-Feld eingelesen und in die DB geschrieben. Zur Kontrolle erscheint der Dateiname im DBGrid. Klickst du jetzt auf "Markierte Datei lesen und speichern" wird das BlobFeld des im Grid aktuell markierten Record ausgelesen und in eine Datei geschrieben. Zur Unterscheidung mit der ursprünglichen Datei wird an den Hauptdateinamen (vor der Endung) ein "x" angehängt. Zur Kontrolle kannst du diese Datei im Betriebssystem öffnen.

So weit so gut. Allerdings ist es meistens gar nicht günstig, große Objekte wie Dateien direkt in der DB zu speichern, weil damit sämtliche Caching-Mechanismen des DB-Systems überlaufen.
Dateianhänge
sqlite3_blobfield.zip
(2.91 KiB) 211-mal heruntergeladen

MmVisual
Beiträge: 1445
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
CPU-Target: 32/64Bit

Re: Files in eine SQLite und MySQL datenbank ablegen?

Beitrag von MmVisual »

TBlobField(DeineQuery.FieldByName('BlobFeldMitDateiDaten')).LoadFromStream(IrgendEinStream);
EleLa - Elektronik Lagerverwaltung - www.elela.de

TT73GP7
Beiträge: 238
Registriert: Di 29. Mär 2016, 20:45

Re: Files in eine SQLite und MySQL datenbank ablegen?

Beitrag von TT73GP7 »

wp_xyz hat geschrieben:Im Anhang findest du eine kleine Anwendung, wie du beliebige Dateien als BLOB in der Datenbank speicherst: Nach dem ersten Start des Programms wird eine leere SQLite3-Datenbank erzeugt, mit zwei Feldern für den Dateinamen (String) und den Dateiinhalt (BLOB). Wähle eine Datei aus (oder nimm die vorschlagene exe-Datei des Programms) und klicke auf "In DB schreiben". Damit die Datei in das Blob-Feld eingelesen und in die DB geschrieben. Zur Kontrolle erscheint der Dateiname im DBGrid. Klickst du jetzt auf "Markierte Datei lesen und speichern" wird das BlobFeld des im Grid aktuell markierten Record ausgelesen und in eine Datei geschrieben. Zur Unterscheidung mit der ursprünglichen Datei wird an den Hauptdateinamen (vor der Endung) ein "x" angehängt. Zur Kontrolle kannst du diese Datei im Betriebssystem öffnen.

So weit so gut. Allerdings ist es meistens gar nicht günstig, große Objekte wie Dateien direkt in der DB zu speichern, weil damit sämtliche Caching-Mechanismen des DB-Systems überlaufen.



hallo zusammen :)

also die Lösung klappt wunderbar. Ich habe das mal nee Zeitlang laufen lassen um aus Neugierde zusehen wie sich das Wirklich auswirkt.
Die Anwender haben etwar 120 PDF's abgelegt und man merkt das schon erheblich an der Geschwindigkeit

das es bei sowenig schon losgeht hätte ich nicht gedacht.

Bessere und zukünftige Lösung wird ein FTP Verzeichnis sein.

aber ich habe noch eine Frage
Die Sache geht solange gut bis ein Umlaut in den Dateinamen enthalten ist?
woher kommt das und wie kann ich diesen Fehler beheben.

viele Grüße
:)

MmVisual
Beiträge: 1445
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
CPU-Target: 32/64Bit

Re: Files in eine SQLite und MySQL datenbank ablegen?

Beitrag von MmVisual »

Ab FPC3 sollte das mit den Umlauten unter Windows doch nun endlich richtig funktionieren?
Oder welche FPC Version nutzt du?
EleLa - Elektronik Lagerverwaltung - www.elela.de

TT73GP7
Beiträge: 238
Registriert: Di 29. Mär 2016, 20:45

Re: Files in eine SQLite und MySQL datenbank ablegen?

Beitrag von TT73GP7 »

guter Einwand!

FPC 2.6.4
ich sollte man auf die neue Version migrieren
hab immer irgendwie schiss das dann irgendwas nicht läuft :(

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: Files in eine SQLite und MySQL datenbank ablegen?

Beitrag von Michl »

Du kannst mehrere Installationen von Lazarus parallel auf einem OS nutzen. Warum nicht eine zweite Installation von Lazarus aufsetzen und einfach mal eine Kopie deines Projektes kompilieren und testen?

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

MmVisual
Beiträge: 1445
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
CPU-Target: 32/64Bit

Re: Files in eine SQLite und MySQL datenbank ablegen?

Beitrag von MmVisual »

Benenne einfach das Verzeichnis um:
C:\Lazarus >> C:\Lazarus_1.4.4

Und kopiere das Verzeichnis:
C:\Users\<Dein Username>\AppData\Local\lazarus >> C:\Users\<Dein Username>\AppData\Local\lazarus_1.4.4

Dann installiere das neue Lazarus und "Update die Konfiguration".

Mit diesen beiden Verzeichnissen zurück umbenennen läuft sofort wieder das alte.
EleLa - Elektronik Lagerverwaltung - www.elela.de

MmVisual
Beiträge: 1445
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
CPU-Target: 32/64Bit

Re: Files in eine SQLite und MySQL datenbank ablegen?

Beitrag von MmVisual »

Um Dateinamen mir Umlauten mit dem alten FPC 2.x nutzen zu können braucht es ein anderes TFileStream:
Mit diesem TFileStreamUTF8 und TStringListUTF8 funktionieren alle Zeichen im Dateinamen korrekt. Dennoch ist es besser auf FPC3 um zu stellen, damit man besser für die Zukunft gerüstet ist.

Code: Alles auswählen

 
type
  TFileStreamUTF8 = class(THandleStream)
  private
    FFileName: string;
  public
    constructor Create(const AFileName: string; Mode: word; Rights: cardinal = 438);
    destructor Destroy; override;
    property FileName: string read FFilename;
  end;
 
  TStringListUTF8 = class(TStringList)
  public
    constructor Create;
    destructor Destroy; override;
    procedure SaveToFileUTF8(const FileName: string);
    procedure LoadFromFileUTF8(const FileName: string);
    function IndexOfText(const sVal: string): integer;
  end;
 
implementation
 
function FileOpenUTF8Mm(const FileName: string; Mode: integer): THandle;
{$ifdef WINDOWS}
const
  AccessMode: array[0..2] of cardinal =
    (GENERIC_READ, GENERIC_WRITE, GENERIC_READ or GENERIC_WRITE);
  ShareModes: array[0..4] of integer =
    (0, 0, FILE_SHARE_READ, FILE_SHARE_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE);
{$endif}
begin
{$ifdef WINDOWS}
  Result := CreateFileW(PWideChar(UTF8Decode(FileName)),
    dword(AccessMode[Mode and 3]), dword(
    ShareModes[(Mode and $F0) shr 4]), nil, OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL, 0);
  //if fail api return feInvalidHandle (INVALIDE_HANDLE=feInvalidHandle=-1)
{$else}
  Result := FileOpen(FileName, Mode);
{$endif}
end;
 
function FileCreateUTF8Mm(const FileName: string; ShareMode: integer = fmShareExclusive;
  Rights: integer = 0): THandle;
{$ifdef WINDOWS}
const
  //  AccessMode: array[0..2] of Cardinal  = (GENERIC_READ, GENERIC_WRITE, GENERIC_READ or GENERIC_WRITE);
  ShareModes: array[0..4] of integer =
    (0, 0, FILE_SHARE_READ, FILE_SHARE_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE);
{$endif}
begin
{$ifdef WINDOWS}
  Result := CreateFileW(PWideChar(UTF8Decode(FileName)), GENERIC_READ or
    GENERIC_WRITE, dword(ShareModes[(ShareMode and $F0) shr 4]),
    nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
{$else}
  Result := FileCreate(FileName, ShareMode, Rights);
{$endif}
end;
 
{****************************************************************************}
{*                             TFileStreamUTF8                              *}
{****************************************************************************}
constructor TFileStreamUTF8.Create(const AFileName: string; Mode: word;
  Rights: cardinal = 438);
var
  hFile: THandle;
begin
  FFileName := AFileName;
  {$ifdef WINDOWS}
  if (Win32Platform = VER_PLATFORM_WIN32_WINDOWS) then
  begin
    if (Mode and fmCreate) = fmCreate then
    begin
      if FileExists(AFileName) then
        DeleteFile(PChar(AFileName));
      hFile := FileCreate(AFileName, Mode, Rights);
    end
    else
      hFile := FileOpen(AFileName, Mode);
  end
  else
  {$endif}
  begin
    if (Mode and fmCreate) = fmCreate then
    begin
      if FileExistsUTF8(AFileName) then
        DeleteFileUTF8(AFileName);
      hFile := FileCreateUTF8Mm(AFileName, Mode, Rights);
    end
    else
      hFile := FileOpenUTF8Mm(AFileName, Mode);
  end;
 
  if hFile = THandle(-1) then
    if (Mode and fmCreate) = fmCreate then
      raise EFCreateError.createfmt(SFCreateError, [AFileName])
    else
      raise EFOpenError.Createfmt(SFOpenError, [AFilename]);
  inherited Create(hFile);
end;
 
destructor TFileStreamUTF8.Destroy;
begin
  FileClose(Handle);
  inherited Destroy;
end;
 
 
{****************************************************************************}
{*                             TStringListUTF8                                *}
{****************************************************************************}
constructor TStringListUTF8.Create;
begin
  inherited Create;
end;
 
destructor TStringListUTF8.Destroy;
begin
  inherited Destroy;
end;
 
procedure TStringListUTF8.SaveToFileUTF8(const FileName: string);
var
  TheStream: TFileStreamUTF8;
begin
  TheStream := TFileStreamUTF8.Create(FileName, fmCreate);
  try
    SaveToStream(TheStream);
  finally
    TheStream.Free;
  end;
end;
 
procedure TStringListUTF8.LoadFromFileUTF8(const FileName: string);
var
  TheStream: TFileStreamUTF8;
begin
  TheStream := TFileStreamUTF8.Create(FileName, fmOpenRead or fmShareDenyWrite);
  try
    LoadFromStream(TheStream);
  finally
    TheStream.Free;
  end;
end;
 
function TStringListUTF8.IndexOfText(const sVal: string): integer;
var
  i: integer;
begin
  Result := -1;
  for i := 0 to Count - 1 do
  begin
    if SameText(sVal, Self[i]) then
    begin
      Result := i;
      Break;
    end;
  end;
end;
 
EleLa - Elektronik Lagerverwaltung - www.elela.de

TT73GP7
Beiträge: 238
Registriert: Di 29. Mär 2016, 20:45

Re: Files in eine SQLite und MySQL datenbank ablegen?

Beitrag von TT73GP7 »

MmVisual hat geschrieben:Benenne einfach das Verzeichnis um:
C:\Lazarus >> C:\Lazarus_1.4.4

Und kopiere das Verzeichnis:
C:\Users\<Dein Username>\AppData\Local\lazarus >> C:\Users\<Dein Username>\AppData\Local\lazarus_1.4.4

Dann installiere das neue Lazarus und "Update die Konfiguration".

Mit diesen beiden Verzeichnissen zurück umbenennen läuft sofort wieder das alte.



super Einwand :)
hab das nun mal alles umgestellt
(hat leider etwas gedauert) und nun läuft es einwandfrei auf der neuen Version :)

und die umlaute sind auch wieder da :)

es hat schon seinen sinn die entwicklungsumgebung auf einen neuen stand zuhalten

Antworten