Mehrere Blobs bei databaseupdate

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
ProgOldie
Beiträge: 236
Registriert: 19.05.2012 17:09
Computerausstattung: Windows11, Arduinos, Pi3, PureBasic 6.02

Mehrere Blobs bei databaseupdate

Beitrag von ProgOldie »

Hallo,
ich habe in einem Datensatz einer SQLITE-DB mehrere BLOBs, in die ich jeweils ein File einlesen will.
Dazu muss ich die Fileinhalte natürlich erst einlesen und dazu wiederum einen Speicherbereich reservieren.
Da ich bei INSERT bzw. UPDATE() alle Bereiche gleichzeitig ansprechen muss, muss ich mir auch für jeden BLOB die zugehörige Adresse und dessen Größe merken, denn ich kann den Bereich (vermutlich!) nicht sofort nach jedem SetDatabaseBlob() wieder freigeben.

Ist das folgende kleine Testprogramm in diesem Zusammenhang unproblematisch oder muss ich dabei mit bösen Überraschungen wie Speicherlecks o.ä. rechnen?

Code: Alles auswählen

EnableExplicit

Dim *mem(5)   ;Bereich für Blobs von 0..4 
Dim size.i(5)
Define Nr.i

For Nr=0 To 4
  size(Nr)=10*Nr + 5  ; irgendeine synthetische Speichergröße
  *mem(Nr)=AllocateMemory(size(Nr))
  Debug Str(*mem(Nr))+"---"+Str(size(Nr))
Next
For Nr=0 To 4
  FreeMemory(*mem(Nr))
Next
Windows10 / PB5.70 / Arduino (-Due) / Raspberry Pi3 /Linux Mint 18
GPI
Beiträge: 1511
Registriert: 29.08.2004 13:18
Kontaktdaten:

Re: Mehrere Blobs bei databaseupdate

Beitrag von GPI »

ProgOldie hat geschrieben:Da ich bei INSERT bzw. UPDATE() alle Bereiche gleichzeitig ansprechen muss, muss ich mir auch für jeden BLOB die zugehörige Adresse und dessen Größe merken, denn ich kann den Bereich (vermutlich!) nicht sofort nach jedem SetDatabaseBlob() wieder freigeben.
Ist in der Hilfe nicht eindeutig angegeben, aber nach DatabaseUpdate() sollte es gefahrlos freigebbar sein.
oder muss ich dabei mit bösen Überraschungen wie Speicherlecks o.ä. rechnen?
Es kann passieren, das kein Speicher mehr frei ist und AllocateMemory() #Null zurückgeben wird. Das sollte man abfangen (zumindest mit einer Fehlermeldung sauber beenden).

Ansonsten: Dim *mem(5) reserviert ein Array von 0-5 - also 6 Elemente.

Es kann auch klug sein, einen ausreichend großen Speicher an Anfang zu reservieren und ihn nicht frei zu geben. Das spart einen immer das neue anlegen und freigeben.
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
Benutzeravatar
ProgOldie
Beiträge: 236
Registriert: 19.05.2012 17:09
Computerausstattung: Windows11, Arduinos, Pi3, PureBasic 6.02

Re: Mehrere Blobs bei databaseupdate

Beitrag von ProgOldie »

Ist in der Hilfe nicht eindeutig angegeben, aber nach DatabaseUpdate() sollte es gefahrlos freigebbar sein.
Ja, doch die eigentliche Frage ist, ob der Speicherbereich auch schon bei setDatabaseBlob() freigegeben wird. Ich vermute allerdings, dass das nicht(!) der Fall ist, sondern dass dabei lediglich eine Art Verknüpfung zum Speicherbereich angelegt wird.
Windows10 / PB5.70 / Arduino (-Due) / Raspberry Pi3 /Linux Mint 18
Benutzeravatar
Bisonte
Beiträge: 2427
Registriert: 01.04.2007 20:18

Re: Mehrere Blobs bei databaseupdate

Beitrag von Bisonte »

Erst nach DatabaseUpdate kannst du gefahrlos freigeben. Habe selbiges auch schon probiert.

Aber bei INSERT und UPDATE muss man nicht alle Felder ansprechen.
Es genügt, wenn man die Felder die man eintragen will in dem ersten Block, bzw bei Update in den SET Anweisungen definiert.

Code: Alles auswählen

"CREATE TABLE tabelle(id, bild1, bild2, bild3, length, length2, length3)"
"INSERT INTO tabelle(bild1, length) VALUES (?, " + Str(Length) + ")"

"UPDATE tabelle SET bild1 = ?, Length = " + Str(Length)
Da muss nicht immer die komplette Tabelle stehen. Fehlende Felder bei INSERT werden mit Standardwerten gefüllt, bei UPDATE komplett ausgelassen.
PureBasic 6.04 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
Benutzeravatar
ProgOldie
Beiträge: 236
Registriert: 19.05.2012 17:09
Computerausstattung: Windows11, Arduinos, Pi3, PureBasic 6.02

Re: Mehrere Blobs bei databaseupdate

Beitrag von ProgOldie »

Aber bei INSERT und UPDATE muss man nicht alle Felder ansprechen.
Es genügt, wenn man die Felder die man eintragen will in dem ersten Block, bzw bei Update in den SET Anweisungen definiert.
Ich vermute, du meinst folgende Vorgehensweise ( am Beispiel einer Personendatei mit u. a. Foto )
Bei INSERT: zuerst alle 'nicht-BLOBS' eintragen. In einer anschließenden update-Anweisung dann die BLOBS wie Foto
Bei UPDATE: Die gleiche zweischrittige Vorgehensweise.

Das funktioniert aber nicht, wenn die Datenbank so definiert ist, dass ein Foto der Person vorhanden sein muss (z.B. NOT NULL oder CHECK (Länge), weil dann zumindest im ersten Schritt von INSERT der Datensatz nicht gültig ist.

Es hilft also nichts, man muss - was ohnehin eleganter und klarer ist- mit Speicherbereichen arbeiten.
Windows10 / PB5.70 / Arduino (-Due) / Raspberry Pi3 /Linux Mint 18
Antworten