Merge lp:~jkakar/storm/reference-set-order-by into lp:storm

Proposed by Jamu Kakar
Status: Merged
Approved by: Sidnei da Silva
Approved revision: 360
Merged at revision: 358
Proposed branch: lp:~jkakar/storm/reference-set-order-by
Merge into: lp:storm
Diff against target: 127 lines (+54/-6)
2 files modified
storm/references.py (+9/-3)
tests/store/base.py (+45/-3)
To merge this branch: bzr merge lp:~jkakar/storm/reference-set-order-by
Reviewer Review Type Date Requested Status
Sidnei da Silva (community) Approve
Gustavo Niemeyer Approve
Review via email: mp+26476@code.launchpad.net

Description of the change

This branch makes it possible to use a string, to work around
circular dependency issues, when defining the order_by property of a
ReferenceSet.

To post a comment you must log in.
Revision history for this message
Gustavo Niemeyer (niemeyer) wrote :

Nice, looks clear and good!

review: Approve
Revision history for this message
Sidnei da Silva (sidnei) wrote :

Looks great. +1!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'storm/references.py'
2--- storm/references.py 2010-02-08 11:30:44 +0000
3+++ storm/references.py 2010-06-01 08:52:24 +0000
4@@ -214,6 +214,7 @@
5 # not be available yet.
6 _relation1 = LazyAttribute("_relation1", "_build_relations")
7 _relation2 = LazyAttribute("_relation2", "_build_relations")
8+ _order_by = LazyAttribute("_order_by", "_build_relations")
9
10 def __init__(self, local_key1, remote_key1,
11 remote_key2=None, local_key2=None, order_by=None):
12@@ -221,7 +222,7 @@
13 self._remote_key1 = remote_key1
14 self._remote_key2 = remote_key2
15 self._local_key2 = local_key2
16- self._order_by = order_by
17+ self._default_order_by = order_by
18 self._cls = None
19
20 def __get__(self, local, cls=None):
21@@ -252,6 +253,11 @@
22 def _build_relations(self):
23 resolver = PropertyResolver(self, self._cls)
24
25+ if self._default_order_by is not None:
26+ self._order_by = resolver.resolve(self._default_order_by)
27+ else:
28+ self._order_by = None
29+
30 self._local_key1 = resolver.resolve(self._local_key1)
31 self._remote_key1 = resolver.resolve(self._remote_key1)
32 self._relation1 = Relation(self._local_key1, self._remote_key1,
33@@ -913,7 +919,7 @@
34 def _resolve_string(self, property_path):
35 if self._registry is None:
36 try:
37- registry = self._used_cls._storm_property_registry
38+ self._registry = self._used_cls._storm_property_registry
39 except AttributeError:
40 raise RuntimeError("When using strings on references, "
41 "classes involved must be subclasses "
42@@ -921,7 +927,7 @@
43 cls = _find_descriptor_class(self._used_cls, self._reference)
44 self._namespace = "%s.%s" % (cls.__module__, cls.__name__)
45
46- return registry.get(property_path, self._namespace)
47+ return self._registry.get(property_path, self._namespace)
48
49
50 def _find_descriptor_class(used_cls, descr):
51
52=== modified file 'tests/store/base.py'
53--- tests/store/base.py 2010-04-16 07:12:13 +0000
54+++ tests/store/base.py 2010-06-01 08:52:24 +0000
55@@ -33,13 +33,16 @@
56 Asc, Desc, Select, LeftJoin, SQL, Count, Sum, Avg, And, Or, Eq, Lower)
57 from storm.variables import Variable, UnicodeVariable, IntVariable
58 from storm.info import get_obj_info, ClassAlias
59-from storm.exceptions import *
60+from storm.exceptions import (
61+ ClosedError, ConnectionBlockedError, FeatureError, LostObjectError,
62+ NoStoreError, NotFlushedError, NotOneError, OrderLoopError, UnorderedError,
63+ WrongStoreError)
64 from storm.cache import Cache
65-from storm.store import *
66+from storm.store import AutoReload, EmptyResultSet, Store
67 from storm.store import ResultSet
68
69 from tests.info import Wrapper
70-from tests.helper import run_this, TestHelper
71+from tests.helper import TestHelper
72
73
74 class Foo(object):
75@@ -4287,6 +4290,12 @@
76 self.assertEquals(type(bar.foo), MyFoo)
77
78 def test_string_indirect_reference_set(self):
79+ """
80+ A L{ReferenceSet} can have its reference keys specified as strings
81+ when the class its a member of uses the L{PropertyPublisherMeta}
82+ metaclass. This makes it possible to work around problems with
83+ circular dependencies by delaying property resolution.
84+ """
85 class Base(object):
86 __metaclass__ = PropertyPublisherMeta
87
88@@ -4320,6 +4329,39 @@
89 (200, "Title 200"),
90 ])
91
92+ def test_string_reference_set_order_by(self):
93+ """
94+ A L{ReferenceSet} can have its default order by specified as a string
95+ when the class its a member of uses the L{PropertyPublisherMeta}
96+ metaclass. This makes it possible to work around problems with
97+ circular dependencies by delaying resolution of the order by column.
98+ """
99+ class Base(object):
100+ __metaclass__ = PropertyPublisherMeta
101+
102+ class MyFoo(Base):
103+ __storm_table__ = "foo"
104+ id = Int(primary=True)
105+ title = Unicode()
106+ bars = ReferenceSet("id", "MyLink.foo_id",
107+ "MyLink.bar_id", "MyBar.id",
108+ order_by="MyBar.title")
109+
110+ class MyBar(Base):
111+ __storm_table__ = "bar"
112+ id = Int(primary=True)
113+ title = Unicode()
114+
115+ class MyLink(Base):
116+ __storm_table__ = "link"
117+ __storm_primary__ = "foo_id", "bar_id"
118+ foo_id = Int()
119+ bar_id = Int()
120+
121+ foo = self.store.get(MyFoo, 20)
122+ items = [(bar.id, bar.title) for bar in foo.bars]
123+ self.assertEquals(items, [(200, "Title 200"), (100, "Title 300")])
124+
125 def test_flush_order(self):
126 foo1 = Foo()
127 foo2 = Foo()

Subscribers

People subscribed via source and target branches

to status/vote changes: