ASCII database (was Re: Should I prefer an external database)
Aahz
aahz at pythoncraft.com
Wed Apr 23 10:13:09 EDT 2003
In article <u3ckbymri.fsf at mail.afm.dtu.dk>,
Brian Elmegaard <brian at rk-speed-rugby.dk> wrote:
>
>I am working on a script for organizing a program for a conference. I
>started out using a connection to mySQL, but then I thought that it
>would be easier to keep it within python.
This seems like a good place to mention that I'm currently rolling my
own database. I'm doing it because I want to keep the DB online in my
shell account, and it's a PITA using anything other than a simple text
editor to update bits within it. So I'm using a simple RFC-822 layout
for the fields with '%%\n' as the record separator; fields are permitted
to have multiple instances. There are no required fields in the design;
each record is free-form.
The fun part was implementing the search engine. I wanted to implement
something usable, so I allow both includes and excludes. Excludes are
always ORed; includes are ANDed; search terms are separated by commas.
An include can have an embedded pipe ('|'), which turns it into a list
of ORed terms. Excludes are prepended with an exclamation point ('!').
(Yes, I don't like the visual confusion, but those are standard chars
and the location makes the intent clear.)
So here's my filter function:
class Excluded(StandardError):
pass
class Found(StandardError):
pass
class NotFound(StandardError):
pass
# Includes by default are ANDed; excludes are always ORed
# Use "|" to OR includes; "!" indicates exclude
def filter(db, FilterString=None, fields=None, FuzzyMatch=True):
includes, excludes = _buildFilters(FilterString)
if fields is not None:
fields = re_comma_field.split(fields)
for i in range(len(fields)):
fields[i] = fields[i].lower()
if FuzzyMatch:
match = _fuzzy_match
else:
match = _exact_match
result = []
for record in db:
if fields is None:
curr_fields = record.keys()
else:
curr_fields = []
for field in fields:
if field in record:
curr_fields.append(field)
try:
for field in curr_fields:
for item in record[field]:
item = item.lower()
for filter in excludes:
if match(item, filter):
raise Excluded
except Excluded:
continue
try:
for ORlist in includes:
try:
for filter in ORlist:
for field in curr_fields:
for item in record[field]:
if item.lower().find(filter) >= 0:
raise Found
else:
raise NotFound
except Found:
continue
except NotFound:
continue
else:
result.append(record)
return result
def _fuzzy_match(string, filter):
return string.find(filter) >= 0
def _exact_match(string, filter):
return string == filter
re_filters = re.compile(r', *')
NOT = '!'
OR = '|'
# Each set of filter words is separated by comma
def _buildFilters(FilterString):
if FilterString is None:
return [], []
else:
FilterString = FilterString.lower()
FilterList = re_filters.split(FilterString)
includes, excludes = [], []
for filter in FilterList:
if filter[0] == NOT:
excludes.append(filter[1:])
else:
includes.append(filter.split(OR))
return includes, excludes
--
Aahz (aahz at pythoncraft.com) <*> http://www.pythoncraft.com/
Why is this newsgroup different from all other newsgroups?
More information about the Python-list
mailing list