|
Forum Index : Microcontroller and PC projects : First stab at an MMBasic database
| Author | Message | ||||
| lizby Guru Joined: 17/05/2016 Location: United StatesPosts: 3535 |
The new structures open a lot of opportunities. Users have already suggested one--databases. I had some fabricated US personal data (500 invented names and locations, but located in accordance with actual demographics). I asked Gemini to convert it into a file for MMBasic on the Pico2 using a structure, and then to produce a simple query program for it to ask for single or AND and/or OR queries. It's fairly fast--half a second to find 69 records out of 500 which have a state of either MD or NJ; quarter of a second to find the single record with a City of Baltimore and a Zip of 21230. This is the structure: Type US500 DelFlag As STRING LENGTH 1 First_Name As STRING LENGTH 12 Last_Name As STRING LENGTH 15 Company As STRING LENGTH 32 Address As STRING LENGTH 33 City As STRING LENGTH 21 County As STRING LENGTH 22 State As STRING LENGTH 4 ZIP As STRING LENGTH 5 Phone1 As STRING LENGTH 14 Phone2 As STRING LENGTH 14 Email As STRING LENGTH 35 End Type Here's the whole query program: Option EXPLICIT Option DEFAULT NONE ' Define Structure Type US500 DelFlag As STRING LENGTH 1 First_Name As STRING LENGTH 12 Last_Name As STRING LENGTH 15 Company As STRING LENGTH 32 Address As STRING LENGTH 33 City As STRING LENGTH 21 County As STRING LENGTH 22 State As STRING LENGTH 4 ZIP As STRING LENGTH 5 Phone1 As STRING LENGTH 14 Phone2 As STRING LENGTH 14 Email As STRING LENGTH 35 End Type Dim db As US500 ' --- Search Storage --- ' We store "OR Groups". Each group contains a list of "AND Conditions". ' Max 5 OR groups, Max 5 ANDs per group to save memory. Dim OrGroups$(5) LENGTH 100 Dim INTEGER NumOrGroups ' Temporary parsing variables Dim rawInput$, currentOr$, currentAnd$, token$ Dim qFld$, qVal$, dbVal$ Dim INTEGER p, i, j, k, orPos, andPos, matchOr, matchAnd Dim INTEGER count = 0 Dim FLOAT startTime, duration PRESS ANY KEY ... > > list Option EXPLICIT Option DEFAULT NONE ' Define Structure Type US500 DelFlag As STRING LENGTH 1 First_Name As STRING LENGTH 12 Last_Name As STRING LENGTH 15 Company As STRING LENGTH 32 Address As STRING LENGTH 33 City As STRING LENGTH 21 County As STRING LENGTH 22 State As STRING LENGTH 4 ZIP As STRING LENGTH 5 Phone1 As STRING LENGTH 14 Phone2 As STRING LENGTH 14 Email As STRING LENGTH 35 End Type Dim db As US500 ' --- Search Storage --- ' We store "OR Groups". Each group contains a list of "AND Conditions". ' Max 5 OR groups, Max 5 ANDs per group to save memory. Dim OrGroups$(5) LENGTH 100 Dim INTEGER NumOrGroups ' Temporary parsing variables Dim rawInput$, currentOr$, currentAnd$, token$ Dim qFld$, qVal$, dbVal$ Dim INTEGER p, i, j, k, orPos, andPos, matchOr, matchAnd Dim INTEGER count = 0 Dim FLOAT startTime, duration ' --------------------------------------------------------- ' 1. Prompt and Parse (The "Compiler") ' --------------------------------------------------------- Print "Search DB (Format: Field=Value & Field=Value | Field=Value)" Line Input "Query: ", rawInput$ If rawInput$ = "" Then End ' Normalize input (Uppercase) rawInput$ = UCase$(rawInput$) NumOrGroups = 0 ' --- Step A: Split by Pipe '|' (OR Logic) --- Do While rawInput$ <> "" orPos = Instr(rawInput$, "|") If orPos > 0 Then currentOr$ = Trim$(Left$(rawInput$, orPos - 1)) rawInput$ = Mid$(rawInput$, orPos + 1) Else currentOr$ = Trim$(rawInput$) rawInput$ = "" End If If currentOr$ <> "" Then NumOrGroups = NumOrGroups + 1 OrGroups$(NumOrGroups) = currentOr$ End If Loop Print "----------------------------------------------------------------" Print "DEBUG: Parsed logic:" For i = 1 To NumOrGroups Print " OR Group " + Str$(i) + ": " + OrGroups$(i) Next i Print "----------------------------------------------------------------" ' --------------------------------------------------------- ' 2. Search Loop ' --------------------------------------------------------- Print "Searching..." startTime = Timer Open "us-500.dbt" For INPUT As #1 Do While Not Eof(#1) Struct LOAD #1, db matchOr = 0 ' Assume the record doesn't match any OR group yet ' --- Loop through OR Groups --- ' If ANY of these groups evaluates to TRUE, we print the record. For i = 1 To NumOrGroups currentOr$ = OrGroups$(i) matchAnd = 1 ' Assume this specific group is TRUE until an AND fails ' --- Loop through AND Conditions inside the group --- Do While currentOr$ <> "" andPos = Instr(currentOr$, "&") If andPos > 0 Then token$ = Trim$(Left$(currentOr$, andPos - 1)) currentOr$ = Mid$(currentOr$, andPos + 1) Else token$ = Trim$(currentOr$) currentOr$ = "" End If ' Parse Field=Value for this single condition p = Instr(token$, "=") If p > 0 Then qFld$ = Trim$(Left$(token$, p - 1)) qVal$ = Trim$(Mid$(token$, p + 1)) ' Check Database Value dbVal$ = "" Select Case qFld$ Case "CITY" : dbVal$ = UCase$(Trim$(db.City, " ", "B")) Case "STATE" : dbVal$ = UCase$(Trim$(db.State, " ", "B")) Case "ZIP" : dbVal$ = UCase$(Trim$(db.ZIP, " ", "B")) Case "LAST_NAME" : dbVal$ = UCase$(Trim$(db.Last_Name, " ", "B")) Case "FIRST_NAME" : dbVal$ = UCase$(Trim$(db.First_Name, " ", "B")) Case "COMPANY" : dbVal$ = UCase$(Trim$(db.Company, " ", "B")) Case Else : matchAnd = 0 ' Invalid field fails the group End Select If dbVal$ <> qVal$ Then matchAnd = 0 Exit Do ' Short circuit: This AND group failed, stop checking it End If End If Loop ' If matchAnd is still 1, this OR group passed! If matchAnd = 1 Then matchOr = 1 Exit For ' Short circuit: We found a valid OR group, no need to check others End If Next i ' If matchOr is 1, print the record If matchOr = 1 Then Print db.First_Name, db.Last_Name, db.City, db.State, db.ZIP count = count + 1 End If Loop Close #1 duration = Timer - startTime ' --------------------------------------------------------- ' 3. Report ' --------------------------------------------------------- Print "----------------------------------------------------------------" Print "Found " + Str$(count) + " records." Print "Runtime: " + Str$(duration) + " ms" I've uploaded the single database file as a zip file: us-500.dbt. Much more could be done--multiple files, indexes if speed is an issue, forms. I would imagine that 4-8 files with up to 1000 records each would be about as much as anyone would be likely to want on a picomite, especially since you can run SQLite on far more powerful and flexible platforms. Congratulations to Peter on this fresh inspiration. us-500.zip PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed |
||||
| Amnesie Guru Joined: 30/06/2020 Location: GermanyPosts: 745 |
Amazing all those new opportunities to try new stuff! Wow! |
||||
| The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2026 |