# KVS.py 27/05/2016 D.J.Whale
#
# A generic key value store
from lifecycle import *
class KVSFile():
"""A persistent key value store"""
def __init__(self, filename=None):
self.filename = filename
self.store = {}
@unimplemented
def load(self, factory):
"""Load the whole file into an in-memory cache"""
# The 'factory' is a place to go to turn device type names into actual class instances
pass #TODO
# open file for read
# for each line read
# if in command mode
# if blank line, ignore it
# else not blank line
# split line, first word is command, second word is the key
# remember both
# change to data mode
# else in data mode
# if not blank line
# grab key=value
# add to temporary object
# else blank line
# process command,key,values
# now eof
# process command,key,values, if it command is not empty
# close file
@unimplemented
def process(self, command, key, values):
"""Process the temporary object"""
pass #TODO
# getattr method associated with the command name, error if no method
# pass the key,values to that method to let it be processed
@unimplemented
def ADD(self, key, values):
"""Add a new item to the kvs"""
# The ADD command process the next type= parameter as the class name in context
# all other parameters are read as strings and passed to class constructor as kwargs
pass #TODO
# add key=values to the in memory object store
# open file for append
# write ADD command with key
# for all keys in value
# write k=v
# close file
@unimplemented
def IGN(self, key, values=None):
"""Ignore the whole record"""
# The IGN command is the same length as ADD, allowing a seek/write to change any
# command into IGN without changing the file size, effectively patching the file
# so that the record is deleted.
pass # There is nothing to do with this command
@unimplemented
def DEL(self, key, values=None):
"""Delete the key from the store"""
# The DEL command deletes the rec from the store.
# This is useful to build temporary objects and delete them later.
# There is no need to write this to the file copy, we're processing the file
pass #TODO
# find key in object store, delete it
@untested
def __getitem__(self, key):
return self.store[key]
@untested
def __setitem__(self, key, value):
self.store[key] = value
self.append(key, value)
@untested
def __delitem__(self, key):
del self.store[key]
self.remove(key)
@untested
def keys(self):
return self.store.keys()
@untested
def size(self):
return len(self.store)
def append(self, key, values):
"""Append a new record to the persistent file"""
with open(self.filename, 'a') as f:
f.write("ADD %s\n" % key)
for k in values:
v = values[k]
f.write("%s=%s\n" % (k, v))
f.write("\n")
@unimplemented
def remove(self, key):
"""Remove reference to this key in the file, and remove from in memory store"""
pass #TODO
# open file for read write
# search line at a time, process each command
# when we find the command 'ADD key'
# reseek to start of line
# write overwrite ADD with IGN
# keep going in case of duplicates
# close file
@unimplemented
def rewrite(self):
"""Rewrite the whole in memory cache over the top of the external file"""
# useful if you have updated the in memory copy only and want to completely regenerate
pass #TODO
# create file new, for write only
# for all objects in the store by key
# get value
# write ADD command key
# for all values
# write k=v
# write blank line
# close file
# END