initialise repo
[debian/make-magic.git] / core / store.py
1 #! /usr/bin/env python
2
3 '''persistant storage of state data
4
5 We need some way to keep track of Tasks that are being worked on,
6 the state of items etc. It would be even cooler if that data was
7 to hang around when the process was gone.
8 '''
9
10 try: import pymongo
11 except: pass    # allow import where noone is using the MongoStore
12
13 import config
14 import random
15
16 class MongoStore(object):
17         '''persistant mongodb store'''
18
19         def __init__(self):
20                 self.connection = pymongo.Connection(config.mongodb_server,config.mongodb_port)
21                 self.db = self.connection[config.mongodb_database]
22         def get_tasks(self):
23                 return [name for name in self.db.collection_names() if 'system.' not in name]
24         def new_task(self, uuid, items, metadata=None):
25                 if metadata == None: metadata = {}
26                 metadata['uuid'] = uuid
27                 metadata['metadata'] = True
28                 self.db[uuid].create_index('name')
29                 self.db[uuid].create_index('metadata')
30                 self.db[uuid].insert(items)
31                 self.db[uuid].insert(metadata)
32         def _noid(self, item):
33                 if item is None or '_id' not in item: return item
34                 del item['_id']
35                 return item
36         def item(self, uuid, name):
37                 '''get a specific item for a task'''
38                 return self._noid( self.db[uuid].find_one({'name': name}) )
39         def items(self, uuid):
40                 '''get all the items for a task'''
41                 # ALL THE THINGS!
42                 return [self._noid(item) for item in self.db[uuid].find({'name': {'$exists': True},'metadata': {'$exists': False}})]
43         def metadata(self, uuid):
44                 '''get metadata for a task'''
45                 metadata = self.db[uuid].find_one({'metadata': {'$exists': True}})
46                 return self._noid(metadata)
47         def update_item(self, uuid, name, updatedict, existingstate={}):
48                 '''updates an item similar to dict.update()
49
50                 if 'existingdict' is supplied, the update will only succeed if 
51                 the items in existingdict match what is in the item already
52
53                 returns the contents of the item after the attempt is made. 
54                 It is up to the caller to check if the update worked or failed.
55                 '''
56                 matchon = dict(existingstate)
57                 matchon['name'] = name
58                 self.db[uuid].update(matchon, {'$set': updatedict})
59                 return self.item(uuid, name)
60         def update_metadata(self, uuid, updatedict, existingstate={}):
61                 '''updates a metadata similar to dict.update()
62
63                 if 'existingdict' is supplied, the update will only succeed if 
64                 the items in existingdict match what is in the metadata already
65
66                 returns the contents of the metadata after the attempt is made. 
67                 It is up to the caller to check if the update worked or failed.
68                 '''
69                 matchon = dict(existingstate)
70                 matchon['metadata'] = {'$exists': True}
71                 self.db[uuid].update(matchon, {'$set': updatedict})
72                 return self.metadata(uuid)
73         def delete_task(self, uuid):
74                 '''delete a task, all it's items, and all it's metadata
75
76                 This is not recoverable.
77                 '''
78                 self.db[uuid].drop()
79
80 # Define the default Store here
81 Store = MongoStore