Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 13:55 08 Jan 2026 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : First stab at an MMBasic database

Author Message
lizby
Guru

Joined: 17/05/2016
Location: United States
Posts: 3535
Posted: 09:34pm 06 Jan 2026
Copy link to clipboard 
Print this post

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"


  Quote  > run
Search DB (Format: Field=Value & Field=Value | Field=Value)
Query: City=Baltimore
----------------------------------------------------------------
DEBUG: Parsed logic:
 OR Group 1: CITY=BALTIMORE
----------------------------------------------------------------
Searching...
Kris            Marrier         Baltimore               MD      21224
Laurel          Reitler         Baltimore               MD      21215
Kaitlyn         Ogg             Baltimore               MD      21230
Eden            Jayson          Baltimore               MD      21202
Izetta          Dewar           Baltimore               MD      21217
----------------------------------------------------------------
Found 5 records.
Runtime: 245.695 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: Germany
Posts: 745
Posted: 10:34pm 06 Jan 2026
Copy link to clipboard 
Print this post

Amazing all those new opportunities to try new stuff! Wow!
 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2026