1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
# A database storing dictionaries, keyed on a timestamp. value = A
# dict which will be stored as a JSON object encoded in UTF-8. Note
# that dict keys of type integer or float will become strings while
# values will keep their type.
# Note that there's a (slim) chance that you'd stomp on the previous
# value if you're too quick with generating the timestamps, ie
# invoking time.time() several times quickly enough.
import os
import sys
import time
import couch
from index import CouchIindex
class DictDB():
def __init__(self):
"""
Check if the database exists, otherwise we will create it together
with the indexes specified in index.py.
"""
try:
self.database = os.environ['COUCHDB_NAME']
self.hostname = os.environ['COUCHDB_HOSTNAME']
self.username = os.environ['COUCHDB_USER']
self.password = os.environ['COUCHDB_PASSWORD']
except KeyError:
print('The environment variables COUCHDB_NAME, COUCHDB_HOSTNAME,' +
' COUCHDB_USER and COUCHDB_PASSWORD must be set.')
sys.exit(-1)
self.server = couch.client.Server(
f"http://{self.username}:{self.password}@{self.hostname}:5984/")
try:
self.couchdb = self.server.database(self.database)
except couch.exceptions.NotFound:
print("Creating database and indexes.")
self.couchdb = self.server.create(self.database)
for i in CouchIindex():
self.couchdb.index(i)
self._ts = time.time()
def unique_key(self):
"""
Create a unique key based on the current time. We will use this as
the ID for any new documents we store in CouchDB.
"""
ts = time.time()
while round(ts * 1000) == self._ts:
ts = time.time()
self._ts = round(ts * 1000)
return self._ts
def add(self, data, batch_write=False):
"""
Store a document in CouchDB.
"""
if type(data) is list:
for item in data:
item['_id'] = str(self.unique_key())
ret = self.couchdb.save_bulk(data)
else:
data['_id'] = str(self.unique_key())
ret = self.couchdb.save(data)
return ret
def get(self, key):
"""
Get a document based on its ID, return an empty dict if not found.
"""
try:
doc = self.couchdb.get(key)
except couch.exceptions.NotFound:
doc = {}
return doc
def slice(self, key_from=None, key_to=None):
pass
def search(self, limit=25, skip=0, **kwargs):
"""
Execute a Mango query, ideally we should have an index matching
the query otherwise things will be slow.
"""
data = list()
selector = dict()
try:
limit = int(limit)
skip = int(skip)
except ValueError:
limit = 25
skip = 0
if kwargs:
selector = {
"limit": limit,
"skip": skip,
"selector": {}
}
for key in kwargs:
if kwargs[key] and kwargs[key].isnumeric():
kwargs[key] = int(kwargs[key])
selector['selector'][key] = {'$eq': kwargs[key]}
for doc in self.couchdb.find(selector, wrapper=None, limit=5):
data.append(doc)
return data
|