Searching a small file database

D

drhowarddrfine

I don't want to use a db manager, like mysql, for such a small
database but I'm finding this trickier than I thought and hope someone
can provide some guidance.

I have a restaurant menu with prices and other info in a small file.
It's set up in a YAML-ish style, if you're familiar with that format.
I'm just looking for some ideas on the best way to retrieve data based
on a "keyword". What complicates things for me is that some of these
keywords might be inside a nested block, such as "prices:".

-navigation
link: link1
link: link2
-menu
chicken:
-roasted
-fried
steak:
-strip
prices:
small: 15.00
medium: 17.00
large: 19.00
-sirloin
prices:
small: 15.00
fish:
-location

In the above example, indentation matters. I am not bound by this
format so better ideas are welcome, but searching for menu->steak-
strip->prices->large returning "19.00" seems logical to me.

What complicates things is when I want to do something like
"next_record()". It must tell me there are no more prices in "strip"
and not mistakenly search into the "prices" records of "sirloin".

Is my whole concern my answer, too? That I am trying to write a small
db manager and it's not a simple solution? Or is there simply a
better idea I'm missing?

Originally I did this in XML but felt parsing the tags wasn't any
easier and my format, above, is more readable. I can't just store a
struct in the file because I want it to be editable with any text
editor.

Thanks,
Doc
 
D

drhowarddrfine

drhowarddrfine said:
I don't want to use a db manager, like mysql, for such a small
database but I'm finding this trickier than I thought and hope someone
can provide some guidance.
I have a restaurant menu with prices and other info in a small file.
It's set up in a YAML-ish style, if you're familiar with that format.
[...]

     I'm not, but Google is.  It seems that libraries for dealing
with YAML in several programming languages, including C, have
already been written.  Use one of them.

But it's not YAML. I don't know that I want to take the time to learn
all of YAML or its libraries. Perhaps because I'm in a bit of a rush
to get this part done. I feel a need to learn how to do this, too,
and not have some library do this for me.
 
B

Bartc

I have a restaurant menu with prices and other info in a small file.
-navigation
link: link1
link: link2
-menu
chicken:
-roasted
-fried
steak:
-strip
prices:
small: 15.00
medium: 17.00
large: 19.00
-sirloin
prices:
small: 15.00
fish:
-location

In the above example, indentation matters. I am not bound by this
format so better ideas are welcome, but searching for menu->steak-

What complicates things is when I want to do something like
"next_record()". It must tell me there are no more prices in "strip"
and not mistakenly search into the "prices" records of "sirloin".

Is my whole concern my answer, too? That I am trying to write a small
db manager and it's not a simple solution? Or is there simply a
better idea I'm missing?

Are you sure you really want to use C? This looks an ideal job for a rapid
development language. I had a go at this using a toy language, and the
result, which possibly might be helpful, follows below (this code is not
case-sensitive and ! is like a // comment).

If you are going to use C, this code at least shows that you don't need
complex data structures like trees or linked lists; a linear set of records
is stored (or you could use 3 parallel arrays), but the indent level has to
be stored (as 1+). (Because, how large will a restaurant menu ever be?)

This uses a modified form of your menu: no "-" or ":" characters (whatever
they meant), and each indentation is a definite number of "\t" characters
(relying on multiples of 3 spaces might be iffy).

The next_record() function here (as findnext()), will also return any (index
to) records at the same or higher level than current.

Hope this helps.

---------------------------------

type rmenuitem = record(var level,name,value)

var menuitems
var currindex

PROC START=
if not readmenu("menu") then stop fi

forall m in menuitems do
println m
od

!index:=finditem("menu->chicken->fried")
index:=finditem("menu->steak->strip->prices")

if index then
println "Found: ",menuitems[currindex]
while findnext() do
println "Next:",menuitems[currindex]
od

else
println "Not found"
fi
END

FUNCTION FINDITEM(searchstring)=
!return index of item (also in currindex), or 0 if not found

keywords:=splitstring(searchstring,"->")

!println "Keywords=",keywords
currindex:=0

forall i,k in keywords do !i is search level
do
++currindex
if currindex>menuitems.upb then return 0 fi
if menuitems[currindex].level<i then return 0 fi
if menuitems[currindex].name=k then exit fi !ie. break
od
od
return 1
END

FUNCTION FINDNEXT=
!return index of next item after currindex, at same level, otherwise return
0
if currindex=0 or currindex>=menuitems.upb then return 0 fi
currlevel:=menuitems[currindex].level
++currindex
if menuitems[currindex].level<currlevel then return 0 fi
return currindex
END

FUNCTION READMENU(file)=
f:=openfile(file)
if f=0 then return 0 fi

menuitems:=()
nitems:=0
currindex:=0

while not eof(f) do

readln #f,x:"l"
if x="" then loop fi

indent:=0
while left(x)="\t" do
++indent
x:=right(x,-1)
od
sreread()
read name:"n"
read value:"l"

menuitems[++nitems]:=rmenuitem(indent+1,name,value)
od

closefile(f)
return nitems
END
 
D

drhowarddrfine

@Bartc,
Your comment about "how large can a restaurant menu be" is my thought
exactly. Just scanned your code and, if nothing else, it shows my
initial thoughts were along the same line and I have a little more
confidence in proceeding with my own code.

Hello Doc, List

Sqlite can be one of your (best, IMHO) options.

http://www.sqlite.org/

Regards
Rafael

I considered sqlite but for such a small amount of data, I just don't
feel this need to install any other programs.
 
M

Martien Verbruggen

Remember Douglas Adams' line
about a beverage "almost, but not quite exactly, unlike tea?"

Almost, but not quite, entirely unlike tea.

The placement of that comma makes a difference.

Martien
 
M

Michael Snoyman

I considered sqlite but for such a small amount of data, I just don't
feel this need to install any other programs.

Actually, with the sqlite amalgamation you only need add two files to
your source tree (sqlite3.c and sqlite3.h). I use sqlite all the time and
can simply pass off binaries with sqlite included.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top