Contact: fumanchu@aminus.org

Log in as guest/dejavu to create tickets

root/tags/1.4.0/schemas.py

Revision 149 (checked in by fumanchu, 3 years ago)

Moved assertion of storage out of schema.upgrade_to_1 and into schema.assert_storage. This allows new installs to immediately be the latest version.

  • Property svn:eol-style set to native
Line 
1
2 import errors
3 import units
4
5
6 __all__ = ['DeployedVersion', 'Schema',
7            ]
8
9
10 class DeployedVersion(units.Unit):
11     """Which schema version the current deployment has reached."""
12     ID = units.UnitProperty(unicode)
13     Version = units.UnitProperty(int)
14
15
16 class Schema(object):
17    
18     guid = ""
19     latest = 0
20     stage = None
21    
22     def __init__(self, arena):
23         # Since schema upgrades may take some time, we keep track of our
24         # own processing state. Legal values are:
25         #   None              = not working on an upgrade
26         #   0 to self.latest  = working on an upgrade to this version
27         self.stage = None
28        
29         self.arena = arena
30         arena.register(DeployedVersion)
31         if not arena.has_storage(DeployedVersion):
32             arena.create_storage(DeployedVersion)
33         self._deployed_unit = None
34    
35     def deployed_unit(self, default=None):
36         """Retrieve our DeployedVersion unit, optionally creating it."""
37         if self._deployed_unit is None:
38             box = self.arena.new_sandbox()
39             du = box.unit(DeployedVersion, ID=self.guid)
40             if du is None:
41                 if default is None:
42                     raise errors.DejavuError("Missing DeployedVersion unit.")
43                 else:
44                     du = DeployedVersion(ID=self.guid, Version=default)
45                     box.memorize(du)
46             self._deployed_unit = du
47         return self._deployed_unit
48    
49     def versioned(self):
50         """Return True if this installation has a DeployedVersion, false otherwise."""
51         box = self.arena.new_sandbox()
52         return bool(box.unit(DeployedVersion, ID=self.guid))
53    
54     def _get_dep(self):
55         # Note that we default the Version to latest.
56         # This allows new installs to skip all the upgrade steps,
57         # and just use the latest class definitions when they call
58         # assert_storage. However, it means that if you deploy your
59         # apps for a while without a Schema, and then introduce one
60         # later, you must manually decrement DeployedVersion from
61         # "latest" to the actual deployed version *before* running
62         # your app for the first time (or things will break due to
63         # the difference between the latest and deployed schema).
64         return self.deployed_unit(self.latest).Version
65    
66     def _set_dep(self, newvalue):
67         depunit = self.deployed_unit(newvalue)
68         depunit.Version = newvalue
69         # Skip the sandbox, so we can save without repress
70         self.arena.storage(DeployedVersion).save(depunit, forceSave=True)
71    
72     deployed = property(_get_dep, _set_dep, doc="Deployed version")
73    
74     def upgrade(self, version=None):
75         """Upgrade deployment to version arg [latest]. Idempotent."""
76         if version is None:
77             version = self.latest
78        
79         # Run upgrade_to_X methods.
80         if self.deployed > version:
81             raise errors.DejavuError("Deployed version is greater than latest version.")
82         for step in range(self.deployed, version):
83             self.stage = step
84             procedure = getattr(self, "upgrade_to_%s" % (step + 1), None)
85             if procedure:
86                 procedure()
87             self.deployed = step + 1
88        
89         self.stage = None
90    
91     def upgrade_to_0(self):
92         pass
93    
94     def assert_storage(self):
95         """Assert that each class has storage reserved for it.
96         
97         You may choose to call this method in an admin script (at the
98         discretion of the deployer), or on application startup. If you
99         call this method on every application start, you should do it
100         after calling upgrade(). Once all of the upgrade methods are done,
101         you can then safely use this method to assert the _final_ schemas
102         for all classes. Note that, if the DeployedVersion unit was just
103         created (our actual deployed version was unknown), then some of
104         the upgrade methods may fail. However, they could fail just as
105         easily if you run assert_storage before the upgrade methods.
106         """
107        
108         classes = self.arena._registered_classes.keys()
109         if DeployedVersion in classes:
110             classes.remove(DeployedVersion)
111        
112         for cls in classes:
113             if not self.arena.has_storage(cls):
114                 self.arena.create_storage(cls)
Note: See TracBrowser for help on using the browser.