Changeset 427
- Timestamp:
- 03/26/07 03:46:02
- Files:
-
- trunk/__init__.py (modified) (2 diffs)
- trunk/arenas.py (modified) (1 diff)
- trunk/codewalk.py (deleted)
- trunk/engines.py (modified) (1 diff)
- trunk/logic.py (deleted)
- trunk/storage/__init__.py (modified) (1 diff)
- trunk/storage/db.py (modified) (1 diff)
- trunk/storage/storefs.py (modified) (1 diff)
- trunk/storage/storeram.py (modified) (1 diff)
- trunk/storage/storeshelve.py (modified) (1 diff)
- trunk/test/clinic_fixture.py (modified) (8 diffs)
- trunk/test/test.py (modified) (1 diff)
- trunk/test/test_codewalk.py (deleted)
- trunk/test/test_logic.py (deleted)
- trunk/test/test_storemsaccess.py (modified) (2 diffs)
- trunk/test/zoo_fixture.py (modified) (5 diffs)
- trunk/views.py (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/__init__.py
r426 r427 44 44 from dejavu.schemas import * 45 45 from dejavu.units import * 46 from dejavu import logic 46 47 from geniusql import logic 48 from geniusql import logicfuncs 47 49 48 50 … … 50 52 # process. Otherwise, you should create your own instance per application. 51 53 dejavuarena = Arena() 52 53 54 ###########################################################################55 ## ##56 ## Logic functions ##57 ## ##58 ###########################################################################59 60 61 def icontains(a, b):62 """Case-insensitive test b in a. Note the operand order."""63 return icontainedby(b, a)64 65 def icontainedby(a, b):66 """Case-insensitive test a in b. Note the operand order."""67 if isinstance(b, basestring):68 # Looking for text in a string.69 if a is None or b is None:70 return False71 return a.lower() in b.lower()72 else:73 # Looking for field in (a, b, c).74 # Force all args to lowercase for case-insensitive comparison.75 if a is None or not b:76 return False77 return a.lower() in [x.lower() for x in b]78 79 def istartswith(a, b):80 """True if a starts with b (case-insensitive), False otherwise."""81 if a is None or b is None:82 return False83 return a.lower().startswith(b.lower())84 85 def iendswith(a, b):86 """True if a ends with b (case-insensitive), False otherwise."""87 if a is None or b is None:88 return False89 return a.lower().endswith(b.lower())90 91 def ieq(a, b):92 """True if a == b (case-insensitive), False otherwise."""93 if a is None or b is None:94 return False95 return (a.lower() == b.lower())96 97 def year(value):98 """The year attribute of a date."""99 if isinstance(value, (_datetime.date, _datetime.datetime)):100 return value.year101 else:102 return None103 104 def month(value):105 """The month attribute of a date."""106 if isinstance(value, (_datetime.date, _datetime.datetime)):107 return value.month108 else:109 return None110 111 def day(value):112 """The day attribute of a date."""113 if isinstance(value, (_datetime.date, _datetime.datetime)):114 return value.day115 else:116 return None117 118 def now():119 """Late-bound datetime.datetime.now(). Taint this when early binding."""120 return _datetime.datetime.now()121 now.bind_late = True122 123 def today():124 """Late-bound datetime.date.today(). Taint this when early binding."""125 return _datetime.date.today()126 today.bind_late = True127 128 def iscurrentweek(value):129 """If value is in the current week, return True, else False."""130 if isinstance(value, (_datetime.date, _datetime.datetime)):131 return _datetime.date.today().strftime('%W%Y') == value.strftime('%W%Y')132 else:133 return False134 iscurrentweek.bind_late = True135 136 # Inject these functions into the logic module's globals.137 class _Empty(object): pass138 _d = _Empty()139 for _name in ['icontains', 'icontainedby', 'istartswith', 'iendswith',140 'ieq', 'year', 'month', 'now', 'today', 'iscurrentweek']:141 setattr(_d, _name, globals()[_name])142 logic.dejavu = _d143 del _name, _d, _Emptytrunk/arenas.py
r426 r427 9 9 10 10 from dejavu.containers import Graph 11 from dejavu import logic, errors, storage, xray 11 from dejavu import errors, storage, xray 12 from geniusql import logic 12 13 13 14 __all__ = ['Arena', 'Sandbox', 'logflags', trunk/engines.py
r426 r427 15 15 16 16 import dejavu 17 from dejavu import errors, logic, recur 17 from dejavu import errors, recur 18 from geniusql import logic 18 19 19 20 trunk/storage/__init__.py
r426 r427 10 10 import warnings 11 11 12 from dejavu import errors, logic, recur 12 from dejavu import errors, recur 13 from geniusql import logic 13 14 14 15 trunk/storage/db.py
r426 r427 34 34 35 35 import geniusql 36 from geniusql import logic 36 37 37 38 import dejavu 38 from dejavu import logic,storage, logflags, xray39 from dejavu import storage, logflags, xray 39 40 from dejavu.errors import StorageWarning, MappingError 40 41 trunk/storage/storefs.py
r426 r427 9 9 10 10 import dejavu 11 from dejavu import errors, logic, storage 11 from dejavu import errors, storage 12 13 from geniusql import logic 12 14 13 15 trunk/storage/storeram.py
r426 r427 6 6 import thread 7 7 8 from dejavu import logic,UnitJoin8 from dejavu import UnitJoin 9 9 from dejavu.storage import StorageManager 10 from geniusql import logic 10 11 11 12 trunk/storage/storeshelve.py
r426 r427 16 16 17 17 import dejavu 18 from dejavu import errors, logic, storage 18 from dejavu import errors, storage 19 from geniusql import logic 19 20 20 21 trunk/test/clinic_fixture.py
r426 r427 2 2 3 3 import datetime 4 dt = datetime.datetime 5 td = datetime.timedelta 4 6 import os 5 7 thisdir = os.path.dirname(__file__) … … 23 25 class Argument(Unit): 24 26 Topic = UnitProperty() 25 Start = UnitProperty(d atetime.datetime)27 Start = UnitProperty(dt) 26 28 Duration = UnitProperty(datetime.timedelta) 27 29 ClinicID = UnitProperty(int, index=True) … … 64 66 65 67 # Arguments 66 sixtynine = datetime.datetime(1969, 1, 1) 67 td = datetime.timedelta 68 sixtynine = dt(1969, 1, 1) 68 69 for s in range(5): 69 70 for d in range(12): … … 74 75 ) 75 76 box.memorize(arg) 76 box.memorize(Participant(ParticipantID=brown.ID, ArgumentID=arg.ID)) 77 box.memorize(Participant(ParticipantID=green.ID, ArgumentID=arg.ID)) 77 box.memorize(Participant(DirectoryID=brown.ID, ArgumentID=arg.ID)) 78 if d % 2: 79 box.memorize(Participant(DirectoryID=green.ID, ArgumentID=arg.ID)) 80 else: 81 box.memorize(Participant(DirectoryID=white.ID, ArgumentID=arg.ID)) 78 82 box.flush_all() 79 83 80 84 def test_2_simple_views(self): 81 85 # Get the start and duration times for: "What is an Argument?" 82 sixtynine = datetime.datetime(1969, 1, 1) 83 td = datetime.timedelta 86 sixtynine = dt(1969, 1, 1) 84 87 expected = [] 85 88 for s in range(5): … … 104 107 self.assertEqual(actual, expected) 105 108 106 ## def test_3_multidim_views(self): 107 ## source = Clinic << Argument << Participant 108 ## sources[Clinic] = ['ID', 'Name'] 109 ## brownargs = views.View(Source=Argument, 110 ## Filter=lambda x: x.DirectoryID == brown.ID) 111 ## self.assertEqual(brownargs(), []) 112 109 def test_3_multidim_views(self): 110 box = arena.new_sandbox() 111 brownid = box.unit(Directory, Name='Sam Brown').ID 112 box.flush_all() 113 114 brownargs = views.View(Clinic << Argument << Participant, 115 [['ID', 'Name'], None, None], 116 lambda c, a, p: p.DirectoryID == brownid) 117 clsname = 'BrownClinics' 118 snap = brownargs.results(clsname, arena) 119 snapclass = snap.unitclass(arena) 120 self.assertEqual(snapclass.__name__, clsname) 121 actual = list(arena.view(snapclass, ['Name'])) 122 actual.sort() 123 self.assertEqual(actual, [(u'The Argument Clinic',)] * 60) 124 125 def test_4_aggregate_views(self): 126 firstargs = views.View(Argument << Participant << Directory, 127 lambda a, p, d: [d.Name, min(a.Start)] 128 ) 129 clsname = 'FirstArgument' 130 snap = firstargs.results(clsname, arena) 131 snapclass = snap.unitclass(arena) 132 self.assertEqual(snapclass.__name__, clsname) 133 actual = list(arena.view(snapclass)) 134 actual.sort() 135 self.assertEqual(actual, [(u'Alice White', dt(1969, 1, 31)), 136 (u'David Green', dt(1969, 1, 1)), 137 (u'Sam Brown', dt(1969, 1, 1)), 138 ]) 113 139 114 140 … … 119 145 if isinstance(message, unicode): 120 146 message = message.encode('utf8') 121 s = "%s %s" % (d atetime.datetime.now().isoformat(), message)147 s = "%s %s" % (dt.now().isoformat(), message) 122 148 f = open(logname, 'ab') 123 149 f.write(s + '\n') … … 140 166 141 167 try: 142 sm.db.typeadapter.add_pickled_type(views.Sources) 143 sm.db.adaptertosql.add_pickled_type(views.Sources) 144 sm.db.adapterfromdb.add_pickled_type(views.Sources) 168 for cls in (views.ViewSource, views.ViewAttrs): 169 sm.db.typeadapter.add_pickled_type(cls) 170 sm.db.adaptertosql.add_pickled_type(cls) 171 sm.db.adapterfromdb.add_pickled_type(cls) 145 172 except AttributeError: 146 173 pass … … 169 196 # Run the OLAPTests and time it. 170 197 case = loader(OLAPTests) 171 startTime = d atetime.datetime.now()198 startTime = dt.now() 172 199 tools.djvTestRunner.run(case) 173 print "Ran clinic case in:", d atetime.datetime.now() - startTime200 print "Ran clinic case in:", dt.now() - startTime 174 201 except: 175 202 traceback.print_exc() trunk/test/test.py
r426 r427 88 88 testList = [ 89 89 'test_analysis', 90 'test_codewalk',91 90 'test_containers', 92 91 'test_dejavu', 93 'test_logic',94 92 'test_storeram', 95 93 'test_storeburned', trunk/test/test_storemsaccess.py
r426 r427 17 17 else: 18 18 19 class CurrencyAdapter(ado.TypeAdapter_MSAccess):20 """Stores Decimal and FixedPoint objects as CURRENCY."""21 22 def decimal_type(self, colname, precision, scale):23 if precision == 0:24 precision = 1925 if scale > precision:26 scale = precision27 if scale > 4 or precision - scale > 15:28 return "TEXT"29 return "CURRENCY"30 31 19 SM_class = "access" 32 20 opts = {'connections.Connect': … … 37 25 import zoo_fixture 38 26 39 # lists to keep track of the test_currency runs40 standard_runs = []41 altered_runs = []42 43 def test_currency(obj):44 sm = zoo_fixture.arena.stores['testSM']45 fta = sm.db.typeadapter.__class__.__name__46 47 for c, p in [('Exhibit', 'Acreage'), ('Zoo', 'Admission')]:48 dbtype = sm.schema[c][p].dbtype49 if fta == "CurrencyAdapter":50 if dbtype != "CURRENCY" and not dbtype.startswith("WCHAR"):51 obj.fail("%s wrong type for %s.%s" % (dbtype, c, p))52 else:53 if not dbtype.startswith("NUMERIC") and not dbtype.startswith("WCHAR"):54 obj.fail("%s wrong type for %s.%s" % (dbtype, c, p))55 obj.assertEqual(len(standard_runs), 0)56 57 27 # Isolate schema changes from one test to the next. 58 28 reload(zoo_fixture) 59 29 60 # test the standard MS Access setup where Decimal and FixedPoint61 # objects are stored in the database as INTEGERS, LONGS or NUMERIC62 print63 print "Standard MSAccess test."64 zoo_fixture.ZooTests.test_currency = test_currency65 30 zoo_fixture.init() 66 31 zoo_fixture.run(SM_class, opts) 67 standard_runs.append(True)68 69 # plugin the adapter for testing CURRENCY columns70 ado.MSAccessDatabase.typeadapter = CurrencyAdapter()71 72 reload(zoo_fixture)73 74 # test storing and recalling Decimal values to the database using75 # CURRENCY columns - the (current) default behavior of pythoncom76 # is to return CURRENCY values as a tuple77 print78 print "MSAccess test - CURRENCY returned as tuple."79 zoo_fixture.ZooTests.test_currency = test_currency80 zoo_fixture.init()81 zoo_fixture.run(SM_class, opts)82 altered_runs.append(True)83 84 # set pythoncom to return CURRENCY values as Decimal objects85 pythoncom.__future_currency__ = True86 87 reload(zoo_fixture)88 89 # test storing and recalling Decimal values to the database using90 # CURRENCY columns - CURRENCY values are now returned as Decimal91 # objects92 print93 print "MSAccess test - CURRENCY returned as Decimal."94 zoo_fixture.ZooTests.test_currency = test_currency95 zoo_fixture.init()96 zoo_fixture.run(SM_class, opts)97 altered_runs.append(True)98 32 99 33 trunk/test/zoo_fixture.py
r426 r427 45 45 46 46 import dejavu 47 from dejavu import errors, logic,storage47 from dejavu import errors, storage 48 48 from dejavu import Unit, UnitProperty, ToOne, ToMany, UnitSequencerInteger, UnitAssociation 49 49 from dejavu.test import tools 50 50 from dejavu import engines 51 from geniusql import logic, logicfuncs 52 logicfuncs.init() 51 53 52 54 … … 463 465 464 466 # logic and other functions 465 self.assertEqual(matches(lambda x: dejavu.ieq(x.Species, 'slug')), 1)466 self.assertEqual(matches(lambda x: dejavu.icontains(x.Species, 'PEDE')), 2)467 self.assertEqual(matches(lambda x: dejavu.icontains(('Lion', 'Banana'), x.Species)), 1)468 f = lambda x: dejavu.icontainedby(x.Species, ('Lion', 'Bear', 'Leopard'))467 self.assertEqual(matches(lambda x: ieq(x.Species, 'slug')), 1) 468 self.assertEqual(matches(lambda x: icontains(x.Species, 'PEDE')), 2) 469 self.assertEqual(matches(lambda x: icontains(('Lion', 'Banana'), x.Species)), 1) 470 f = lambda x: icontainedby(x.Species, ('Lion', 'Bear', 'Leopard')) 469 471 self.assertEqual(matches(f), 3) 470 472 name = 'Lion' … … 476 478 # Test now(), today(), year(), month(), day() 477 479 self.assertEqual(matches(lambda x: x.Founded != None 478 and x.Founded < dejavu.today(), Zoo), 3)479 self.assertEqual(matches(lambda x: x.LastEscape == dejavu.now()), 0)480 self.assertEqual(matches(lambda x: dejavu.year(x.LastEscape) == 2004), 1)481 self.assertEqual(matches(lambda x: dejavu.month(x.LastEscape) == 12), 1)482 self.assertEqual(matches(lambda x: d ejavu.day(x.LastEscape) == 21), 1)480 and x.Founded < today(), Zoo), 3) 481 self.assertEqual(matches(lambda x: x.LastEscape == now()), 0) 482 self.assertEqual(matches(lambda x: year(x.LastEscape) == 2004), 1) 483 self.assertEqual(matches(lambda x: month(x.LastEscape) == 12), 1) 484 self.assertEqual(matches(lambda x: day(x.LastEscape) == 21), 1) 483 485 484 486 … … 537 539 expected = [u'Montr\xe9al Biod\xf4me', 'Wild Animal Park'] 538 540 e = (lambda x: x.Founded != None 539 and x.Founded <= dejavu.today()541 and x.Founded <= today() 540 542 and x.Founded >= datetime.date(1990, 1, 1)) 541 543 values = [val[0] for val in box.view(Zoo, ['Name'], e)] … … 772 774 expected = [u'Montr\xe9al Biod\xf4me', 'Wild Animal Park'] 773 775 e = (lambda x: x.Founded != None 774 and x.Founded <= dejavu.today()776 and x.Founded <= today() 775 777 and x.Founded >= datetime.date(1990, 1, 1)) 776 778 values = [val[0] for val in arena.view(Zoo, ['Name'], e)] trunk/views.py
r426 r427 8 8 import datetime 9 9 import dejavu 10 from dejavu import errors, logic, recur 10 from dejavu import errors, recur 11 from geniusql import logic 11 12 12 13 … … 45 46 46 47 47 class Sources(object):48 class ViewSource(object): 48 49 49 50 # This should be either a Unit class or a UnitJoin instance. 50 sources= None51 value = None 51 52 52 def __init__(self, sources): 53 self.sources = sources 53 def __init__(self, value): 54 self.value = value 55 56 57 class ViewAttrs(object): 58 59 # This should be either a list of lists or a logic.Expression. 60 value = [] 61 62 def __init__(self, value): 63 if not isinstance(value, (list, tuple, logic.Expression)): 64 value = logic.Expression(value) 65 self.value = value 54 66 55 67 … … 65 77 # The following are equivalent to: 66 78 # "SELECT Attributes FROM Relation WHERE Restriction" 67 Relation = dejavu.UnitProperty(Sources) 79 Relation = dejavu.UnitProperty(ViewSource) 80 68 81 # At the moment, Attributes is a list (of lists, probably). 69 82 # In the future, it might be a lambda instead in order to support 70 83 # aggregation functions (possibly with GROUP BY?) 71 Attributes = dejavu.UnitProperty(list) 84 Attributes = dejavu.UnitProperty(ViewAttrs) 85 72 86 Restriction = dejavu.UnitProperty(logic.Expression) 73 87 … … 91 105 sm = arena.storage(self.__class__) 92 106 93 sources = self.Relation. sources107 sources = self.Relation.value 94 108 if isinstance(sources, dejavu.UnitJoin): 95 109 sources = sm.tablejoin(sources) … … 97 111 sources = sm.schema[sources.__name__] 98 112 99 newtable = sm.db.insert_into(name, sources, self.Attributes ,113 newtable = sm.db.insert_into(name, sources, self.Attributes.value, 100 114 self.Restriction) 101 115
