- Timestamp:
- 09/01/08 13:12:08 (4 months ago)
- Files:
-
- trunk/src/dm/dom/metatest.py (modified) (4 diffs)
- trunk/src/dm/dom/temporal.py (modified) (5 diffs)
- trunk/src/dm/dom/temporaltest.py (modified) (5 diffs)
- trunk/src/dm/timepoint.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/src/dm/dom/metatest.py
r335 r380 20 20 unittest.makeSuite(TestBoolean_True), 21 21 unittest.makeSuite(TestBoolean_False), 22 unittest.makeSuite(TestInteger_Zero), 22 23 unittest.makeSuite(TestInteger_NonZero), 23 24 unittest.makeSuite(TestInteger_Negative), … … 207 208 isValueObject = True 208 209 htmlValue = '0' 209 htmlRepr = '0'210 htmlRepr = 0 210 211 domValue = 0 211 212 dbValue = 0 … … 218 219 isValueObject = True 219 220 htmlValue = '12' 220 htmlRepr = '12'221 htmlRepr = 12 221 222 domValue = 12 222 223 dbValue = 12 … … 229 230 isValueObject = True 230 231 htmlValue = '-12' 231 htmlRepr = '-12'232 htmlRepr = -12 232 233 domValue = -12 233 234 dbValue = -12 trunk/src/dm/dom/temporal.py
r305 r380 1 """A generic sub-domain for temporal persistence.""" 2 1 3 from dm.dom.base import DomainObjectRegister, DomainObject 2 4 from dm.dom.meta import DateTime, String, Integer … … 4 6 5 7 8 9 6 10 # Todo: Constraints regarding stateful requirements of temporal objects. 7 11 8 12 class BaseTemporalCollection(DomainObjectRegister): 13 """Base class for historical registers.""" 9 14 10 15 ownerName = 'parent' … … 37 42 38 43 class TemporalCollection(BaseTemporalCollection): 44 """Register for simple history of values.""" 45 46 def getCreateTime(self): 47 return self.timepoint.recorded 48 49 def getFindTime(self): 50 return self.timepoint.recorded 39 51 40 52 def create(self, recordedValue, loadedList={}, dateCreated=None): … … 47 59 48 60 class BitemporalActualCollection(TemporalCollection): 61 """Register for simple history of actual values.""" 49 62 50 63 def getCreateTime(self): … … 56 69 57 70 class BitemporalCollection(BaseTemporalCollection): 71 """Register for history of recorded history of actual values.""" 72 73 def getCreateTime(self): 74 return self.timepoint.recorded 75 76 def getFindTime(self): 77 return self.timepoint.recorded 58 78 59 79 def create(self, recordedValue, loadedList={}, dateCreated=None): trunk/src/dm/dom/temporaltest.py
r364 r380 267 267 self.timepoint.recorded = time1 268 268 sleep(0.1) 269 self.failUnless (self.collection.getCreateTime() >time1)269 self.failUnlessEqual(self.collection.getCreateTime(), time1) 270 270 271 271 … … 434 434 self.timepoint.recorded = time1 435 435 sleep(0.1) 436 self.failUnless (self.collection.getCreateTime() >time1)436 self.failUnlessEqual(self.collection.getCreateTime(), time1) 437 437 438 438 … … 507 507 ) 508 508 509 def test_save(self): 509 def test_recorded_history_of_actual_history(self): 510 # This test follows the example half-way down this page: 511 # http://martinfowler.com/ap2/temporalProperty.html 512 513 self.timepoint.reset() 514 515 color1 = "First Color" 516 color2 = "Second Color" 517 changeTime1 = mx.DateTime.DateTime(2000, 1, 1, 0, 0 ,0) 518 updateTime1 = mx.DateTime.DateTime(2003, 6, 1, 0, 0 ,0) 519 beforeChange2 = mx.DateTime.DateTime(2003, 12, 1, 0, 0, 0) 520 changeTime2 = mx.DateTime.DateTime(2004, 1, 1, 0, 0 ,0) 521 afterChange2 = mx.DateTime.DateTime(2004, 1, 2, 0, 0, 0) 522 beforeUpdate2 = mx.DateTime.DateTime(2004, 1, 9, 0, 0, 0) 523 updateTime2 = mx.DateTime.DateTime(2004, 1, 10, 0, 0 ,0) 524 afterUpdate2 = mx.DateTime.DateTime(2004, 1, 10, 0, 0, 0) 525 526 temporal = self.temporals[self.fixtureName] 527 # Check that we currently have first value before time of 2nd change. 528 529 # Record something happening at an earlier actual time. 530 self.timepoint.reset() 531 self.timepoint.recorded = updateTime1 532 self.timepoint.actual = changeTime1 533 temporal.haircolor = color1 534 temporal.save() 535 536 # Later, record that something else has happened. 537 self.timepoint.reset() 538 self.timepoint.recorded = updateTime2 539 self.timepoint.actual = changeTime2 540 temporal.haircolor = color2 541 temporal.save() 542 543 # Check before 2nd update that we have first value before time of 2nd change. 544 self.timepoint.reset() 545 self.timepoint.recorded = beforeUpdate2 546 self.timepoint.actual = beforeChange2 547 temporal = self.temporals[self.fixtureName] 548 self.failUnlessEqual(self.temporal.haircolor, color1) 549 550 # Check after 2nd update that we have first value before time of 2nd change. 551 self.timepoint.reset() 552 self.timepoint.recorded = afterUpdate2 553 self.timepoint.actual = beforeChange2 554 temporal = self.temporals[self.fixtureName] 555 self.failUnlessEqual(self.temporal.haircolor, color1) 556 557 # Check that we currently have first value before time of 2nd change. 558 self.timepoint.reset() 559 self.timepoint.actual = beforeChange2 560 temporal = self.temporals[self.fixtureName] 561 self.failUnlessEqual(self.temporal.haircolor, color1) 562 563 564 # Check before 2nd update that we have first value after time of 2nd change. 565 self.timepoint.reset() 566 self.timepoint.recorded = beforeUpdate2 567 self.timepoint.actual = afterChange2 568 temporal = self.temporals[self.fixtureName] 569 self.failUnlessEqual(self.temporal.haircolor, color1) 570 571 # Check after 2nd update that we have second value after time of 2nd change. 572 self.timepoint.reset() 573 self.timepoint.recorded = afterUpdate2 574 self.timepoint.actual = afterChange2 575 temporal = self.temporals[self.fixtureName] 576 self.failUnlessEqual(self.temporal.haircolor, color2) 577 578 # Check that we currently have second value after time of 2nd change. 579 self.timepoint.reset() 580 self.timepoint.actual = afterChange2 581 temporal = self.temporals[self.fixtureName] 582 self.failUnlessEqual(self.temporal.haircolor, color2) 583 584 585 586 def test_recorded_value_history(self): 510 587 self.failUnlessEqual(self.temporal.description, "", "Already has a description.") 511 588 self.temporal.description = "Test Temporal" … … 531 608 time2 = mx.DateTime.DateTime(2007, 7, 1, 0, 0 ,0) 532 609 time3 = mx.DateTime.DateTime(2007, 8, 1, 0, 0 ,0) 533 description1 = " Recent Description"534 description2 = " Most Recent Description"535 description3 = " Next Most Recent Description"536 haircolor0 = " Ancient Haircolor"537 haircolor1 = " Recent Haircolor"538 haircolor2 = " Most Recent Haircolor"539 haircolor3 = " Next Most Recent Haircolor"540 haircolor4 = " Omg Next Most Recent Haircolor"610 description1 = "Description One" 611 description2 = "Description Two" 612 description3 = "Description Three" 613 haircolor0 = "Haircolor Zero" 614 haircolor1 = "Haircolor One" 615 haircolor2 = "Haircolor Two" 616 haircolor3 = "Haircolor Three" 617 haircolor4 = "Haircolor Four" 541 618 temporal.description = description1 542 619 temporal.firstkiss = time1 … … 579 656 temporal.save() 580 657 temporal = self.temporals[self.fixtureName] 658 581 659 self.failUnlessEqual(temporal.description, description3) 582 660 self.failUnlessEqual(temporal.firstkiss, time3) 583 661 self.failUnlessEqual(temporal.state, state3) 584 662 self.failUnlessEqual(temporal.haircolor, haircolor3) 585 586 #raise Exception, str(temporal)587 588 # Make changes to the actual time.589 self.timepoint.reset()590 temporal = self.temporals[self.fixtureName]591 self.failUnlessEqual(temporal.haircolor, haircolor3)592 yearsAgo = mx.DateTime.DateTime(2001, 6, 1, 0, 0, 0)593 self.timepoint.actual = yearsAgo594 temporal.haircolor = haircolor0595 temporal.save()596 temporal = self.temporals[self.fixtureName]597 self.failUnlessEqual(temporal.haircolor, haircolor0)598 self.timepoint.reset()599 temporal = self.temporals[self.fixtureName]600 self.failUnlessEqual(temporal.haircolor, haircolor3)601 self.timepoint.actual = yearsAgo602 temporal = self.temporals[self.fixtureName]603 self.failUnlessEqual(temporal.haircolor, haircolor0)604 self.timepoint.reset()605 temporal = self.temporals[self.fixtureName]606 self.failUnlessEqual(temporal.haircolor, haircolor3)607 self.timepoint.recorded = revisionTime608 self.timepoint.actual = yearsAgo609 temporal = self.temporals[self.fixtureName]610 self.failUnlessEqual(temporal.haircolor, 'My Natural Color')611 self.timepoint.reset()612 self.timepoint.recorded = revisionTime613 temporal = self.temporals[self.fixtureName]614 self.failUnlessEqual(temporal.haircolor, haircolor1)615 663 616 664 def test_count(self): trunk/src/dm/timepoint.py
r364 r380 5 5 in universal time. There are two properties, recorded and actual. 6 6 7 Most temporal aspects are (uni-)temporal, and time-travelling is achieved by 8 setting the recorded time property before object retrieval. 7 All temporal aspects are sensitive to the time when values are recorded 8 ("recorded time"). The usual assumption is that recording happens when 9 changes in the domain happen, so recorded time and actual time are identical. 9 10 10 If you have a bi-temporal aspect you can also time-travel in actual time. Set 11 the actual property to see what an aspect is at some time in the past, 12 according to how things were recorded at some particular time. 11 By setting the timepoint's 'recorded' property, you retrieve values 12 from a recorded history of values (so you can find which value was recorded at 13 a given point in time). 14 15 However, some aspects are bi-temporal and are sensitive to when the actual 16 changes in the domain were thought to occur in distinction from when the 17 changes are recorded. 18 19 By setting the timepoint's 'actual' property you can retrieve values from the 20 currently recorded history of actual values. By also setting the 'recorded' 21 property, you retrieve values from an older history. 22 23 Just setting the timepoint's 'recorded' property and retrieving the object 24 will return the "most recent actual" value, as it was recorded in the past. 25 26 So the primary time-frame is "when things were recorded". In addition to this, 27 bi-temporal values can vary across "when things actually happened". Changing 28 only the 'actual' time is like asking "what do we currently think it was then". 29 Changing only the 'recorded' time is like asking "what did we think it was". 30 13 31 """ 14 32
