diff --git a/EditorialModel/components.py b/EditorialModel/components.py index b55fad7..4af64e2 100644 --- a/EditorialModel/components.py +++ b/EditorialModel/components.py @@ -6,8 +6,6 @@ import datetime import logging -import sqlalchemy as sql -from Database import sqlutils import EditorialModel.fieldtypes as ftypes from collections import OrderedDict @@ -21,12 +19,6 @@ logger = logging.getLogger('Lodel2.EditorialModel') # @pure class EmComponent(object): - ## The name of the engine configuration - # @todo Not a good idea to store it here - dbconf = 'default' - ## The table in wich we store data for this object - # None for EmComponent - table = None ## Used by EmComponent::modify_rank ranked_in = None @@ -53,14 +45,7 @@ class EmComponent(object): # @param id_or_name int|str: name or id of the object # @throw TypeError if id_or_name is not an integer nor a string # @throw NotImplementedError if called with EmComponent - def __init__(self, id_or_name, dbconf = 'default'): - - self.dbconf = dbconf - if self.dbconf: - self.db_engine = sqlutils.get_engine(dbconf) - else: - self.db_engine = False - + def __init__(self, id_or_name): if type(self) == EmComponent: raise NotImplementedError('Abstract class') @@ -77,7 +62,6 @@ class EmComponent(object): self.name = id_or_name else: raise TypeError('Bad argument: expecting or but got : ' + str(type(id_or_name))) - self.table = self.__class__.table self.populate() ## @brief Access an attribute of an EmComponent @@ -124,10 +108,9 @@ class EmComponent(object): def __eq__(self, other): return self.__class__ == other.__class__ and self.uid == other.uid - ## Lookup in the database properties of the object to populate the properties - # @throw EmComponentNotExistError if the instance is not anymore stored in database + ## Set all fields def populate(self): - records = self._populate_db() # Db query + records = [] # TODO for record in records: for keys in self._fields.keys(): @@ -136,34 +119,7 @@ class EmComponent(object): super(EmComponent, self).__setattr__('deleted', False) - #@classmethod - ## Shortcut that return the sqlAlchemy engine - #def db_engine(cls): - # return sqlutils.get_engine(cls.dbconf) - - ## Do the query on the database for EmComponent::populate() - # @throw EmComponentNotExistError if the instance is not anymore stored in database - def _populate_db(self): - dbe = self.db_engine - component = sql.Table(self.table, sqlutils.meta(dbe)) - req = sql.sql.select([component]) - - if self.uid is None: - req = req.where(component.c.name == self.name) - else: - req = req.where(component.c.uid == self.uid) - conn = dbe.connect() - res = conn.execute(req) - - res = res.fetchall() - conn.close() - - if not res or len(res) == 0: - raise EmComponentNotExistError("No " + self.__class__.__name__ + " found with " + ('name ' + self.name if self.uid is None else 'uid ' + str(self.uid))) - - return res - - ## Insert a new component in the database + ## Insert a new component # # This function create and assign a new UID and handle the date_create and date_update values # @warning There is a mandatory argument dbconf that indicate wich database configuration to use @@ -182,118 +138,45 @@ class EmComponent(object): if argname in ['date_update', 'date_create', 'rank', 'uid']: # Automatic properties raise TypeError("Invalid argument : " + argname) elif argname not in valid_args: - raise TypeError("Unexcepted keyword argument '"+argname+"' for "+cls.__name__+" creation") - + raise TypeError("Unexcepted keyword argument '" + argname + "' for " + cls.__name__ + " creation") + #Check uniq names constraint try: name = kwargs['name'] exist = cls(name) for kname in kwargs: if not (getattr(exist, kname) == kwargs[kname]): - raise EmComponentExistError("An "+cls.__name__+" named "+name+" allready exists with a different "+kname) - logger.info("Trying to create an "+cls.__name__+" that allready exist with same attribute. Returning the existing one") + raise EmComponentExistError("An " + cls.__name__ + " named " + name + " allready exists with a different " + kname) + logger.info("Trying to create an " + cls.__name__ + " that allready exist with same attribute. Returning the existing one") return exist except EmComponentNotExistError: pass - - # Mandatory fields check (actual fieldtypes don't allow this check - #for name in cls._fields: - # if cls._fields[name].notNull and cls._fields[name].default == None: - # raise TypeError("Missing argument : "+name) - if 'dbconf' in kwargs: - if not kwargs['db_engine']: - raise NotImplementedError("Its a nonsense to call create with no database") - dbconf = kwargs['dbconf'] - else: - dbconf = 'default' - dbe = sqlutils.get_engine(dbconf) - - kwargs['uid'] = cls.new_uid(dbe) + kwargs['uid'] = cls.new_uid() kwargs['date_update'] = kwargs['date_create'] = datetime.datetime.utcnow() - conn = dbe.connect() - kwargs['rank'] = cls._get_max_rank( kwargs[cls.ranked_in], dbe )+1 - table = sql.Table(cls.table, sqlutils.meta(dbe)) - req = table.insert(kwargs) - if not conn.execute(req): - raise RuntimeError("Unable to create the "+cls.__class__.__name__+" EmComponent ") - conn.close() return cls(kwargs['name'], dbconf) - ## Write the representation of the component in the database - # @return bool - # @todo stop using datetime.datetime.utcnow() for date_update update - def save(self): - values = {} - for name, field in self._fields.items(): - values[name] = field.to_sql() - - # Don't allow creation date overwritting - #if 'date_create' in values: - #del values['date_create'] - #logger.warning("date_create supplied for save, but overwritting of date_create not allowed, the date will not be changed") - - values['date_update'] = datetime.datetime.utcnow() - - self._save_db(values) - - ## Do the query in the datbase for EmComponent::save() - # @param values dict: A dictionnary of the values to insert - # @throw RunTimeError if it was unable to do the Db update - def _save_db(self, values): - """ Do the query on the db """ - dbe = self.db_engine - component = sql.Table(self.table, sqlutils.meta(dbe)) - req = sql.update(component, values=values).where(component.c.uid == self.uid) - - conn = dbe.connect() - res = conn.execute(req) - conn.close() - if not res: - raise RuntimeError("Unable to save the component in the database") - - ## Delete this component data in the database + ## Delete this component # @return bool : True if deleted False if deletion aborded # @throw RunTimeError if it was unable to do the deletion def delete(self): - # - dbe = self.db_engine - component = sql.Table(self.table, sqlutils.meta(dbe)) - req = component.delete().where(component.c.uid == self.uid) - conn = dbe.connect() - res = conn.execute(req) - conn.close() - if not res: - raise RuntimeError("Unable to delete the component in the database") - - # - super(EmComponent, self).__setattr__('deleted', True) - return True + pass ## @brief Get the maximum rank given an EmComponent child class and a ranked_in filter # @param ranked_in_value mixed: The rank "family" # @return -1 if no EmComponent found else return an integer >= 0 @classmethod - def _get_max_rank(cls, ranked_in_value, dbe): - component = sql.Table(cls.table, sqlutils.meta(dbe)) - req = sql.sql.select([component.c.rank]).where(getattr(component.c, cls.ranked_in) == ranked_in_value).order_by(component.c.rank.desc()) - c = dbe.connect() - res = c.execute(req) - res = res.fetchone() - c.close() - if res != None: - return res['rank'] - else: - return -1 + def _get_max_rank(cls, ranked_in_value): + pass ## Only make a call to the class method # @return A positive integer or -1 if no components # @see EmComponent::_get_max_rank() def get_max_rank(self, ranked_in_value): - return self.__class__._get_max_rank(ranked_in_value, self.db_engine) + return self.__class__._get_max_rank(ranked_in_value) ## Set a new rank for this component # @note This function assume that ranks are properly set from 1 to x with no gap @@ -334,12 +217,12 @@ class EmComponent(object): req = table.update().where(table.c.uid == sql.bindparam('b_uid')).values(rank=sql.bindparam('b_rank')) res = conn.execute(req, updated_ranks) conn.close() - + if res: #Instance rank update self._fields['rank'].value = new_rank return bool(res) - + ## @brief Modify a rank given a sign and a new_rank # - If sign is '=' set the rank to new_rank # - If sign is '-' set the rank to cur_rank - new_rank