Seite 1 von 2

Auswerteproblem von FTS unter SQLite

Verfasst: 14.07.2016 22:06
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

Re: Auswerteproblem von FTS unter SQLite

Verfasst: 14.07.2016 23:27
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.)

Re: Auswerteproblem von FTS unter SQLite

Verfasst: 15.07.2016 07:39
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.

Re: Auswerteproblem von FTS unter SQLite

Verfasst: 15.07.2016 08:17
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

Re: Auswerteproblem von FTS unter SQLite

Verfasst: 15.07.2016 08:44
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)

Re: Auswerteproblem von FTS unter SQLite

Verfasst: 15.07.2016 09:50
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.

Re: Auswerteproblem von FTS unter SQLite

Verfasst: 15.07.2016 10:26
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

Re: Auswerteproblem von FTS unter SQLite

Verfasst: 15.07.2016 10:42
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 ...

Re: Auswerteproblem von FTS unter SQLite

Verfasst: 15.07.2016 11:26
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

Re: Auswerteproblem von FTS unter SQLite

Verfasst: 15.07.2016 11:35
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