|
@@ -11,13 +11,23 @@ import urllib
|
11
|
11
|
|
12
|
12
|
from lodel import logger
|
13
|
13
|
|
14
|
|
-from .utils import mongodbconnect, object_collection_name, MONGODB_SORT_OPERATORS_MAP
|
|
14
|
+from .utils import mongodbconnect, object_collection_name, \
|
|
15
|
+ connect, MONGODB_SORT_OPERATORS_MAP
|
15
|
16
|
|
16
|
17
|
class MongoDbDataSourceError(Exception):
|
17
|
18
|
pass
|
18
|
19
|
|
19
|
20
|
class MongoDbDatasource(object):
|
20
|
21
|
|
|
22
|
+ ##@brief Stores existing connections
|
|
23
|
+ #
|
|
24
|
+ #The key of this dict is a hash of the connection string + ro parameter.
|
|
25
|
+ #The value is a dict with 2 keys :
|
|
26
|
+ # - conn_count : the number of instanciated datasource that use this
|
|
27
|
+ #connection
|
|
28
|
+ # - db : the pymongo database object instance
|
|
29
|
+ _connections = dict()
|
|
30
|
+
|
21
|
31
|
##@brief Mapping from lodel2 operators to mongodb operator
|
22
|
32
|
lodel2mongo_op_map = {
|
23
|
33
|
'=':'$eq', '<=':'$lte', '>=':'$gte', '!=':'$ne', '<':'$lt',
|
|
@@ -26,10 +36,34 @@ class MongoDbDatasource(object):
|
26
|
36
|
mongo_op_re = ['$in', '$nin']
|
27
|
37
|
wildcard_re = re.compile('[^\\\\]\*')
|
28
|
38
|
|
29
|
|
- ## @brief instanciates a database object given a connection name
|
30
|
|
- # @param connection_name str
|
31
|
|
- def __init__(self, connection_name):
|
32
|
|
- self.r_database = mongodbconnect(connection_name)
|
|
39
|
+ ##@brief instanciates a database object given a connection name
|
|
40
|
+ #@param host str : hostname or IP
|
|
41
|
+ #@param port int : mongodb listening port
|
|
42
|
+ #@param db_name str
|
|
43
|
+ #@param username str
|
|
44
|
+ #@param password str
|
|
45
|
+ #@param ro bool : If True the Datasource is for read only, else the
|
|
46
|
+ #Datasource is write only !
|
|
47
|
+ def __init__(self, host, port, db_name, username, password, read_only = False):
|
|
48
|
+ ##@brief Connections infos that can be kept securly
|
|
49
|
+ self.__db_infos = {'host': host, 'port': port, 'db_name': db_name}
|
|
50
|
+ ##@brief Is the instance read only ? (if not it's write only)
|
|
51
|
+ self.__read_only = bool(read_only)
|
|
52
|
+ ##@brief Uniq ID for mongodb connection
|
|
53
|
+ self.__conn_hash= None
|
|
54
|
+ ##@brief Stores the connection to MongoDB
|
|
55
|
+ self.database = self.__connect(username, password)
|
|
56
|
+
|
|
57
|
+ ##@brief Destructor that attempt to close connection to DB
|
|
58
|
+ #
|
|
59
|
+ #Decrease the conn_count of associated MongoDbDatasource::_connections
|
|
60
|
+ #item. If it reach 0 close the connection to the db
|
|
61
|
+ #@see MongoDbDatasource::__connect()
|
|
62
|
+ def __del__(self):
|
|
63
|
+ self._connections[self.__conn_hash]['conn_count'] -= 1
|
|
64
|
+ if self._connections[self.__conn_hash]['conn_count'] <= 0:
|
|
65
|
+ self._connections[self.__conn_hash]['db'].close()
|
|
66
|
+ del(self._connections[self.__conn_hash])
|
33
|
67
|
|
34
|
68
|
##@brief returns a selection of documents from the datasource
|
35
|
69
|
#@param target Emclass
|
|
@@ -131,6 +165,24 @@ class MongoDbDatasource(object):
|
131
|
165
|
res = self.__collection.insert_many(datas_list)
|
132
|
166
|
return list(result.inserted_ids)
|
133
|
167
|
|
|
168
|
+ ##@brief Connect to database
|
|
169
|
+ #@not this method avoid opening two times the same connection using
|
|
170
|
+ #MongoDbDatasource::_connections static attribute
|
|
171
|
+ #@param host str : hostname or IP
|
|
172
|
+ #@param port int : mongodb listening port
|
|
173
|
+ #@param db_name str
|
|
174
|
+ #@param username str
|
|
175
|
+ #@param password str
|
|
176
|
+ #@param ro bool : If True the Datasource is for read only, else the
|
|
177
|
+ def __connect(self, username, password, ro):
|
|
178
|
+ conn_string = connection_string(
|
|
179
|
+ username = username, password = password, **self.__db_infos)
|
|
180
|
+ conn_string += "__ReadOnly__:"+self.__read_only
|
|
181
|
+ self.__conf_hash = conn_h = hash(conn_string)
|
|
182
|
+ if conn_h in self._connections:
|
|
183
|
+ self._connections[conn_h]['conn_count'] += 1
|
|
184
|
+ return self._connections[conn_h]['db']
|
|
185
|
+
|
134
|
186
|
##@brief Return a pymongo collection given a LeObject child class
|
135
|
187
|
#@param leobject LeObject child class (no instance)
|
136
|
188
|
#return a pymongo.collection instance
|