Seite 1 von 1

Dynamische Befehlszeile

Verfasst: 29.12.2015 18:33
von MenschMarkus
Hallo Zusammen, im alten Jahr ich nochmal.

Hat jemand eine Idee, wie man eine Befehlszeile dynamisch gestalten kann?

Anbei mal ein Beispielcode in dem ich versucht habe die Problematik darzustellen.

Code: Alles auswählen

;************************
;** problem:
;** Dynamic Request Line
;** 20151229
;************************

EnableExplicit

Global Eingabe.s

Structure dDB
    Field1.s
    Field2.s
    Field3.s
EndStructure
NewList MemDB.dDB()

AddElement(MemDB())
MemDB()\Field1 = "Diese Eingabe ist die erste Eingabe"
MemDB()\Field2 = "Und es folgt die zweite Eingabe"
MemDB()\Field3 = "Zuguterletzt der erste inverse Wert" 
AddElement(MemDB())
MemDB()\Field1 = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr,"
MemDB()\Field2 = "sed diam nonumy eirmod tempor invidunt ut labore et "
MemDB()\Field3 = "dolore magna aliquyam erat, sed diam die voluptua." 

; Fall1: Ein Suchwort
;Eingabe = InputRequester("Worteingabe","Bitte Worte eingeben",#MB_ICONINFORMATION)     ;Eingabe soll später über Input Requester erfolgen!

Eingabe = "Diese"       ;Erzeugt 1 Ergebniszeile
;Eingabe = "die"        ;Erzeugt 2 Ergebniszeilen
;Eingabe = "die eirmod" ;Erzeugt 1 Ergebniszeile wenn beide Worte mit AND verknüpft werden (siehe Bsp. unten). Aber wie?

ResetList(MemDB())
While NextElement(MemDB())
    If FindString(MemDB()\Field1,Eingabe) > 0 Or
       FindString(MemDB()\Field2,Eingabe) > 0 Or
       FindString(MemDB()\Field3,Eingabe)
        Debug MemDB()\Field1 + " | "  + MemDB()\Field2 + " | " + MemDB()\Field3
    EndIf
Wend

; Fall2 = Problem
;
; If (FindString(MemDB()\Field1,Eingabe) > 0 Or ......Eingabe)) AND ((FindString(MemDB\Field1,Eingabe2) > 0 Or......Eingabe))   ;hier ggf. n weitere Abfragen
; Wie kann ich dynamisch n Wörter in der obigen if Abfrage jeweils mit AND verknüpfen?
; Sicherlich ist eine Datenbankabfrage einfacher zu gestalten, da dort der Query als Variable übergeben werden kann.
; Aus Performancegründen würde ich die Abfrage aber gerne im Arbeitsspeicher machen
Sollte etwas unklar sein, einfach nachfragen.
Wenn so eine Anfrage schon mal da war, bitte ein Link anfügen

An alle die antworten, Vielen Dank für die Hilfe.
An die gleiche Gruppe und den Rest wünsche ich einen guten Rutsch ins Jahr 2016

MenschMarkus

Re: Dynamische Befehlszeile

Verfasst: 30.12.2015 09:31
von mhs
Wenn du schon einen Lösungsansatz für die Abfrage per DB hast, dann kannst du auch einfach eine SQLite DB im Arbeitsspeicher mittels ":memory:" anlegen.

In folgendem Beispiel wird mit einer DB im Arbeitsspeicher gearbeitet:
http://purebasic.fr/german/viewtopic.ph ... ite+memory

__________________________________________________
Link angepasst
30.12.2015
RSBasic

Re: Dynamische Befehlszeile

Verfasst: 30.12.2015 12:09
von MenschMarkus
Wenn du schon einen Lösungsansatz für die Abfrage per DB hast, dann kannst du auch einfach eine SQLite DB im Arbeitsspeicher mittels ":memory:" anlegen.
Danke mhs für den Link. Das werde ich mir noch einmal genauer ansehen.
So wie ich auf die Schnelle erkennen konnte wird im Speicher eine neue SQLite DB erzeugt.
Ich habe aber eine bestehende DB die ich nicht jedesmal neu erzeugen und füllen möchte (Ist ja auch nicht Sinn und Zweck einer DB). Gibt es sowas wie ':memory:' zum öffnen einer bestehenden SQLite DB im Arbeitsspeicher anstelle auf der HDD?

Re: Dynamische Befehlszeile

Verfasst: 30.12.2015 12:16
von Kiffi
@MenschMarkus: Mir erschließt sich noch nicht ganz, was Du genau vorhast. Was heißt in diesem Zusammenhang "Befehlszeile"? Möchtest Du die Parameter analysieren, die Deinem Programm übergeben werden (und die man mit ProgramParameter() auslesen kann)?

Grüße ... Peter

Re: Dynamische Befehlszeile

Verfasst: 30.12.2015 12:33
von MenschMarkus
@ Kiffi

Im wesentlichen geht es um die Befehlszeile:

Code: Alles auswählen

If FindString(MemDB()\Field1,Eingabe) > 0 Or
       FindString(MemDB()\Field2,Eingabe) > 0 Or
       FindString(MemDB()\Field3,Eingabe)
        Debug MemDB()\Field1 + " | "  + MemDB()\Field2 + " | " + MemDB()\Field3
    EndIf
Diese gilt es, je nach Anzahl der zu suchenden Worte auf

Code: Alles auswählen

If (FindString(MemDB()\Field1,Eingabe) > 0 Or
       FindString(MemDB()\Field2,Eingabe) > 0 Or
       FindString(MemDB()\Field3,Eingabe)) AND
       (FindString(MemDB()\Field1,Eingabe2) > 0 Or
       FindString(MemDB()\Field2,Eingabe2) > 0 Or
       FindString(MemDB()\Field3,Eingabe2))
        Debug MemDB()\Field1 + " | "  + MemDB()\Field2 + " | " + MemDB()\Field3
    EndIf
zu ergänzen, wobei Eingabe und Eingabe2 die zu suchenden Worte darstellen. Jetzt kann ich aber im Voraus nicht wissen wieviele Worte abgefragt werden. Das bedeutet die AND Verknüpfung wiederholt sich so oft wie Worte angegeben werden.
(edit:) Eine Befehlszeile muss scheinbar gecodet werden und kann nicht als Variable ausgeführt werden ! Bei If muss dann auch noch eine Bedingung her.

Ich hoffe diese Erklärung hilft etwas.

LG MenschMarkus

Re: Dynamische Befehlszeile

Verfasst: 30.12.2015 12:56
von mhs
MenschMarkus hat geschrieben:Ich habe aber eine bestehende DB die ich nicht jedesmal neu erzeugen und füllen möchte (Ist ja auch nicht Sinn und Zweck einer DB).
Wenn du schon eine DB hast, dann verwende die DB auch wie eine DB und führe normale Queries darauf aus. Sonst müsstest du ja alle Datensätze aus der DB in den Arbeitsspeicher einlesen und würdest damit jegliche Optimierung seitens der DB auf Performance vernichten.
MenschMarkus hat geschrieben:zu ergänzen, wobei Eingabe und Eingabe2 die zu suchenden Worte darstellen. Jetzt kann ich aber im Voraus nicht wissen wieviele Worte abgefragt werden. Das bedeutet die AND Verknüpfung wiederholt sich so oft wie Worte angegeben werden.
Wenn es dir nur um einen Stringvergleich geht, kannst du einfach die Suchworte in Tokens (StringField()) aufteilen und dann mittels einer Schleife die Funktion FindString() für jedes Suchwort eigens aufrufen.

Re: Dynamische Befehlszeile

Verfasst: 30.12.2015 13:04
von GPI
Um ehrlich zu sein, ich verstehe deine Fragestellen überhaupt nicht. Was willst du machen?

Aber eventuell so:

Code: Alles auswählen

NewMap Such()

such("Hallo")=1
such("wer")=1
such("du")=1
such("bist")=1

gefunden=#True
str.s="Hallo wer du bist nicht"

i=0
Repeat
  i+1
  a$=StringField(str,i," ")
  If a$=""
    Break
  EndIf
  
  If Not FindMapElement(such(),a$)
    gefunden=#False
    Break
  EndIf
ForEver
Debug gefunden

Re: Dynamische Befehlszeile

Verfasst: 30.12.2015 13:15
von MenschMarkus
@GPI
Um ehrlich zu sein, ich verstehe deine Fragestellen überhaupt nicht. Was willst du machen?
Der Idealfall wäre eine SQLite DB im Arbeitsspeicher zu haben.
Ich hatte versucht die DB Struktur mittels Listen im Speicher nachzubilden, was ja problemlos funktioniert.


Danke für Deinen Code.

Über Maps habe ich auch schon nachgedacht, die sind aber nicht flexiebel genug.
Beinhaltet ein Datensatz "Hallo wer du bist" und ein weiterer "Hallo wer ist da" klappt das mit Maps schon nicht mehr. Mit Listen schon.

Re: Dynamische Befehlszeile

Verfasst: 30.12.2015 16:42
von GPI
Wie gesagt, ich hab nicht ganz geschnallt, was du willst. Aber du kannst ja auch eine map-list machen

Code: Alles auswählen

Structure Maplist
  Map iMap()
EndStructure

NewList mList.Maplist()

AddElement(mList())
mList()\iMap("Hallo")=1

Re: Dynamische Befehlszeile

Verfasst: 30.12.2015 16:51
von MenschMarkus
Danke GPI, dass Du Dir weitere Gedanken gemacht hast. Aber eine DB im Speicher ist die Beste Lösung. Da kann ich auf die gesamte Variabilität einer SQL Anfrage zurückgreifen.

Ich bin dem Link aus der ersten Antwort gefolgt und habe es getestet. Das hat funktioniert. Ich denke einmal, ob ich eine strukturierte Liste oder eine sqlite DB im Speicher aufbaue macht keinen wirklichen Unterschied. Es sollte halt nur darauf geachtet werden, dass die DB nicht größer ist als der Arbeitsspeicher ist. Bei mir ist die DB 20 MB groß. Ich glaube das ist noch vertretbar.
Damit ist die Frage nach der dynamischen Befehlszeile zwar nicht beantwortet, aber das Problem konnte brauchbar gelöst werden. Danke nochmal an mhs für den Link und Kiffi, der das veröffentlicht hat.

hier meine Lösung meines Problems basierend auf dem Link aus der ersten Antwort

Code: Alles auswählen

;*******************************
;**  Memory Database Test
;**  20151230
;**  Author:  MenschMarkus
;**  PureBasic Forum
;*******************************
EnableExplicit

UseSQLiteDatabase()
Define.s Eingabe, Query
Define.l Wortzahl, i

Enumeration
    #HDD_DB
    #MEM_DB
EndEnumeration

If FileSize("dbmemtest.sql")  < 0           ;Falls die DB noch nicht existiert wird sie erzeugt
    CreateFile(0,"dbmemtest.sql")
    CloseFile(0)
    OpenDatabase(#HDD_DB,"dbmemtest.sql","","",#PB_Database_SQLite)
    DatabaseUpdate(#HDD_DB,"CREATE TABLE data (Field1 TEXT,Field2 TEXT,Field3 TEXT)")
    DatabaseUpdate(#HDD_DB,"INSERT INTO data (Field1,Field2,Field3) VALUES ('Dies ist die erste Eingabe','Und es folgt die zweite Eingabe','Zuguterletzt der erste inverse Wert')")
    DatabaseUpdate(#HDD_DB,"INSERT INTO data (Field1,Field2,Field3) VALUES ('Lorem ipsum dolor sit amet','sed diam nonumy eirmod tempor','dolore magna aliquyam erat, sed diam die voluptua')")
    CloseDatabase(#HDD_DB)
EndIf

OpenDatabase(#HDD_DB,"dbmemtest.sql","","",#PB_Database_SQLite)     ;Datenbank zum Einlesen öffnen
OpenDatabase(#MEM_DB,":memory:","","",#PB_Database_SQLite)          ;Memory Datenbank erzeugen 
DatabaseUpdate(#MEM_DB,"CREATE TABLE data (Field1 TEXT,Field2 TEXT,Field3 TEXT)")

Query = "SELECT * FROM data"
DatabaseQuery(#HDD_DB,Query)
While NextDatabaseRow(#HDD_DB)        ; Datenbank in den Arbeitsspeicher schreiben
    Query = "INSERT INTO data (Field1,Field2,Field3) VALUES ('" + GetDatabaseString(#HDD_DB,0) + "','" + GetDatabaseString(#HDD_DB,1) + "','" + GetDatabaseString(#HDD_DB,2) + "')"
    DatabaseUpdate(#MEM_DB,Query)
Wend

Repeat
    Eingabe = InputRequester("Worteingabe","Bitte Suchworte eingeben","") + " "
    If Trim(UCase(Eingabe)) = "EXIT"
        CloseDatabase(#MEM_DB)
        End
    EndIf
    Wortzahl = CountString(Eingabe," ")
    Query = "SELECT * FROM data WHERE"
    For i = 1 To Wortzahl
        Query + " (Field1 LIKE '%" + StringField(Eingabe,i," ") + "%'"
        Query + " OR Field2 LIKE '%" + StringField(Eingabe,i," ") + "%'"
        Query + " OR Field3 LIKE '%" + StringField(Eingabe,i," ") + "%') AND"
    Next
    Query = Left(Query,Len(Query)-4)
    DatabaseQuery(#MEM_DB,Query)
    While NextDatabaseRow(#MEM_DB)
        Debug "Ergebnis MEM: " + GetDatabaseString(#MEM_DB,0) + " | " + GetDatabaseString(#MEM_DB,1) + " | " + GetDatabaseString(#MEM_DB,2) 
    Wend
    DatabaseQuery(#HDD_DB,Query)
    While NextDatabaseRow(#HDD_DB)
        Debug "Ergebnis HDD: " + GetDatabaseString(#HDD_DB,0) + " | " + GetDatabaseString(#HDD_DB,1) + " | " + GetDatabaseString(#HDD_DB,2) 
    Wend
ForEver
Danke für die Anregungen
Allen ein gutes Neues Jahr 2016

P.S.: Dumme Fragen sind doch nicht so dumm. Man denkt wenigstens mal darüber nach. Manchmal findet man auch eine Lösung :mrgreen: