def test_init_adds_clock_tick(self, session): clock_query = session.query( models.SimpleTableTemporal.temporal_options.clock_table).count() assert clock_query == 0 t = models.SimpleTableTemporal(prop_a=1, prop_b='foo') assert t.clock.count() == 1 session.add(t) session.commit() t = session.query(models.SimpleTableTemporal).first() clock_query = session.query( models.SimpleTableTemporal.temporal_options.clock_table) assert clock_query.count() == 1 assert t.vclock == 1 assert t.clock.count() == 1 clock = clock_query.first() prop_a_history_model = temporal.get_history_model( models.SimpleTableTemporal.prop_a) prop_b_history_model = temporal.get_history_model( models.SimpleTableTemporal.prop_b) for attr, history_table in [ ('prop_a', prop_a_history_model), ('prop_b', prop_b_history_model), ]: clock_query = session.query(history_table).count() assert clock_query == 1, "missing entry for %r" % history_table history = session.query(history_table).first() assert clock.tick in history.vclock assert getattr(history, attr) == getattr(t, attr)
def test_doesnt_duplicate_unnecessary_history(self, session): history_tables = { 'prop_a': temporal.get_history_model( models.SimpleTableTemporal.prop_a), 'prop_b': temporal.get_history_model( models.SimpleTableTemporal.prop_b), 'prop_c': temporal.get_history_model( models.SimpleTableTemporal.prop_c), } t = models.SimpleTableTemporal( prop_a=1, prop_b='foo', prop_c=datetime.datetime(2016, 5, 11, tzinfo=datetime.timezone.utc)) session.add(t) session.commit() with t.clock_tick(): t.prop_a = 1 t.prop_c = datetime.datetime(2016, 5, 11, tzinfo=datetime.timezone.utc) session.commit() assert t.vclock == 1 for attr, history in history_tables.items(): clock_query = session.query(history) assert clock_query.count() == 1, \ "%r missing a history entry for initial value" % history recorded_history = clock_query.first() assert 1 in recorded_history.vclock assert getattr(t, attr) == getattr(recorded_history, attr)
def test_multiple_edits(self, session): history_models = { 'prop_a': temporal.get_history_model( models.SimpleConcreteChildTemporalTable.prop_a), 'prop_b': temporal.get_history_model( models.SimpleConcreteChildTemporalTable.prop_b), } t = models.SimpleConcreteChildTemporalTable(prop_a=1, prop_b='foo') session.add(t) session.commit() for attr, history in history_models.items(): clock_query = session.query(history) assert clock_query.count() == 1, \ "%r missing a history entry for initial value" % history recorded_history = clock_query.first() assert 1 in recorded_history.vclock assert getattr(t, attr) == getattr(recorded_history, attr) with t.clock_tick(): t.prop_a = 2 t.prop_b = 'bar' session.commit() for attr, history in history_models.items(): clock_query = session.query(history) assert clock_query.count() == 2, \ "%r missing a history entry for initial value" % history recorded_history = clock_query[-1] assert 2 in recorded_history.vclock assert getattr(t, attr) == getattr(recorded_history, attr) with t.clock_tick(): t.prop_a = 3 t.prop_b = 'foobar' session.commit() for attr, history in history_models.items(): clock_query = session.query(history) assert clock_query.count() == 3, \ "%r missing a history entry for initial value" % history recorded_history = clock_query[-1] assert 3 in recorded_history.vclock assert getattr(t, attr) == getattr(recorded_history, attr)
def test_init_adds_clock_tick(self, session): clock_query = session.query( models.SimpleConcreteChildTemporalTable.temporal_options. clock_model, ).count() assert clock_query == 0 t = models.SimpleConcreteChildTemporalTable( prop_a=1, prop_b='foo', prop_c=datetime.datetime(2016, 5, 11, 1, 2, 3, tzinfo=datetime.timezone.utc)) assert t.clock.count() == 1 session.add(t) session.commit() t = session.query(models.SimpleConcreteChildTemporalTable).first() clock_query = session.query( models.SimpleConcreteChildTemporalTable.temporal_options. clock_model, ) assert clock_query.count() == 1 assert t.vclock == 1 assert t.clock.count() == 1 clock = clock_query.first() prop_a_history_model = temporal.get_history_model( models.SimpleConcreteChildTemporalTable.prop_a) prop_b_history_model = temporal.get_history_model( models.SimpleConcreteChildTemporalTable.prop_b) prop_c_history_model = temporal.get_history_model( models.SimpleConcreteChildTemporalTable.prop_c) for attr, history_table in [ ('prop_a', prop_a_history_model), ('prop_b', prop_b_history_model), ('prop_c', prop_c_history_model), ]: clock_query = session.query(history_table).count() assert clock_query == 1, "missing entry for %r" % history_table history = session.query(history_table).first() assert clock.tick in history.vclock assert getattr(history, attr) == getattr(t, attr)
def test_init_adds_clock_tick(self, session, newstylemodel): clock_query = session.query( models.NewStyleModel.temporal_options.clock_model).count() assert clock_query == 0 assert newstylemodel.clock.count() == 1 session.add(newstylemodel) session.commit() t = session.query(models.NewStyleModel).first() clock_query = session.query( models.NewStyleModel.temporal_options.clock_model) assert clock_query.count() == 1 assert t.vclock == 1 assert t.clock.count() == 1 clock = clock_query.first() for attr, backref in [ ('description', 'description_history'), ('int_prop', 'int_prop_history'), ('bool_prop', 'bool_prop_history'), ('datetime_prop', 'datetime_prop_history'), ]: history_model = temporal.get_history_model(getattr(models.NewStyleModel, attr)) backref_history_query = getattr(t, backref) clock_query = session.query(history_model).count() assert clock_query == 1, "missing entry for %r" % history_model assert clock_query == backref_history_query.count() backref_history = backref_history_query[0] history = session.query(history_model).first() assert clock.tick in history.vclock assert clock.tick in backref_history.vclock assert getattr(history, attr) == getattr(t, attr) == getattr(backref_history, attr)
def test_joined_enums_create(session): session.add_all([ models.JoinedEnumA(val='foo'), models.JoinedEnumA(val='foobar'), models.JoinedEnumB(val='bar'), models.JoinedEnumB(val='barfoo'), models.JoinedEnumB(val='barfoo'), ]) session.commit() assert session.query(models.JoinedEnumBase).count() == 5 enum_a_val_history = temporal.get_history_model(models.JoinedEnumA.val) assert session.query(enum_a_val_history).count() == 2 enum_b_val_history = temporal.get_history_model(models.JoinedEnumB.val) assert session.query(enum_b_val_history).count() == 3
def test_edit_on_double_wrapped(self, session): double_wrapped_session = temporal.temporal_session(session) t = models.SimpleTableTemporal( prop_a=1, prop_b='foo', prop_c=datetime.datetime(2016, 5, 11, 1, 2, 3, tzinfo=datetime.timezone.utc), prop_d={'foo': 'old value'}, prop_e=psql_extras.DateRange(datetime.date(2016, 1, 1), datetime.date(2016, 1, 10)), prop_f=['old', 'stuff'], ) double_wrapped_session.add(t) double_wrapped_session.commit() t = double_wrapped_session.query(models.SimpleTableTemporal).first() with t.clock_tick(): t.prop_a = 2 t.prop_b = 'bar' double_wrapped_session.commit() history_tables = { 'prop_a': temporal.get_history_model(models.SimpleTableTemporal.prop_a), 'prop_b': temporal.get_history_model(models.SimpleTableTemporal.prop_b), } for attr, history in history_tables.items(): clock_query = session.query(history) assert clock_query.count() == 2, \ "%r missing a history entry for initial value" % history recorded_history = clock_query[-1] assert 2 in recorded_history.vclock assert getattr(t, attr) == getattr(recorded_history, attr)
def test_default_parameters(self, session): t = models.TemporalTableWithDefault(prop_a=1, prop_b='foo') session.add(t) session.commit() t = session.query(models.TemporalTableWithDefault).first() clock_query = session.query( models.TemporalTableWithDefault.temporal_options.clock_table) assert clock_query.count() == 1 assert t.vclock == 1 assert t.clock.count() == 1 # some sanity check assert t.prop_default == 10 assert t.prop_callable, "a value here" assert isinstance(t.prop_func, datetime.datetime) clock = clock_query.first() history_tables = { 'prop_func': temporal.get_history_model( models.TemporalTableWithDefault.prop_func), 'prop_callable': temporal.get_history_model( models.TemporalTableWithDefault.prop_callable), 'prop_default': temporal.get_history_model( models.TemporalTableWithDefault.prop_default), 'prop_a': temporal.get_history_model(models.TemporalTableWithDefault.prop_a), 'prop_b': temporal.get_history_model(models.TemporalTableWithDefault.prop_b), } for attr, history in history_tables.items(): clock_query = session.query(history) assert clock_query.count() == 1, \ "%r missing a history entry for initial value" % history recorded_history = clock_query.first() assert clock.tick in recorded_history.vclock assert getattr(t, attr) == getattr(recorded_history, attr)
def test_indentifiers_too_long(self): models.edgecase_metadata.create_all(self.connection) clock_table = models.HugeIndices.temporal_options.clock_table.__table__ assert clock_table.name == ('testing_a_' + models.REALLY_REALLY + 'long_table_2907') history_model = temporal.get_history_model( models.HugeIndices.really_really_really_really_really_long_column) history_table = history_model.__table__ assert history_table.name == ('testing_a_' + models.REALLY_REALLY + 'long_table_9e40') assert ('testing_a_' + models.REALLY_REALLY + 'long_table_3b65' in {idx.name for idx in history_table.indexes})