No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

components.py 5.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. # -*- coding: utf-8 -*-
  2. """ Main object to manipulate Editorial Model
  3. parent of all other EM editing classes
  4. @see EmClass, EmType, EmFieldGroup, EmField
  5. """
  6. import datetime
  7. from Lodel.utils.mlstring import MlString
  8. import logging
  9. import sqlalchemy as sql
  10. from Database import sqlutils
  11. logger = logging.getLogger('Lodel2.EditorialModel')
  12. class EmComponent(object):
  13. dbconf = 'default' #the name of the engine configuration
  14. table = None
  15. """ instaciate an EmComponent
  16. @param id_or_name int|str: name or id of the object
  17. @exception TypeError
  18. """
  19. def __init__(self, id_or_name):
  20. if type(self) is EmComponent:
  21. raise EnvironmentError('Abstract class')
  22. if isinstance(id_or_name, int):
  23. self.id = id_or_name
  24. self.name = None
  25. elif isinstance(id_or_name, str):
  26. self.id = None
  27. self.name = id_or_name
  28. self.populate()
  29. else:
  30. raise TypeError('Bad argument: expecting <int> or <str> but got : '+str(type(id_or_name)))
  31. """ Lookup in the database properties of the object to populate the properties
  32. """
  33. def populate(self):
  34. records = self._populateDb() #Db query
  35. for record in records:
  36. row = type('row', (object,), {})()
  37. for k in record.keys():
  38. setattr(row, k, record[k])
  39. self.id = int(row.uid)
  40. self.name = row.name
  41. self.rank = 0 if row.rank is None else int(row.rank)
  42. self.date_update = row.date_update
  43. self.date_create = row.date_create
  44. self.string = MlString.load(row.string)
  45. self.help = MlString.load(row.help)
  46. return row
  47. @classmethod
  48. def getDbE(c):
  49. """ Shortcut that return the sqlAlchemy engine """
  50. return sqlutils.getEngine(c.dbconf)
  51. def _populateDb(self):
  52. """ Do the query on the db """
  53. dbe = self.__class__.getDbE()
  54. component = sql.Table(self.table, sqlutils.meta(dbe))
  55. req = sql.sql.select([component])
  56. if self.id == None:
  57. req = req.where(component.c.name == self.name)
  58. else:
  59. req = req.where(component.c.uid == self.id)
  60. c = dbe.connect()
  61. res = c.execute(req)
  62. c.close()
  63. res = res.fetchall()
  64. if not res or len(res) == 0:
  65. raise EmComponentNotExistError("No component found with "+('name '+self.name if self.id == None else 'id '+self.id ))
  66. return res
  67. ## Insert a new component in the database
  68. # This function create and assign a new UID and handle the date_create value
  69. # @param values The values of the new component
  70. # @return An instance of the created component
  71. #
  72. # @todo Check that the query didn't failed
  73. @classmethod
  74. def create(c, values):
  75. values['uid'] = c.newUid()
  76. values['date_update'] = values['date_create'] = datetime.datetime.utcnow()
  77. dbe = c.getDbE()
  78. conn = dbe.connect()
  79. table = sql.Table(c.table, sqlutils.meta(dbe))
  80. req = table.insert(values)
  81. res = conn.execute(req) #Check res?
  82. conn.close()
  83. return c(values['name']) #Maybe no need to check res because this would fail if the query failed
  84. """ write the representation of the component in the database
  85. @return bool
  86. """
  87. def save(self, values):
  88. values['name'] = self.name
  89. values['rank'] = self.rank
  90. values['date_update'] = datetime.datetime.utcnow()
  91. values['string'] = str(self.string)
  92. values['help']= str(self.help)
  93. #Don't allow creation date overwritting
  94. if 'date_create' in values:
  95. del values['date_create']
  96. logger.warning("date_create supplied for save, but overwritting of date_create not allowed, the date will not be changed")
  97. self._saveDb(values)
  98. def _saveDb(self, values):
  99. """ Do the query on the db """
  100. dbe = self.__class__.getDbE()
  101. component = sql.Table(self.table, sqlutils.meta(dbe))
  102. req = sql.update(component, values = values).where(component.c.uid == self.id)
  103. c = dbe.connect()
  104. res = c.execute(req)
  105. c.close()
  106. if not res:
  107. raise RuntimeError("Unable to save the component in the database")
  108. """ delete this component data in the database
  109. @return bool
  110. """
  111. def delete(self):
  112. #<SQL>
  113. dbe = self.__class__.getDbE()
  114. component = sql.Table(self.table, sqlutils.meta(dbe))
  115. req= component.delete().where(component.c.uid == self.id)
  116. c = dbe.connect()
  117. res = c.execute(req)
  118. c.close
  119. if not res:
  120. raise RuntimeError("Unable to delete the component in the database")
  121. #</SQL>
  122. pass
  123. """ change the rank of the component
  124. @param int new_rank new position
  125. """
  126. def modify_rank(self, new_rank):
  127. pass
  128. def __repr__(self):
  129. if self.name is None:
  130. return "<%s #%s, 'non populated'>" % (type(self).__name__, self.id)
  131. else:
  132. return "<%s #%s, '%s'>" % (type(self).__name__, self.id, self.name)
  133. @classmethod
  134. def newUid(c):
  135. """ This function register a new component in uids table
  136. @return The new uid
  137. """
  138. dbe = c.getDbE()
  139. uidtable = sql.Table('uids', sqlutils.meta(dbe))
  140. conn = dbe.connect()
  141. req = uidtable.insert(values={'table':c.table})
  142. res = conn.execute(req)
  143. uid = res.inserted_primary_key[0]
  144. logger.debug("Registering a new UID '"+str(uid)+"' for '"+c.table+"' component")
  145. conn.close()
  146. return uid
  147. class EmComponentNotExistError(Exception):
  148. pass