Advertisement
Guest User

Untitled

a guest
Apr 25th, 2017
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.50 KB | None | 0 0
  1. """Test for s7."""
  2. import psycopg2
  3.  
  4.  
  5. class Relations(object):
  6. """Wrapper class to iterate db rows as sets."""
  7.  
  8. def __init__(self):
  9. """Setting up a cursor."""
  10. self.connection = psycopg2.connect('dbname=test user=postgres')
  11. self.cursor = self.connection.cursor('components') # serverside cursor
  12. self.cursor.execute(
  13. 'SELECT object_id, relative_ids FROM relations;'
  14. )
  15.  
  16. def __iter__(self):
  17. """Iterator interface."""
  18. return self
  19.  
  20. def __next__(self):
  21. """Python 3 compatibiliy."""
  22. return self.next()
  23.  
  24. def next(self):
  25. """Next row as combined set."""
  26. # next() call will raise StopIteration on cursor exhaustion,
  27. # no need to wrap that since for-loop will handle it by itself
  28. # but we want to free resources as soon as possible.
  29. try:
  30. object_id, relations = next(self.cursor)
  31. except StopIteration:
  32. self.cursor.close()
  33. self.connection.close()
  34. raise
  35.  
  36. return set([object_id] + relations)
  37.  
  38. def __del__(self):
  39. """Free resources on gc."""
  40. self.cursor.close()
  41. self.connection.close()
  42.  
  43.  
  44. class Ids(object):
  45. """Wrapper class to iterate db rows as single integers."""
  46.  
  47. def __init__(self):
  48. """Setting up a cursor."""
  49. self.connection = psycopg2.connect('dbname=test user=postgres')
  50. self.cursor = self.connection.cursor('ids') # serverside cursor
  51. self.cursor.execute('SELECT id FROM objects;')
  52.  
  53. def __iter__(self):
  54. """Iterator interface."""
  55. return self
  56.  
  57. def __next__(self):
  58. """Python 3 compatibiliy."""
  59. return self.next()
  60.  
  61. def next(self):
  62. """Next row as combined set."""
  63. # next() call will raise StopIteration on cursor exhaustion,
  64. # no need to wrap that since for-loop will handle it by itself
  65. # but we have to free connection as soon as possible.
  66. ident = next(self.cursor)
  67. return ident[0]
  68.  
  69. def __del__(self):
  70. """Free resources on gc."""
  71. self.cursor.close()
  72. self.connection.close()
  73.  
  74.  
  75. def make_components(relations):
  76. """Return list of components (sets) from relations list of sets."""
  77. components = []
  78. for relation in relations:
  79. merged = True
  80. while merged:
  81. merged = False
  82. for index, component in enumerate(components):
  83. if relation & component:
  84. relation |= components.pop(index)
  85. merged = True
  86. break
  87. components.append(relation)
  88. return components
  89.  
  90.  
  91. def include_ids(ids, components):
  92. """Add id as sole-value component if one not found in relations."""
  93. for ident in ids:
  94. not_found = True
  95. for component in components:
  96. if ident in component:
  97. not_found = False
  98. break
  99. if not_found:
  100. components.append({ident})
  101. return components
  102.  
  103. relations = Relations()
  104. components = make_components(relations)
  105. ids = Ids()
  106. components = include_ids(ids, components)
  107.  
  108. # components have not to intersect
  109. assert all((
  110. (not a & b)
  111. for ia, a in enumerate(components)
  112. for ib, b in enumerate(components)
  113. if ia != ib
  114. )), [ # Assertion error output
  115. (a, b, a & b)
  116. for ia, a in enumerate(components)
  117. for ib, b in enumerate(components)
  118. if ia != ib and a & b
  119. ]
  120. # all ids have to take part in components, even empty ones
  121. assert ids == set.union(*components), (ids, set.union(*components))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement