This file is indexed.

/usr/share/pyshared/zope.app.generations-3.6.1.egg-info/PKG-INFO is in python-zope.app.generations 3.6.1-0ubuntu1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
Metadata-Version: 1.1
Name: zope.app.generations
Version: 3.6.1
Summary: Zope Application Schema Generations
Home-page: http://pypi.python.org/pypi/zope.app.generations
Author: Zope Corporation and Contributors
Author-email: zope-dev@zope.org
License: ZPL 2.1
Description: Generations are a way of updating objects in the database when the application
        schema changes.  An application schema is essentially the structure of data,
        the structure of classes in the case of ZODB or the table descriptions in the
        case of a relational database.
        
        
        .. contents::
        
        ======================
        Detailed Documentation
        ======================
        
        
        Generations are a way of updating objects in the database when the application
        schema changes.  An application schema is essentially the structure of data,
        the structure of classes in the case of ZODB or the table descriptions in the
        case of a relational database.
        
        When you change your application's data structures, for example,
        you change the semantic meaning of an existing field in a class, you will
        have a problem with databases that were created before your change.  For a
        more thorough discussion and possible solutions, see
        http://wiki.zope.org/zope3/DatabaseGenerations
        
        We will be using the component architecture, and we will need a database and a
        connection:
        
            >>> import cgi
            >>> from pprint import pprint
            >>> from zope.interface import implements
            >>> from zope.app.testing import ztapi
        
            >>> from ZODB.tests.util import DB
            >>> db = DB()
            >>> conn = db.open()
            >>> root = conn.root()
        
        Imagine that our application is an oracle: you can teach it to react to
        phrases.  Let's keep it simple and store the data in a dict:
        
            >>> root['answers'] = {'Hello': 'Hi & how do you do?',
            ...                    'Meaning of life?': '42',
            ...                    'four < ?': 'four < five'}
            >>> import transaction
            >>> transaction.commit()
        
        
        Initial setup
        -------------
        
        Here's some generations-specific code.  We will create and register a
        SchemaManager.  SchemaManagers are responsible for the actual updates of the
        database.  This one will be just a dummy.  The point here is to make the
        generations module aware that our application supports generations.
        
        The default implementation of SchemaManager is not suitable for this test
        because it uses Python modules to manage generations.  For now, it
        will be just fine, since we don't want it to do anything just yet.
        
            >>> from zope.app.generations.interfaces import ISchemaManager
            >>> from zope.app.generations.generations import SchemaManager
            >>> dummy_manager = SchemaManager(minimum_generation=0, generation=0)
            >>> ztapi.provideUtility(ISchemaManager, dummy_manager, name='some.app')
        
        'some.app' is a unique identifier.  You should use a URI or the dotted name
        of your package.
        
        When you start Zope and a database is opened, an event
        IDatabaseOpenedWithRoot is sent.  Zope registers
        evolveMinimumSubscriber by default as a handler for this event.  Let's
        simulate this:
        
            >>> class DatabaseOpenedEventStub(object):
            ...     def __init__(self, database):
            ...         self.database = database
            >>> event = DatabaseOpenedEventStub(db)
        
            >>> from zope.app.generations.generations import evolveMinimumSubscriber
            >>> evolveMinimumSubscriber(event)
        
        The consequence of this action is that now the database contains the fact
        that our current schema number is 0.  When we update the schema, Zope3 will
        have an idea of what the starting point was.  Here, see?
        
            >>> from zope.app.generations.generations import generations_key
            >>> root[generations_key]['some.app']
            0
        
        In real life you should never have to bother with this key directly,
        but you should be aware that it exists.
        
        
        Upgrade scenario
        ----------------
        
        Back to the story.  Some time passes and one of our clients gets hacked because
        we forgot to escape HTML special characters!  The horror!  We must fix this
        problem ASAP without losing any data.  We decide to use generations to impress
        our peers.
        
        Let's update the schema manager (drop the old one and install a new custom
        one):
        
            >>> ztapi.unprovideUtility(ISchemaManager, name='some.app')
        
            >>> class MySchemaManager(object):
            ...     implements(ISchemaManager)
            ...
            ...     minimum_generation = 1
            ...     generation = 2
            ...
            ...     def evolve(self, context, generation):
            ...         root = context.connection.root()
            ...         answers = root['answers']
            ...         if generation == 1:
            ...             for question, answer in answers.items():
            ...                 answers[question] = cgi.escape(answer)
            ...         elif generation == 2:
            ...             for question, answer in answers.items():
            ...                 del answers[question]
            ...                 answers[cgi.escape(question)] = answer
            ...         else:
            ...             raise ValueError("Bummer")
            ...         root['answers'] = answers # ping persistence
            ...         transaction.commit()
        
            >>> manager = MySchemaManager()
            >>> ztapi.provideUtility(ISchemaManager, manager, name='some.app')
        
        We have set `minimum_generation` to 1.  That means that our application
        will refuse to run with a database older than generation 1.  The `generation`
        attribute is set to 2, which means that the latest generation that this
        SchemaManager knows about is 2.
        
        evolve() is the workhorse here.  Its job is to get the database from
        `generation`-1 to `generation`.  It gets a context which has the attribute
        'connection', which is a connection to the ZODB.  You can use that to change
        objects like in this example.
        
        In this particular implementation generation 1 escapes the answers (say,
        critical, because they can be entered by anyone!), generation 2 escapes the
        questions (say, less important, because these can be entered by authorized
        personell only).
        
        In fact, you don't really need a custom implementation of ISchemaManager.  One
        is available, we have used it for a dummy previously. It uses Python modules
        for organization of evolver functions.  See its docstring for more information.
        
        In real life you will have much more complex object structures than the one
        here.  To make your life easier, there are two very useful functions available
        in zope.app.generations.utility: findObjectsMatching() and
        findObjectsProviding().  They will dig through containers recursively to help
        you seek out old objects that you wish to update, by interface or by some other
        criteria.  They are easy to understand, check their docstrings.
        
        
        Generations in action
        ---------------------
        
        So, our furious client downloads our latest code and restarts Zope.  The event
        is automatically sent again:
        
            >>> event = DatabaseOpenedEventStub(db)
            >>> evolveMinimumSubscriber(event)
        
        Shazam!  The client is happy again!
        
            >>> pprint(root['answers'])
            {'Hello': 'Hi &amp; how do you do?',
             'Meaning of life?': '42',
             'four < ?': 'four &lt; five'}
        
        Because evolveMinimumSubscriber is very lazy, it only updates the database just
        enough so that your application can use it (to the `minimum_generation`, that
        is).  Indeed, the marker indicates that the database generation has been bumped
        to 1:
        
            >>> root[generations_key]['some.app']
            1
        
        We see that generations are working, so we decide to take the next step
        and evolve to generation 2.  Let's see how this can be done manually:
        
            >>> from zope.app.generations.generations import evolve
            >>> evolve(db)
        
            >>> pprint(root['answers'])
            {'Hello': 'Hi &amp; how do you do?',
             'Meaning of life?': '42',
             'four &lt; ?': 'four &lt; five'}
            >>> root[generations_key]['some.app']
            2
        
        Default behaviour of `evolve` upgrades to the latest generation provided by
        the SchemaManager. You can use the `how` argument to evolve() when you want
        just to check if you need to update or if you want to be lazy like the
        subscriber which we have called previously.
        
        
        Ordering of schema managers
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~
        
        Frequently subsystems used to compose an application rely on other
        subsystems to operate properly.  If both subsystems provide schema
        managers, it is often helpful to know the order in which the evolvers
        will be invoked.  This allows a framework and it's clients to be able
        to evolve in concert, and the clients can know that the framework will
        be evolved before or after itself.
        
        This can be accomplished by controlling the names of the schema
        manager utilities.  The schema managers are run in the order
        determined by sorting their names.
        
            >>> manager1 = SchemaManager(minimum_generation=0, generation=0)
            >>> manager2 = SchemaManager(minimum_generation=0, generation=0)
        
            >>> ztapi.provideUtility(
            ...     ISchemaManager, manager1, name='another.app')
            >>> ztapi.provideUtility(
            ...     ISchemaManager, manager2, name='another.app-extension')
        
        Notice how the name of the first package is used to create a namespace
        for dependent packages.  This is not a requirement of the framework,
        but a convenient pattern for this usage.
        
        Let's evolve the database to establish these generations:
        
            >>> event = DatabaseOpenedEventStub(db)
            >>> evolveMinimumSubscriber(event)
        
            >>> root[generations_key]['another.app']
            0
            >>> root[generations_key]['another.app-extension']
            0
        
        Let's assume that for some reason each of these subsystems needs to
        add a generation, and that generation 1 of 'another.app-extension'
        depends on generation 1 of 'another.app'.  We'll need to provide
        schema managers for each that record that they've been run so we can
        verify the result:
        
            >>> ztapi.unprovideUtility(ISchemaManager, name='another.app')
            >>> ztapi.unprovideUtility(ISchemaManager, name='another.app-extension')
        
            >>> class FoundationSchemaManager(object):
            ...     implements(ISchemaManager)
            ...
            ...     minimum_generation = 1
            ...     generation = 1
            ...
            ...     def evolve(self, context, generation):
            ...         root = context.connection.root()
            ...         ordering = root.get('ordering', [])
            ...         if generation == 1:
            ...             ordering.append('foundation 1')
            ...             print 'foundation generation 1'
            ...         else:
            ...             raise ValueError("Bummer")
            ...         root['ordering'] = ordering # ping persistence
            ...         transaction.commit()
        
            >>> class DependentSchemaManager(object):
            ...     implements(ISchemaManager)
            ...
            ...     minimum_generation = 1
            ...     generation = 1
            ...
            ...     def evolve(self, context, generation):
            ...         root = context.connection.root()
            ...         ordering = root.get('ordering', [])
            ...         if generation == 1:
            ...             ordering.append('dependent 1')
            ...             print 'dependent generation 1'
            ...         else:
            ...             raise ValueError("Bummer")
            ...         root['ordering'] = ordering # ping persistence
            ...         transaction.commit()
        
            >>> manager1 = FoundationSchemaManager()
            >>> manager2 = DependentSchemaManager()
        
            >>> ztapi.provideUtility(
            ...     ISchemaManager, manager1, name='another.app')
            >>> ztapi.provideUtility(
            ...     ISchemaManager, manager2, name='another.app-extension')
        
        Evolving the database now will always run the 'another.app' evolver
        before the 'another.app-extension' evolver:
        
            >>> event = DatabaseOpenedEventStub(db)
            >>> evolveMinimumSubscriber(event)
            foundation generation 1
            dependent generation 1
        
            >>> root['ordering']
            ['foundation 1', 'dependent 1']
        
        
        Installation
        ------------
        
        In the the example above, we manually initialized the answers.  We
        shouldn't have to do that manually.  The application should be able to
        do that automatically.
        
        IInstallableSchemaManager extends ISchemaManager, providing an install
        method for performing an intial installation of an application.  This
        is a better alternative than registering database-opened subscribers.
        
        Let's define a new schema manager that includes installation:
        
        
            >>> ztapi.unprovideUtility(ISchemaManager, name='some.app')
        
            >>> from zope.app.generations.interfaces import IInstallableSchemaManager
            >>> class MySchemaManager(object):
            ...     implements(IInstallableSchemaManager)
            ...
            ...     minimum_generation = 1
            ...     generation = 2
            ...
            ...     def install(self, context):
            ...         root = context.connection.root()
            ...         root['answers'] = {'Hello': 'Hi &amp; how do you do?',
            ...                            'Meaning of life?': '42',
            ...                            'four &lt; ?': 'four &lt; five'}
            ...         transaction.commit()
            ...
            ...     def evolve(self, context, generation):
            ...         root = context.connection.root()
            ...         answers = root['answers']
            ...         if generation == 1:
            ...             for question, answer in answers.items():
            ...                 answers[question] = cgi.escape(answer)
            ...         elif generation == 2:
            ...             for question, answer in answers.items():
            ...                 del answers[question]
            ...                 answers[cgi.escape(question)] = answer
            ...         else:
            ...             raise ValueError("Bummer")
            ...         root['answers'] = answers # ping persistence
            ...         transaction.commit()
        
            >>> manager = MySchemaManager()
            >>> ztapi.provideUtility(ISchemaManager, manager, name='some.app')
        
        Now, lets open a new database:
        
            >>> db.close()
            >>> db = DB()
            >>> conn = db.open()
            >>> 'answers' in conn.root()
            False
        
        
            >>> event = DatabaseOpenedEventStub(db)
            >>> evolveMinimumSubscriber(event)
        
            >>> conn.sync()
            >>> root = conn.root()
        
            >>> pprint(root['answers'])
            {'Hello': 'Hi &amp; how do you do?',
             'Meaning of life?': '42',
             'four &lt; ?': 'four &lt; five'}
            >>> root[generations_key]['some.app']
            2
        
        
        =======
        CHANGES
        =======
        
        3.6.1 (2012-01-23)
        ------------------
        
        - Replaced an undeclared test dependency on ``zope.app.authentication`` with
          ``zope.password``.
        
        
        3.6.0 (2010-09-17)
        ------------------
        
        - ``zope.app.generations`` depended on ``zope.app.applicationcontrol`` but
          did not declare it. Modernized dependecy to ``zope.applicationcontrol`` as
          the needed interface has been moved there.
        
        - Using python's ``doctest`` module instead of deprecated
          ``zope.testing.doctest[unit]``.
        
        - Replaced a testing dependency on ``zope.app.securitypolicy`` with one on
          ``zope.securitypolicy``.
        
        
        3.5.1 (2010-01-08)
        ------------------
        
        - Depend on new ``zope.processlifetime`` interfaces instead of using
          BBB imports from ``zope.app.appsetup``.
        
        - Fix ftesting.zcml due to ``zope.securitypolicy`` update.
        
        - Fix tests using a newer zope.publisher that requires zope.login.
        
        3.5.0 (2009-04-05)
        ------------------
        
        - Moved ``getRootFolder`` utility method from
          ``zope.app.zopeappgenerations`` to ``zope.app.generations.utility``.
        
        - Removed not necessary install dependency on ``zope.app.testing``.
        
        
        3.4.2 (2009-01-27)
        ------------------
        
        - Provide more logging output for the various stages and actions of evolving a
          database.
        
        - Fixed bug: A failing last generation would allow starting an app server
          without having evolved to the minimum generation.
        
        - Substitute zope.app.zapi by direct calls to its wrapped apis. See
          bug 219302.
        
        - Corrected author email and home page address.
        
        
        3.4.1 (2007-10-31)
        ------------------
        
        - Resolve ``ZopeSecurityPolicy`` deprecation warning.
        
        
        3.4.0 (2007-10-24)
        ------------------
        
        - Initial release independent of the main Zope tree.
        
Keywords: zope3 zodb schema generation
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Zope Public License
Classifier: Programming Language :: Python
Classifier: Natural Language :: English
Classifier: Operating System :: OS Independent
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Framework :: Zope3