mirror of
https://github.com/yweber/lodel2.git
synced 2025-12-03 17:26:54 +01:00
MongoDB datasource enhancement
- Enables connections saving & auto cleaning - Preparing possibility to declare a datasource as read only
This commit is contained in:
parent
5708194875
commit
d9399bc64d
3 changed files with 68 additions and 8 deletions
|
|
@ -4,10 +4,11 @@ from lodel.settings.validator import SettingValidator
|
|||
|
||||
CONFSPEC = {
|
||||
'lodel2.datasource.mongodb_datasource.*':{
|
||||
'read_only': (True, SettingValidator('bool')),
|
||||
'host': ('localhost', SettingValidator('host')),
|
||||
'port': (None, SettingValidator('string')),
|
||||
'db_name':('lodel', SettingValidator('string')),
|
||||
'username': (None, SettingValidator('string')),
|
||||
'password': (None, SettingValidator('string'))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,13 +11,23 @@ import urllib
|
|||
|
||||
from lodel import logger
|
||||
|
||||
from .utils import mongodbconnect, object_collection_name, MONGODB_SORT_OPERATORS_MAP
|
||||
from .utils import mongodbconnect, object_collection_name, \
|
||||
connect, MONGODB_SORT_OPERATORS_MAP
|
||||
|
||||
class MongoDbDataSourceError(Exception):
|
||||
pass
|
||||
|
||||
class MongoDbDatasource(object):
|
||||
|
||||
##@brief Stores existing connections
|
||||
#
|
||||
#The key of this dict is a hash of the connection string + ro parameter.
|
||||
#The value is a dict with 2 keys :
|
||||
# - conn_count : the number of instanciated datasource that use this
|
||||
#connection
|
||||
# - db : the pymongo database object instance
|
||||
_connections = dict()
|
||||
|
||||
##@brief Mapping from lodel2 operators to mongodb operator
|
||||
lodel2mongo_op_map = {
|
||||
'=':'$eq', '<=':'$lte', '>=':'$gte', '!=':'$ne', '<':'$lt',
|
||||
|
|
@ -26,10 +36,34 @@ class MongoDbDatasource(object):
|
|||
mongo_op_re = ['$in', '$nin']
|
||||
wildcard_re = re.compile('[^\\\\]\*')
|
||||
|
||||
## @brief instanciates a database object given a connection name
|
||||
# @param connection_name str
|
||||
def __init__(self, connection_name):
|
||||
self.r_database = mongodbconnect(connection_name)
|
||||
##@brief instanciates a database object given a connection name
|
||||
#@param host str : hostname or IP
|
||||
#@param port int : mongodb listening port
|
||||
#@param db_name str
|
||||
#@param username str
|
||||
#@param password str
|
||||
#@param ro bool : If True the Datasource is for read only, else the
|
||||
#Datasource is write only !
|
||||
def __init__(self, host, port, db_name, username, password, read_only = False):
|
||||
##@brief Connections infos that can be kept securly
|
||||
self.__db_infos = {'host': host, 'port': port, 'db_name': db_name}
|
||||
##@brief Is the instance read only ? (if not it's write only)
|
||||
self.__read_only = bool(read_only)
|
||||
##@brief Uniq ID for mongodb connection
|
||||
self.__conn_hash= None
|
||||
##@brief Stores the connection to MongoDB
|
||||
self.database = self.__connect(username, password)
|
||||
|
||||
##@brief Destructor that attempt to close connection to DB
|
||||
#
|
||||
#Decrease the conn_count of associated MongoDbDatasource::_connections
|
||||
#item. If it reach 0 close the connection to the db
|
||||
#@see MongoDbDatasource::__connect()
|
||||
def __del__(self):
|
||||
self._connections[self.__conn_hash]['conn_count'] -= 1
|
||||
if self._connections[self.__conn_hash]['conn_count'] <= 0:
|
||||
self._connections[self.__conn_hash]['db'].close()
|
||||
del(self._connections[self.__conn_hash])
|
||||
|
||||
##@brief returns a selection of documents from the datasource
|
||||
#@param target Emclass
|
||||
|
|
@ -131,6 +165,24 @@ class MongoDbDatasource(object):
|
|||
res = self.__collection.insert_many(datas_list)
|
||||
return list(result.inserted_ids)
|
||||
|
||||
##@brief Connect to database
|
||||
#@not this method avoid opening two times the same connection using
|
||||
#MongoDbDatasource::_connections static attribute
|
||||
#@param host str : hostname or IP
|
||||
#@param port int : mongodb listening port
|
||||
#@param db_name str
|
||||
#@param username str
|
||||
#@param password str
|
||||
#@param ro bool : If True the Datasource is for read only, else the
|
||||
def __connect(self, username, password, ro):
|
||||
conn_string = connection_string(
|
||||
username = username, password = password, **self.__db_infos)
|
||||
conn_string += "__ReadOnly__:"+self.__read_only
|
||||
self.__conf_hash = conn_h = hash(conn_string)
|
||||
if conn_h in self._connections:
|
||||
self._connections[conn_h]['conn_count'] += 1
|
||||
return self._connections[conn_h]['db']
|
||||
|
||||
##@brief Return a pymongo collection given a LeObject child class
|
||||
#@param leobject LeObject child class (no instance)
|
||||
#return a pymongo.collection instance
|
||||
|
|
|
|||
|
|
@ -46,12 +46,19 @@ def get_connection_args(connnection_name='default'):
|
|||
# @return MongoClient
|
||||
def mongodbconnect(connection_name):
|
||||
login, password, host, port, dbname = get_connection_args(connection_name)
|
||||
connection_string = 'mongodb://%s:%s@%s:%s' % (login, password, host, port)
|
||||
connection = MongoClient(connection_string)
|
||||
return connect(host, port, db_name, username, password)
|
||||
|
||||
def connection_string(host, port, db_name, username, password):
|
||||
return 'mongodb://%s:%s@%s:%s' % (login, password, host, port)
|
||||
|
||||
def connect(host, port, db_name, username, password):
|
||||
connection = MongoClient(
|
||||
connection_string(host, port, db_name, username, password))
|
||||
database = connection[dbname]
|
||||
return database
|
||||
|
||||
|
||||
|
||||
## @brief Returns a collection name given a EmClass
|
||||
# @param class_object EmClass
|
||||
# @return str
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue