PageRenderTime 1019ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/weave/server/storage/sql.py

https://bitbucket.org/tarek/python-weave-server
Python | 289 lines | 267 code | 10 blank | 12 comment | 1 complexity | 06e367892dd648d47668c476ec691243 MD5 | raw file
  1. """
  2. username and (collection)name are the ids/
  3. """
  4. from sqlalchemy import create_engine
  5. from sqlalchemy.sql import text
  6. from weave.server.storage import register
  7. from weave.server.storage.sqlmappers import tables
  8. _SQLURI = 'mysql://sync:sync@localhost/sync'
  9. engine = create_engine(_SQLURI)
  10. for table in tables:
  11. table.metadata.bind = engine
  12. class WeaveSQLStorage(object):
  13. def __init__(self):
  14. self._conn = engine.connect()
  15. def get_name(self):
  16. """Returns the name of the storage"""
  17. return 'sql'
  18. #
  19. # Users APIs -- the user identifier is the 'username' field
  20. #
  21. def user_exists(self, user_name):
  22. """Returns true if the user exists."""
  23. query = text('select id from users where username = :username')
  24. res = self._conn.execute(query, username=user_name).fetchone()
  25. return res is not None
  26. def set_user(self, user_name, **values):
  27. """set information for a user. values contains the fields to set.
  28. If the user doesn't exists, it will be created."""
  29. values['username'] = user_name
  30. if not self.user_exists(user_name):
  31. fields = values.keys()
  32. params = ','.join([':%s' % field for field in fields])
  33. fields = ','.join(fields)
  34. query = text('insert into users (%s) values (%s)' % \
  35. (fields, params))
  36. else:
  37. fields = values.keys()
  38. params = ','.join(['%s = :%s' % (field, field)
  39. for field in fields])
  40. query = text('update users set %s where username = :username' \
  41. % params)
  42. return self._conn.execute(query, **values)
  43. def get_user(self, user_name, fields=None):
  44. """Returns user information.
  45. If fields is provided, its a list of fields to return
  46. """
  47. if fields is None:
  48. fields = ['*']
  49. fields = ', '.join(fields)
  50. query = text('select %s from users where username = :username' \
  51. % fields)
  52. return self._conn.execute(query, username=user_name).first()
  53. def delete_user(self, user_name):
  54. """Removes a user (and all its data)"""
  55. user_id = self._get_user_id(user_name)
  56. # remocing collections
  57. query = text('delete from collections where '
  58. 'userid = :userid')
  59. self._conn.execute(query, userid=user_id)
  60. # removing items
  61. query = text('delete from wbo where '
  62. 'username = :userid')
  63. self._conn.execute(query, userid=user_id)
  64. # XXX remove reset codes
  65. # removing user
  66. query = 'delete from users where username = :username'
  67. return self._conn.execute(query, username=user_name)
  68. def _get_user_id(self, user_name):
  69. """Returns a user id, given the name
  70. XXX We need to cache this, or to alter the DB (userid -> username)
  71. """
  72. data = self.get_user(user_name, ['id'])
  73. if data is None:
  74. return None
  75. return data[0]
  76. def _get_collection_id(self, user_name, collection_name):
  77. """Returns a collection id, given the name
  78. XXX We need to cache this, or to alter the DB
  79. """
  80. data = self.get_collection(user_name, collection_name,
  81. ['collectionid'])
  82. if data is None:
  83. return None
  84. return data[0]
  85. #
  86. # Collections APIs
  87. #
  88. def delete_collection(self, user_name, collection_name):
  89. """deletes a collection"""
  90. if not self.collection_exists(user_name, collection_name):
  91. return
  92. # removing items first
  93. self.delete_items(user_name, collection_name)
  94. user_id = self._get_user_id(user_name)
  95. query = text('delete from collections where '
  96. 'userid = :userid and name = :name')
  97. return self._conn.execute(query, userid=user_id, name=collection_name)
  98. def collection_exists(self, user_name, collection_name):
  99. """Returns True if the collection exists"""
  100. user_id = self._get_user_id(user_name)
  101. query = text('select collectionid from collections where '
  102. 'userid = :userid and name = :name')
  103. res = self._conn.execute(query, userid=user_id,
  104. name=collection_name)
  105. res = res.fetchone()
  106. return res is not None
  107. def set_collection(self, user_name, collection_name, **values):
  108. """Creates a collection"""
  109. # XXX values is not used for now because there are no values besides
  110. # the name
  111. if self.collection_exists(user_name, collection_name):
  112. return
  113. user_id = self._get_user_id(user_name)
  114. values['userid'] = user_id
  115. values['name'] = collection_name
  116. # getting the max collection_id
  117. # XXX why don't we have an autoinc here ?
  118. # instead
  119. max = ('select max(collectionid) from collections where '
  120. 'userid = :userid')
  121. max = self._conn.execute(max, userid=user_id).first()
  122. if max[0] is None:
  123. next_id = 1
  124. else:
  125. next_id = max[0] + 1
  126. # insertion
  127. values['collectionid'] = next_id
  128. fields = values.keys()
  129. params = ','.join([':%s' % field for field in fields])
  130. fields = ','.join(fields)
  131. query = text('insert into collections (%s) values (%s)' % \
  132. (fields, params))
  133. return self._conn.execute(query, **values)
  134. def get_collection(self, user_name, collection_name, fields=None):
  135. """Return information about a collection."""
  136. user_id = self._get_user_id(user_name)
  137. if fields is None:
  138. fields = ['*']
  139. fields = ', '.join(fields)
  140. query = text('select %s from collections where '
  141. 'userid = :userid and name = :name'\
  142. % fields)
  143. return self._conn.execute(query, userid=user_id,
  144. name=collection_name).first()
  145. def get_collections(self, user_name, fields=None):
  146. """returns the collections information """
  147. user_id = self._get_user_id(user_name)
  148. if fields is None:
  149. fields = ['*']
  150. fields = ', '.join(fields)
  151. query = text('select %s from collections where userid = :userid'
  152. % fields)
  153. return self._conn.execute(query, userid=user_id).fetchall()
  154. def get_collection_names(self, user_name):
  155. """return the collection names for a given user"""
  156. user_id = self._get_user_id(user_name)
  157. query = text('select name from collections '
  158. 'where userid = :userid')
  159. return self._conn.execute(query, userid=user_id).fetchall()
  160. #
  161. # Items APIs
  162. #
  163. def item_exists(self, user_name, collection_name, item_id):
  164. """Returns True if an item exists."""
  165. user_id = self._get_user_id(user_name)
  166. collection_id = self._get_collection_id(user_name, collection_name)
  167. query = text('select id from wbo where '
  168. 'username = :user_id and collection = :collection_id')
  169. res = self._conn.execute(query, user_id=user_id,
  170. collection_id=collection_id)
  171. res = res.fetchone()
  172. return res is not None
  173. def get_items(self, user_name, collection_name, fields=None):
  174. """returns items from a collection"""
  175. user_id = self._get_user_id(user_name)
  176. collection_id = self._get_collection_id(user_name, collection_name)
  177. if fields is None:
  178. fields = ['*']
  179. fields = ', '.join(fields)
  180. query = text('select %s from wbo where '
  181. 'username = :user_id and collection = :collection_id'\
  182. % fields)
  183. return self._conn.execute(query, user_id=user_id,
  184. collection_id=collection_id).fetchall()
  185. def get_item(self, user_name, collection_name, item_id, fields=None):
  186. """returns one item"""
  187. user_id = self._get_user_id(user_name)
  188. collection_id = self._get_collection_id(user_name, collection_name)
  189. if fields is None:
  190. fields = ['*']
  191. fields = ', '.join(fields)
  192. query = text('select %s from wbo where '
  193. 'username = :user_id and collection = :collection_id '
  194. 'and id = :item_id ' % fields)
  195. return self._conn.execute(query, user_id=user_id, item_id=item_id,
  196. collection_id=collection_id).first()
  197. def set_item(self, user_name, collection_name, item_id, **values):
  198. """Adds or update an item"""
  199. values['username'] = self._get_user_id(user_name)
  200. values['collection'] = self._get_collection_id(user_name,
  201. collection_name)
  202. values['id'] = item_id
  203. if not self.item_exists(user_name, collection_name, item_id):
  204. fields = values.keys()
  205. params = ','.join([':%s' % field for field in fields])
  206. fields = ','.join(fields)
  207. query = text('insert into wbo (%s) values (%s)' % \
  208. (fields, params))
  209. else:
  210. fields = values.keys()
  211. params = ','.join(['%s = :%s' % (field, field)
  212. for field in fields if field != ''])
  213. query = text('update wbo set %s where id = :id' \
  214. % params)
  215. return self._conn.execute(query, **values)
  216. def delete_item(self, user_name, collection_name, item_id):
  217. """Deletes an item"""
  218. user_id = self._get_user_id(user_name)
  219. collection_id = self._get_collection_id(user_name, collection_name)
  220. query = text('delete from wbo where username = :user_id and '
  221. 'collection = :collection_id and id = :item_id')
  222. return self._conn.execute(query, user_id=user_id,
  223. collection_id=collection_id, item_id=item_id)
  224. def delete_items(self, user_name, collection_name, item_ids=None):
  225. """Deletes items. All items are removed unless item_ids is provided"""
  226. user_id = self._get_user_id(user_name)
  227. collection_id = self._get_collection_id(user_name, collection_name)
  228. if item_ids is None:
  229. query = text('delete from wbo where username = :user_id and '
  230. 'collection = :collection_id')
  231. else:
  232. ids = ', '.join(item_ids)
  233. query = text('delete from wbo where username = :user_id and '
  234. 'collection = :collection_id and id in (%s)' % ids)
  235. return self._conn.execute(query, user_id=user_id,
  236. collection_id=collection_id)
  237. register(WeaveSQLStorage)