#-- Version 1.0.0 #-- Nathan Denny, July 20, 2000 import string import types import fnmatch class Textbase: def __init__(self,source_file_name): self.Records=[] self.Source=source_file_name self.QuerySet=None #-- Open the source file and read it in. self.Read() #-- Set up an alias. COMMIT flushes the textbase to disk. self.Commit=self.Write def Read(self): source_file=open(self.Source,'r') l=source_file.readline() record={} linenumber=1 while l!="": l=string.strip(l) if len(l)>0: i=string.find(l,':') if i>=0: attribute=string.strip(l[:i]) value=string.strip(l[i+1:]) if record.has_key(attribute): if type(record[attribute])==types.ListType: record[attribute].append(value) else: record[attribute]=[record[attribute],value] else: record[attribute]=value else: print "TextDatabase: Parser error at %d"%(linenumber) else: if len(record.keys())>0: self.Records.append(record) record={} l=source_file.readline() linenumber=linenumber+1 if len(record.keys())>0: self.Records.append(record) source_file.close() def Commit(self): self.Write() def Write(self): source_file=open(self.Source,'w') for record in self.Records: for attribute in record.keys(): if type(record[attribute])==types.ListType: for x in record[attribute]: source_file.write("%s:%s\n"%(attribute,x)) else: source_file.write("%s:%s\n"%(attribute,record[attribute])) source_file.write('\n') source_file.close() #-- Returns 1 if the given record satisfies the query. def QueryMatch(self,record_number): #-- Is this query case sensitive? if self.QueryCaseSensitive: matcher=fnmatch.fnmatchcase else: matcher=fnmatch.fnmatch #-- Do the query. record=self.Records[record_number] for attribute in self.Query.keys(): if record.has_key(attribute): #-- If the values are 1 to 1. if (type(record[attribute])!=types.ListType) and (type(self.Query[attribute])!=types.ListType): if not matcher(record[attribute],self.Query[attribute]): return 0 if (type(record[attribute])!=types.ListType) and (type(self.Query[attribute])==types.ListType): matched=0 for x in self.Query[attribute]: if matcher(record[attribute],x): matched=1 break if not matched: return 0 if (type(record[attribute])==types.ListType) and (type(self.Query[attribute])!=types.ListType): matched=0 for x in record[attribute]: if matcher(x,self.Query[attribute]): matched=1 break if not matched: return 0 if (type(record[attribute])==types.ListType) and (type(self.Query[attribute])==types.ListType): match=0 for x in self.Query[attribute]: for y in record[attribute]: if matcher(y,x): match=1 break if not match: return 0 else: return 0 if record_number not in self.QuerySet: return 1 else: return 0 def GetRecord(self,record_number): return self.Records[record_number] def QueryPrep(self,query,case_sensitive): #-- Clear the previous query buffer. self.QuerySet=[] self.QueryCaseSensitive=case_sensitive #-- Is this a singular query or a union query? Lqueries=[] if type(query)==types.ListType: Lqueries=query else: Lqueries=[query] return Lqueries def Select(self,query,case_sensitive=0): Lqueries=self.QueryPrep(query,case_sensitive) qset=[] for q in Lqueries: self.Query=q qset=qset+filter(self.QueryMatch,range(len(self.Records))) return map(self.GetRecord,qset) def Insert(self,records): if type(records)==types.ListType: return_values=[] for record in records: return_values.append(self.Insert(record)) return return_values if type(records)==types.DictType: self.Records.append(records) return len(self.Records)-1 def Delete(self,query,case_sensitive=0): deletion_set=self.Select(query,case_sensitive) for record in deletion_set: del self.Records[self.Records.index(record)] return deletion_set #-- Returns a list of all attributes in the textbase. def Attributes(self): attributes=[] for record in self.Records: for attribute in record.keys(): if attribute not in attributes: attributes.append(attribute) return attributes