Auswerteproblem von FTS unter SQLite

Für allgemeine Fragen zur Programmierung mit PureBasic.
MenschMarkus
Beiträge: 227
Registriert: 30.04.2009 21:21
Computerausstattung: i5-2300 (2.8 Ghz) Win10 -64bit / PB 5.73 LTS

Auswerteproblem von FTS unter SQLite

Beitrag von MenschMarkus »

Hallo mal wieder,
Ich bin gerade dabei eine FTS Abfrage unter SQLite zu konstruieren und diese auszuwerten.
Das Erzeugen der FTS Tabelle ist kein Problem
Die FTS Abfrage selbst ist kein Problem
Die Auswertung der FTS Abfrage mittels matchinfo() allerdings schon. SQLite gibt einen BLOB von 80 Byte zurück. Diesen kann ich in einen *Buffer schreiben. Das Problem ist, wie kann ich die 80 Byte Byteweise auslesen?

Hier mal mein Ansatz

Code: Alles auswählen

EnableExplicit
UseSQLiteDatabase()
Define *blobresult

CreateFile(0,"fts_test.sql")
CloseFile(0)
OpenDatabase(0,"fts_test.sql","","",#PB_Database_SQLite)
DatabaseUpdate(0,"CREATE VIRTUAL TABLE t1 USING fts4(a, b)")
DatabaseUpdate(0,"INSERT INTO t1 VALUES('transaction default models default', 'Non transaction reads')")
DatabaseUpdate(0,"INSERT INTO t1 VALUES('the default transaction', 'these semantics present')")
DatabaseUpdate(0,"INSERT INTO t1 VALUES('single request', 'default data')")

DatabaseQuery(0,"SELECT matchinfo(t1) FROM t1 WHERE t1 MATCH 'default transaction " + Chr(34) + "these semantics" + Chr(34) + "'")

While NextDatabaseRow(0)
    Debug "***"
    Debug GetDatabaseBlob(0,0,@*blobresult,DatabaseColumnSize(0,0))     ;1 wenn erfolgreich gelesen werden konnte
    Debug DatabaseColumnSize(0,0)                                       ;BLOB Größe in Byte
    Debug @*blobresult                                                  ;Beginn der Speicheradresse
    Debug "Wie bringe ich die 80 Byte zu Papier?"
Wend
CloseDatabase(0)                                                        ;Warum erscheint hier ein Speicherfehler?
End
Nochmals die Frage: Wie komme ich an die 80 Byte BLOB Information im Pointer?
(nähere Info und das Ergebnis der 80 Byte dieses Beispiels findet Ihr unter: http://sqlite.org/fts3.html#matchinfo)

Vielen Dank schon mal für die Hilfe

mm
Wissen schadet nur dem, der es nicht hat !
Benutzeravatar
Bisonte
Beiträge: 2474
Registriert: 01.04.2007 20:18

Re: Auswerteproblem von FTS unter SQLite

Beitrag von Bisonte »

Ohne gross zu testen ....

Den Speicher muss man vorher reservieren !

Also : AllocateMemory(Speichergrösse)

Du versuchst in deinem Beispiel, wohl 80Byte, in eine Integervariable speichern, was natürlich in die Hose geht....

(Und als Tipp... Bewährt bei Binären Blobs hat es sich ein Feld in die Tabelle aufzunehmen in der die Grösse des Speichers steht der gebraucht wird.)
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
Benutzeravatar
mhs
Beiträge: 224
Registriert: 11.01.2009 16:30
Wohnort: Graben
Kontaktdaten:

Re: Auswerteproblem von FTS unter SQLite

Beitrag von mhs »

Eine andere Variante ist, die Größe eines Blobs DatabaseColumnSize() abzufragen.

Also zuerst die Größe abfragen (eine von beiden Varianten), Speicher reservieren und diesen Speicherbereich beim GetDatabaseBlob() mit angeben.
Michael Hack

Michael Hack Software :: Softwareentwicklung | Webentwicklung | IT-Dienstleistungen
www.michaelhacksoftware.de :: www.mh-s.de :: www.michael-hack.de
MenschMarkus
Beiträge: 227
Registriert: 30.04.2009 21:21
Computerausstattung: i5-2300 (2.8 Ghz) Win10 -64bit / PB 5.73 LTS

Re: Auswerteproblem von FTS unter SQLite

Beitrag von MenschMarkus »

@Bisonte
Du versuchst in deinem Beispiel, wohl 80Byte, in eine Integervariable speichern, was natürlich in die Hose geht....
Hm welche Integervariable sollte das denn sein? Ich definiere nur einen Pointer, welcher ja bekanntlich nicht mit einem nativen Typ definiert werden kann
(Und als Tipp... Bewährt bei Binären Blobs hat es sich ein Feld in die Tabelle aufzunehmen in der die Grösse des Speichers steht der gebraucht wird.)
ja, korrekt, das geschieht auch in der Zeile GetDatabaseBlob(....)

@mhs
Eine andere Variante ist, die Größe eines Blobs DatabaseColumnSize() abzufragen.
ja, korrekt, das geschieht auch in der Zeile GetDatabaseBlob(....)

Kopiert man mein Beispiel und führt es aus, sieht man, dass die Daten im Pointer *blobresult alle da sind wo sie hin gehören.
Ich wollte sie nur byte weise auslesen. Da liegt das Problem nicht schon vorher.

Weitere Vorschläge ?

mm
Wissen schadet nur dem, der es nicht hat !
Benutzeravatar
mhs
Beiträge: 224
Registriert: 11.01.2009 16:30
Wohnort: Graben
Kontaktdaten:

Re: Auswerteproblem von FTS unter SQLite

Beitrag von mhs »

MenschMarkus hat geschrieben: @mhs
Eine andere Variante ist, die Größe eines Blobs DatabaseColumnSize() abzufragen.
ja, korrekt, das geschieht auch in der Zeile GetDatabaseBlob(....)
mhs hat geschrieben:Also zuerst die Größe abfragen (eine von beiden Varianten), Speicher reservieren und diesen Speicherbereich beim GetDatabaseBlob() mit angeben.
Du hast keinen Speicher reserviert... so sollte es richtig aussehen:

Code: Alles auswählen

size        = DatabaseColumnSize(0, 0)
*blobresult = AllocateMemory(size)

GetDatabaseBlob(0, 0, *blobresult, size)

PeekS(*blobresult) ; Speicher ausgeben oder was du damit machen möchtest

FreeMemory(*blobresult)
Michael Hack

Michael Hack Software :: Softwareentwicklung | Webentwicklung | IT-Dienstleistungen
www.michaelhacksoftware.de :: www.mh-s.de :: www.michael-hack.de
Benutzeravatar
Bisonte
Beiträge: 2474
Registriert: 01.04.2007 20:18

Re: Auswerteproblem von FTS unter SQLite

Beitrag von Bisonte »

MenschMarkus hat geschrieben:Hm welche Integervariable sollte das denn sein? Ich definiere nur einen Pointer, welcher ja bekanntlich nicht mit einem nativen Typ definiert werden kann
Der Pointer IST eine Integervariable.

Man kann *pointer oder auch pointer.i nehmen... spielt in PB keine Rolle.
Der * dient nur der eindeutigen Identifizierung, damit
man sofort sieht, dass ein Speicherbereich gemeint ist.

Das mit "DatabaseColumnSize()" hab ich wohl bemerkt, mein Tipp war als
Alternative zu verstehen.

Was für Daten sollen denn in *blobresult sein ? Mehr als 4 Byte passen nicht.
Wenn man mehr hineinschreiben will ist das so, als würdest du in einen 5 Liter
Eimer 20 Liter Wasser einfüllen....

Wie mhs und ich schon bemerkten : Du hast keinen Speicher reserviert.
Siehe sein Beispiel.
PureBasic 6.21 (Windows x86/x64) | Windows11 Pro x64 | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | GeForce RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
MenschMarkus
Beiträge: 227
Registriert: 30.04.2009 21:21
Computerausstattung: i5-2300 (2.8 Ghz) Win10 -64bit / PB 5.73 LTS

Re: Auswerteproblem von FTS unter SQLite

Beitrag von MenschMarkus »

@Bisonte
Der Pointer IST eine Integervariable.

Man kann *pointer oder auch pointer.i nehmen... spielt in PB keine Rolle.
Der * dient nur der eindeutigen Identifizierung, damit
man sofort sieht, dass ein Speicherbereich gemeint ist.
Hm, das war mir so nicht bewusst. Ich bin eher davon ausgegangen, dass der * vor dem Variablennamen dafür sorgt, dass auch der Pointer intern anders als eine normale Variable gehandelt wird.
Danke für die Info.
Was für Daten sollen denn in *blobresult sein ? Mehr als 4 Byte passen nicht.
Wenn man mehr hineinschreiben will ist das so, als würdest du in einen 5 Liter
Eimer 20 Liter Wasser einfüllen....
Nettes Beispiel. Das war auch so das Problem welches ich hatte. Wie bekommen ich 80 Byte in *blobresult. Dank des Beispiels von mhs kann ich das ja auslesen. Ich muss das mal testen wie das Ergebnis aussieht und wie ich das verwenden kann.

@mhs
Du hast keinen Speicher reserviert... so sollte es richtig aussehen:

Code:

Code: Alles auswählen

size        = DatabaseColumnSize(0, 0)
*blobresult = AllocateMemory(size)

GetDatabaseBlob(0, 0, *blobresult, size)

PeekS(*blobresult) ; Speicher ausgeben oder was du damit machen möchtest

FreeMemory(*blobresult)
Danke für das Muster. Sollte helfen.

Falls nicht, melde ich mich wieder.

Danke nochmals Ihr zwei für die Kommentare.

mm
Wissen schadet nur dem, der es nicht hat !
Benutzeravatar
mhs
Beiträge: 224
Registriert: 11.01.2009 16:30
Wohnort: Graben
Kontaktdaten:

Re: Auswerteproblem von FTS unter SQLite

Beitrag von mhs »

Und vergiss nicht den Speicher nach dem Reservieren bzw. GetDatabaseBlob zu prüfen:

Code: Alles auswählen

size        = DatabaseColumnSize(0, 0)
*blobresult = AllocateMemory(size)

If *blobresult

  If GetDatabaseBlob(0, 0, *blobresult, size)
    PeekS(*blobresult) ; Speicher ausgeben oder was du damit machen möchtest
  EndIf
  
  FreeMemory(*blobresult)
  
EndIf
... hatte ich vorhin vergessen ...
Michael Hack

Michael Hack Software :: Softwareentwicklung | Webentwicklung | IT-Dienstleistungen
www.michaelhacksoftware.de :: www.mh-s.de :: www.michael-hack.de
MenschMarkus
Beiträge: 227
Registriert: 30.04.2009 21:21
Computerausstattung: i5-2300 (2.8 Ghz) Win10 -64bit / PB 5.73 LTS

Re: Auswerteproblem von FTS unter SQLite

Beitrag von MenschMarkus »

So, hab das mal getestet.
Dank Speicherreservierung kommt es auch zu keiner Fehlermeldung mehr.
Leider nutzt mich das Auslesen der 80 Byte mit PeekS() nichts, da hier kein Klartext steht, PeekS() den Inhalt aber in ASCII/Unicode/Utf-8 ausgibt.
Der Inhalt sieht aber wie folgt aus:

Code: Alles auswählen

03 00 00 00 02 00 00 00 01 00 00 00 03 00 00 00
02 00 00 00 00 00 00 00 01 00 00 00 01 00 00 00
01 00 00 00 02 00 00 00 02 00 00 00 00 00 00 00
01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00
(Ermittelt via Speicheranzeige)

Ich benötige als Information jeweils den erste Hex Wert eines Quartets.

Keine Ahnung wie ich da dran komme

mm
Wissen schadet nur dem, der es nicht hat !
Benutzeravatar
mhs
Beiträge: 224
Registriert: 11.01.2009 16:30
Wohnort: Graben
Kontaktdaten:

Re: Auswerteproblem von FTS unter SQLite

Beitrag von mhs »

Dann musst du dich durch den Speicherbereich mit PeekB() oder PeekL() durchhangeln, je nachdem wie die Daten dort abgelegt sind.

Code: Alles auswählen

Define.i offset

While offset < size

  Debug PeekB(*blobresult + offset)

  offset + 4
  
Wend
Michael Hack

Michael Hack Software :: Softwareentwicklung | Webentwicklung | IT-Dienstleistungen
www.michaelhacksoftware.de :: www.mh-s.de :: www.michael-hack.de
Antworten