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 = {
|
CONFSPEC = {
|
||||||
'lodel2.datasource.mongodb_datasource.*':{
|
'lodel2.datasource.mongodb_datasource.*':{
|
||||||
|
'read_only': (True, SettingValidator('bool')),
|
||||||
'host': ('localhost', SettingValidator('host')),
|
'host': ('localhost', SettingValidator('host')),
|
||||||
'port': (None, SettingValidator('string')),
|
'port': (None, SettingValidator('string')),
|
||||||
'db_name':('lodel', SettingValidator('string')),
|
'db_name':('lodel', SettingValidator('string')),
|
||||||
'username': (None, SettingValidator('string')),
|
'username': (None, SettingValidator('string')),
|
||||||
'password': (None, SettingValidator('string'))
|
'password': (None, SettingValidator('string'))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,13 +11,23 @@ import urllib
|
||||||
|
|
||||||
from lodel import logger
|
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):
|
class MongoDbDataSourceError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class MongoDbDatasource(object):
|
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
|
##@brief Mapping from lodel2 operators to mongodb operator
|
||||||
lodel2mongo_op_map = {
|
lodel2mongo_op_map = {
|
||||||
'=':'$eq', '<=':'$lte', '>=':'$gte', '!=':'$ne', '<':'$lt',
|
'=':'$eq', '<=':'$lte', '>=':'$gte', '!=':'$ne', '<':'$lt',
|
||||||
|
|
@ -26,10 +36,34 @@ class MongoDbDatasource(object):
|
||||||
mongo_op_re = ['$in', '$nin']
|
mongo_op_re = ['$in', '$nin']
|
||||||
wildcard_re = re.compile('[^\\\\]\*')
|
wildcard_re = re.compile('[^\\\\]\*')
|
||||||
|
|
||||||
## @brief instanciates a database object given a connection name
|
##@brief instanciates a database object given a connection name
|
||||||
# @param connection_name str
|
#@param host str : hostname or IP
|
||||||
def __init__(self, connection_name):
|
#@param port int : mongodb listening port
|
||||||
self.r_database = mongodbconnect(connection_name)
|
#@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
|
##@brief returns a selection of documents from the datasource
|
||||||
#@param target Emclass
|
#@param target Emclass
|
||||||
|
|
@ -131,6 +165,24 @@ class MongoDbDatasource(object):
|
||||||
res = self.__collection.insert_many(datas_list)
|
res = self.__collection.insert_many(datas_list)
|
||||||
return list(result.inserted_ids)
|
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
|
##@brief Return a pymongo collection given a LeObject child class
|
||||||
#@param leobject LeObject child class (no instance)
|
#@param leobject LeObject child class (no instance)
|
||||||
#return a pymongo.collection instance
|
#return a pymongo.collection instance
|
||||||
|
|
|
||||||
|
|
@ -46,12 +46,19 @@ def get_connection_args(connnection_name='default'):
|
||||||
# @return MongoClient
|
# @return MongoClient
|
||||||
def mongodbconnect(connection_name):
|
def mongodbconnect(connection_name):
|
||||||
login, password, host, port, dbname = get_connection_args(connection_name)
|
login, password, host, port, dbname = get_connection_args(connection_name)
|
||||||
connection_string = 'mongodb://%s:%s@%s:%s' % (login, password, host, port)
|
return connect(host, port, db_name, username, password)
|
||||||
connection = MongoClient(connection_string)
|
|
||||||
|
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]
|
database = connection[dbname]
|
||||||
return database
|
return database
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## @brief Returns a collection name given a EmClass
|
## @brief Returns a collection name given a EmClass
|
||||||
# @param class_object EmClass
|
# @param class_object EmClass
|
||||||
# @return str
|
# @return str
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue