123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- import os.path
- from lodel.context import LodelContext
-
- LodelContext.expose_modules(globals(), {
- 'lodel.plugin.datasource_plugin': ['AbstractDatasource', 'DatasourcePlugin'],
- 'lodel.logger': 'logger',
- 'lodel.exceptions': ['LodelFatalError'],
- 'lodel.settings': 'Settings'})
-
- from .fs_utils import *
- from .specs import check as check_leo
- from .exceptions import *
-
-
- ##@brief This datasource handles site creation
- #@note Filters evaluation is forwarded to child datasource using our select
- #method. Not optimized but much simple
- class Datasource(AbstractDatasource):
-
- ##@brief Constructor
- #
- #Handles child datasource instanciation
- #@param db_datasource str : datasource identifier
- #@param db_datasource_ro str : read only datasource identitifer
- def __init__(self, db_datasource, db_datasource_ro = None):
- if db_datasource_ro is None:
- db_datasource_ro = db_datasource
- self._child_ds = DatasourcePlugin.init_datasource(
- db_datasource, False)
- self._child_ds_ro = DatasourcePlugin.init_datasource(
- db_datasource, True)
- pass
-
- ##@brief Checks that given emcomponent is compatible with datasource
- #behavior
- #@warning 100% hardcoded checks on leo name fieldnames & types
- #@param emcomp LeObject subclass (or instance)
- #@throws LodelFatalError if not compatible
- @staticmethod
- def __assert_good_leo(leo):
- res, reason = check_leo(leo)
- if not res:
- msg = 'Bad leo given : %s because %s' % (leo, reason)
- logger.critical(msg)
- raise LodelFatalError(msg)
-
- ##@brief Provide a new uniq numeric ID
- #@param emcomp LeObject subclass (not instance) : To know on wich things we
- #have to be uniq
- #@return an integer
- def new_numeric_id(self, emcomp):
- self.__assert_good_leo(emcomp)
- return self._child_ds.new_numeric_id(emcomp)
-
- ##@brief returns a selection of documents from the datasource
- #@note Simply forwarded to ro child datasource
- #@param target Emclass
- #@param field_list list
- #@param filters list : List of filters
- #@param rel_filters list : List of relational filters
- #@param order list : List of column to order. ex: order = [('title', 'ASC'),]
- #@param group list : List of tupple representing the column to group together. ex: group = [('title', 'ASC'),]
- #@param limit int : Number of records to be returned
- #@param offset int: used with limit to choose the start record
- #@param instanciate bool : If true, the records are returned as instances, else they are returned as dict
- #@return list
- def select(self, target, field_list, filters, relational_filters=None,
- order=None, group=None, limit=None, offset=0, instanciate=True):
- return self._child_ds_ro.select(
- target, field_list, relational_filters, order, group, limit, offset)
-
- ##@brief Deletes records according to given filters
- #@note lazy filters evaluation implementation : to evaluate filters &
- #rel_filters we run self.select using them
- #@param target Emclass : class of the record to delete
- #@param filters list : List of filters
- #@param relational_filters list : List of relational filters
- #@return int : number of deleted records
- def delete(self, target, filters, relational_filters):
- shortnames = self.select(
- target,
- ['shortname'],
- filters,
- relational_filters)
- for shortname in [ item['shortname'] for item in shortnames]:
- purge(shortname)
- return self._child_ds.delete(target, filters, relational_filters)
-
- ## @brief updates records according to given filters
- #
- #@note lazy filters evaluation implementation : to evaluate filters &
- #rel_filters we run self.select using them
- #@note shortname updates are forbidden
- #@param target Emclass : class of the object to update
- #@param filters list : List of filters
- #@param relational_filters list : List of relational filters
- #@param upd_datas dict : datas to update (new values)
- #@return int : Number of updated records
- def update(self, target, filters, relational_filters, upd_datas):
- if 'shortname' in upd_datas:
- raise LodelSiteDatasourceError('Unable to update the \
- shortname, it is a site identifier. The right way for doing so is to copy \
- existing site with a new name')
-
- datas = self.select(
- target,
- ['shortname', 'em_groups', 'extensions'],
- filters,
- relational_filters)
-
- for data in datas:
- if 'em_groups' in upd_datas:
- groups = upd_datas['em_groups']
- else:
- groups = data['em_groups']
- if 'extensions' in upd_datas:
- extensions = upd_datas['extensions']
- else:
- extensions = data['extensions']
-
- update_conf(**{
- 'sitename': data['shortname'],
- 'em_groups': groups,
- 'extensions': extensions})
-
- return self._child_ds.update(
- target, filters, relational_filters, upd_datas)
-
- ##@brief Inserts a record in a given collection
- #@param target Emclass : class of the object to insert
- #@param new_datas dict : datas to insert
- #@return the inserted uid
- def insert(self, target, new_datas):
- self.__assert_good_leo(target)
- if site_exists(new_datas['shortname']):
- raise LodelSiteDatasourceError('A site with "%s" as shortname \
- already exists' % (new_datas['shortname']))
- site_directories_creation(new_datas['shortname'])
- generate_conf(
- new_datas['shortname'],
- new_datas['em_groups'],
- new_datas['extensions'])
- return self._child_ds.insert(target, new_datas)
-
- ## @brief Inserts a list of records in a given collection
- #@note Here is a simple implementation : a for loop triggering
- #insert() calls
- # @param target Emclass : class of the objects inserted
- # @param datas_list list : list of dict
- # @return list : list of the inserted records' ids
- def insert_multi(self, target, datas_list):
- res = []
- for new_datas in datas_list:
- res.append(self.insert(target, datas))
- return res
-
|