38454b3b468319de03eaece5cf00e99b70279e59
[osm/RO.git] / lcm / osm_common / dbmongo.py
1 #import pymongo
2 from pymongo import MongoClient
3 from dbbase import DbException, dbbase
4 from http import HTTPStatus
5
6 class dbmongo(dbbase):
7
8 def __init__(self):
9 pass
10
11 def db_connect(self, config):
12 try:
13 self.client = MongoClient(config["host"], config["port"])
14 self.db = self.client[config["name"]]
15 # get data to try a connection
16 self.db.users.find_one({"username": "admin"})
17 except Exception as e: # TODO refine
18 raise DbException(str(e))
19
20 def db_disconnect(self):
21 pass # TODO
22
23 @staticmethod
24 def _format_filter(filter):
25 try:
26 db_filter = {}
27 for query_k, query_v in filter.items():
28 dot_index = query_k.rfind(".")
29 if dot_index > 1 and query_k[dot_index+1:] in ("eq", "ne", "gt", "gte", "lt", "lte", "cont",
30 "ncont", "neq"):
31 operator = "$" + query_k[dot_index+1:]
32 if operator == "$neq":
33 operator = "$nq"
34 k = query_k[:dot_index]
35 else:
36 operator = "$eq"
37 k = query_k
38
39 v = query_v
40 if isinstance(v, list):
41 if operator in ("$eq", "$cont"):
42 operator = "$in"
43 v = query_v
44 elif operator in ("$ne", "$ncont"):
45 operator = "$nin"
46 v = query_v
47 else:
48 v = query_v.join(",")
49
50 if operator in ("$eq", "$cont"):
51 # v cannot be a comma separated list, because operator would have been changed to $in
52 db_filter[k] = v
53 elif operator == "$ncount":
54 # v cannot be a comma separated list, because operator would have been changed to $nin
55 db_filter[k] = {"$ne": v}
56 else:
57 # maybe db_filter[k] exist. e.g. in the query string for values between 5 and 8: "a.gt=5&a.lt=8"
58 if k not in db_filter:
59 db_filter[k] = {}
60 db_filter[k][operator] = v
61
62 return db_filter
63 except Exception as e:
64 raise DbException("Invalid query string filter at {}:{}. Error: {}".format(query_k, v, e),
65 http_code=HTTPStatus.BAD_REQUEST.value)
66
67
68 def get_list(self, table, filter={}):
69 try:
70 l = []
71 collection = self.db[table]
72 rows = collection.find(self._format_filter(filter))
73 for row in rows:
74 l.append(row)
75 return l
76 except DbException:
77 raise
78 except Exception as e: # TODO refine
79 raise DbException(str(e))
80
81 def get_one(self, table, filter={}, fail_on_empty=True, fail_on_more=True):
82 try:
83 if filter:
84 filter = self._format_filter(filter)
85 collection = self.db[table]
86 if not (fail_on_empty and fail_on_more):
87 return collection.find_one(filter)
88 rows = collection.find(filter)
89 if rows.count() == 0:
90 if fail_on_empty:
91 raise DbException("Not found entry with filter='{}'".format(filter), HTTPStatus.NOT_FOUND.value)
92 return None
93 elif rows.count() > 1:
94 if fail_on_more:
95 raise DbException("Found more than one entry with filter='{}'".format(filter),
96 HTTPStatus.CONFLICT.value)
97 return rows[0]
98 except Exception as e: # TODO refine
99 raise DbException(str(e))
100
101 def del_list(self, table, filter={}):
102 try:
103 collection = self.db[table]
104 rows = collection.delete_many(self._format_filter(filter))
105 return {"deleted": rows.deleted_count}
106 except DbException:
107 raise
108 except Exception as e: # TODO refine
109 raise DbException(str(e))
110
111 def del_one(self, table, filter={}, fail_on_empty=True):
112 try:
113 collection = self.db[table]
114 rows = collection.delete_one(self._format_filter(filter))
115 if rows.deleted_count == 0:
116 if fail_on_empty:
117 raise DbException("Not found entry with filter='{}'".format(filter), HTTPStatus.NOT_FOUND.value)
118 return None
119 return {"deleted": rows.deleted_count}
120 except Exception as e: # TODO refine
121 raise DbException(str(e))
122
123 def create(self, table, indata):
124 try:
125 collection = self.db[table]
126 data = collection.insert_one(indata)
127 return data.inserted_id
128 except Exception as e: # TODO refine
129 raise DbException(str(e))
130
131 def set_one(self, table, filter, update_dict, fail_on_empty=True):
132 try:
133 collection = self.db[table]
134 rows = collection.update_one(self._format_filter(filter), {"$set": update_dict})
135 if rows.updated_count == 0:
136 if fail_on_empty:
137 raise DbException("Not found entry with filter='{}'".format(filter), HTTPStatus.NOT_FOUND.value)
138 return None
139 return {"deleted": rows.deleted_count}
140 except Exception as e: # TODO refine
141 raise DbException(str(e))
142
143 def replace(self, table, id, indata, fail_on_empty=True):
144 try:
145 collection = self.db[table]
146 rows = collection.replace_one({"_id": id}, indata)
147 if rows.modified_count == 0:
148 if fail_on_empty:
149 raise DbException("Not found entry with filter='{}'".format(filter), HTTPStatus.NOT_FOUND.value)
150 return None
151 return {"replace": rows.modified_count}
152 except Exception as e: # TODO refine
153 raise DbException(str(e))