def test_ReltionshipFields_DOT_dict__by_order(connection: dcdb.DBConnection): # TODO should refactor to have a stack based dictionary class because # otherwise this behavior is a tad confusing. @dataclass() class Box: widget = dcdb.RelationshipFields.dict("Thing.name", "parent_id", by_order="version") @dataclass() class Thing: name: str version: int parent_id: int = None connection.binds(Box, Thing) b = connection.t.Box() object1 = b.widget.create(name="Foo", version=1) object2 = b.widget.create(name="Foo", version=3) object3 = b.widget.create(name="Foo", version=2) assert b.widget['Foo'].id == 2 object3 = b.widget.create(name="Foo", version=4) assert b.widget['Foo'].id == 4
def test_RelationshipFields_DOT_unordered_list__works( connection: dcdb.DBConnection): # whoops, realized this isn't tested inside dcdb but in harvester @dataclass() class Box: contents = dcdb.RelationshipFields.unordered_list("Widget", "box_id") @dataclass() class Widget: name: str quantity: int box_id: int = None connection.bind(Box, Widget) box = connection.t.Box() box.contents.create(name="Nails", quantity=300) box.contents.create(name="Hammer", quantity=2) box.contents.create(name="Measuring tape", quantity=1) box.contents.create(name="Bandaids", quantity=25) many_widgets = box.contents.where("quantity > ?", 1) # type: dcdb.DBCursorProxy alot_widgets = box.contents.where("quantity >= ?", 25) # type: dcdb.DBCursorProxy assert len(list(many_widgets)) == 3 assert len(list(alot_widgets.fetchall())) == 2 # NOTE relying heavily on order of inserts assert box.contents[1].name == "Hammer" assert len(box.contents) == 4 del box.contents[1] assert len(box.contents) == 3 assert connection.t.Widget.Count() == 3 assert box.contents[1].name == "Measuring tape" with pytest.raises(TypeError): box.contents[5] = connection.t.Widget(name="Stuff", quantity=10**5) assert len(box.contents) == 3 assert connection.t.Widget.Count() == 4 widget = box.contents.first() assert widget.name == "Nails" widget.delete() assert len(box.contents) == 2 assert box.contents.first().name == "Measuring tape" assert box.contents[1].name == "Bandaids" bandaids = box.contents.pop(1) assert bandaids.quantity == 25 assert len(box.contents) == 1 assert connection.t.Widget.Count() == 3
def conn2(connection: dcdb.DBConnection): """ :param connection: dcdb.DBConnection uses the connection fixture :return: """ @dataclass() class Widget: name: str age: int panacea: bool connection.bind(Widget) return connection
def test_RelationshipFields_dot_dict__works(connection: dcdb.DBConnection): @dataclass() class House: price: float name: str furniture = dcdb.RelationshipFields.dict("Furniture", "type", "house_id") @dataclass() class Furniture: type: str material: str quantity: int house_id: int = None # TODO foreign key constraint # setup connection.binds(House, Furniture) house = connection.t.House(price=123.45, name="The Manor") # Ensure relationship is bound on direct creation house.furniture.create(type="Chair", material="Wood", quantity=10) assert len(house.furniture) == 1 assert house.furniture["chair"] is None assert house.furniture["Chair"].material == "Wood" # ensure binding is independant sofa = connection.t.Furniture(type="Sofa", material="cloth", quantity=2) assert len(house.furniture) == 1 # test count and retrieval house.furniture.add(sofa) assert len(house.furniture) == 2 assert house.furniture["Sofa"].quantity == 2 # verify integrity keys = house.furniture.keys() assert "Sofa" in keys assert "Chair" in keys # del house.furniture['Chair'] furniture_count = connection.direct( "SELECT count(*) FROM Furniture").fetchone()[0] assert furniture_count == 2 assert len(house.furniture) == 1
def test_mutation_tracking(conn2: dcdb.DBConnection): @dataclass class OtherWidget: length: int height: int weight: int name: str conn2.bind(OtherWidget) bob = conn2.t.Widget(name="Bob", age=44, panacea=False) thingamajig = conn2.t.OtherWidget(name="Thinga 2000", length=10, height=1, weight=8) assert bob._is_dirty is False assert thingamajig._is_dirty is False # Known and intended gotcha thingamajig.height = 5 assert thingamajig._is_dirty is False with conn2.track_changes(): bob.age = 22 assert bob._is_dirty is True assert len(conn2._dirty_records) == 1 thingamajig.weight = 12 thingamajig.name = "New Hotness 2.0" assert len(conn2._dirty_records) == 2 assert thingamajig._is_dirty is True assert len(conn2._dirty_records) == 0 assert bob._is_dirty is False assert thingamajig._is_dirty is False bob_copy = conn2.t.Widget.Get("id=?", bob.id) thing_copy = conn2.t.OtherWidget.Get("id=?", thingamajig.id) assert bob_copy.age == 22 assert thingamajig.weight == 12 assert thingamajig.name == "New Hotness 2.0" # Intentional and intended, change tracking is only available when explicitly tracking assert thingamajig.height == 5