def setUp(self):
        self.session = Session(0, self.connection['test_tori_db_session'])

        for collection in self.session.collections:
            collection._api.remove() # Reset the database

        self.__inject_data_with_one_to_many_association()
    def setUp(self):
        self.session = Session(0, self.connection['test_tori_db_uow_cascade_on_refresh'])

        data_set = {
            'regions': [
                {'_id': 1, 'name': 'Asia'},
                {'_id': 2, 'name': 'Europe'},
                {'_id': 3, 'name': 'North America'}
            ],
            'countries': [
                {'_id': 1, 'region': 3, 'name': 'Canada'},
                {'_id': 2, 'region': 2, 'name': 'England'},
                {'_id': 3, 'region': 1, 'name': 'Japan'},
                {'_id': 4, 'region': 1, 'name': 'Thailand'}
            ]
        }

        self.session.collection(Region)._api.remove()

        for region in data_set['regions']:
            self.session.collection(Region)._api.insert(region)

        self.session.collection(Country)._api.remove()

        for country in data_set['countries']:
            self.session.collection(Country)._api.insert(country)
    def setUp(self):
        self.session = Session(0, self.connection['test_tori_db_session_assoc_m2m'], self.registered_types)

        for collection in self.session.collections:
            collection._api.remove() # Reset the database

        self.session.db['groups_members'].remove({}) # Reset the associations

        self.__set_fixtures()
Beispiel #4
0
    def setUp(self):
        self.session = Session(0, self.connection['test_tori_db_mapper_link'], self.registered_types)

        for collection in self.session.collections:
            collection._api.remove() # Reset the database

        self.session.collection(Character)._api.insert(self.ts_character)
        self.session.collection(Job)._api.insert(self.ts_job)
        self.session.collection(Weapon)._api.insert(self.ts_shield)
        self.session.collection(Weapon)._api.insert(self.ts_sword)
class TestDbUowAssociationManyToMany(TestCase):
    connection       = Connection()
    registered_types = {
        'groups':  Group,
        'members': Member
    }

    def setUp(self):
        self.session = Session(0, self.connection['test_tori_db_session_assoc_m2m'], self.registered_types)

        for collection in self.session.collections:
            collection._api.remove() # Reset the database

        self.session.db['groups_members'].remove({}) # Reset the associations

        self.__set_fixtures()

    def test_load(self):
        groups  = self.session.collection(Group)
        members = self.session.collection(Member)

        group_a  = groups.filter_one({'name': 'group a'})
        member_d = members.filter_one({'name': 'member d'})

        self.assertTrue(group_a.members._loaded, 'The IDs should be loaded by UOW.')
        self.assertEqual(2, len(group_a.members))
        self.assertTrue(group_a.members._loaded)
        self.assertEqual('member a', group_a.members[0].name)
        self.assertEqual('member b', group_a.members[1].name)

    def test_with_new_entites(self):
        groups  = self.session.collection(Group)
        members = self.session.collection(Member)

        associations = self.session.collection(Group.__relational_map__['members'].association_class.cls)

        group = groups.new(name='From Up On Poppy Hill')

        umi   = members.new(name='Umi')
        shun  = members.new(name='Shun')
        shiro = members.new(name='Shiro')

        group.members.extend([umi, shun, shiro])

        groups.post(group)

        self.assertEqual(4, groups._api.count())
        self.assertEqual(7, members._api.count())
        self.assertEqual(9, associations._api.count())

    def test_commit(self):
        groups  = self.session.collection(Group)
        members = self.session.collection(Member)

        associations = self.session.collection(Group.__relational_map__['members'].association_class.cls)

        group_a  = groups.filter_one({'name': 'group a'})
        group_b  = groups.filter_one({'name': 'group b'})
        group_c  = groups.filter_one({'name': 'group c'})
        member_d = members.filter_one({'name': 'member d'})

        groups.delete(group_c)

        group_a.members.append(member_d)
        group_b.members.append(member_d)

        group_a.members.pop(0)

        self.session.persist(group_a, group_b)
        self.session.flush()

        self.assertEqual(2, groups._api.count())
        self.assertEqual(5, associations._api.count())

    def test_commit_with_new_element_on_explicit_persistence_and_repository(self):
        groups  = self.session.collection(Group)
        members = self.session.collection(Member)

        associations = self.session.collection(Group.__relational_map__['members'].association_class.cls)

        group_a  = groups.filter_one({'name': 'group a'})
        group_b  = groups.filter_one({'name': 'group b'})
        group_c  = groups.filter_one({'name': 'group c'})
        member_d = members.filter_one({'name': 'member d'})

        member_d.name = 'extra member'

        member_e = members.new(name='member e')

        groups.delete(group_c)

        group_a.members.append(member_d)
        group_a.members.pop(0)
        groups.put(group_a)

        group_b.members.append(member_e)
        groups.put(group_b)

        self.assertEqual(2, groups._api.count())
        self.assertEqual(5, associations._api.count())

    def test_commit_with_new_element_on_explicit_persistence_and_session(self):
        groups  = self.session.collection(Group)
        members = self.session.collection(Member)

        associations = self.session.collection(Group.__relational_map__['members'].association_class.cls)

        group_a  = groups.filter_one({'name': 'group a'})
        group_b  = groups.filter_one({'name': 'group b'})
        group_c  = groups.filter_one({'name': 'group c'})
        member_d = members.filter_one({'name': 'member d'})

        member_d.name = 'extra member'

        member_e = members.new(name='member e')

        groups.delete(group_c)

        group_a.members.append(member_d)
        group_b.members.append(member_e)

        group_a.members.pop(0)

        self.session.persist(group_a)
        self.session.persist(group_b)
        self.session.flush()

        self.assertEqual(2, groups._api.count())

        self.assertEqual(5, associations._api.count())

    def __set_fixtures(self):
        data_sets = {
            'members': [
                {'name': 'member a'},
                {'name': 'member b'},
                {'name': 'member c'},
                {'name': 'member d'}
            ],
            'groups': [
                {'name': 'group a'},
                {'name': 'group b'},
                {'name': 'group c'}
            ]
        }

        associations = [
            (0, 0),
            (0, 1),
            (1, 1),
            (1, 2),
            (2, 0),
            (2, 2)
        ]

        api = self.session.collection(Member)._api

        for data in data_sets['members']:
            object_id   = api.insert(data)
            data['_id'] = object_id

        api = self.session.collection(Group)._api

        for data in data_sets['groups']:
            object_id   = api.insert(data)
            data['_id'] = object_id

        api = self.session.db['groups_members']

        api.remove()

        for origin, destination in associations:
            api.insert({
                'origin':      data_sets['groups'][origin]['_id'],
                'destination': data_sets['members'][destination]['_id']
            })

        collection_names = self.session.db.collection_names()

        self.assertIn('members', collection_names)
        self.assertIn('groups', collection_names)
        self.assertIn('groups_members', collection_names)
class TestDbUowAssociationOneToMany(TestCase):
    connection = Connection()

    def setUp(self):
        self.session = Session(0, self.connection['test_tori_db_session'])

        for collection in self.session.collections:
            collection._api.remove() # Reset the database

        self.__inject_data_with_one_to_many_association()

    def test_fetching(self):
        c = self.session.collection(Developer)

        boss = c.filter_one({'name': 'boss'})

        self.assertIsInstance(boss.delegates, list)

        self.assertIsInstance(boss.delegates[0], ProxyObject)
        self.assertEqual(boss.delegates[0].name, 'a')
        self.assertIsInstance(boss.delegates[1], ProxyObject)
        self.assertEqual(boss.delegates[1].name, 'b')

    def test_cascading_on_persist(self):
        c = self.session.collection(Developer)

        boss = c.filter_one({'name': 'boss'})
        boss.delegates[0].name = 'assistant'

        self.session.persist(boss)
        self.session.flush()

        data = c._api.find_one({'_id': boss.delegates[0].id})

        self.assertEqual(boss.delegates[0].name, data['name'])

    def test_update_association(self):
        c = self.session.collection(Developer)

        boss = c.filter_one({'name': 'boss'})
        boss.delegates[0].name = 'assistant'

        boss.delegates.append(Developer('c'))

        self.session.persist(boss)
        self.session.flush()

        data = c._api.find_one({'name': 'c'})

        self.assertIsNotNone(data)
        self.assertEqual(boss.delegates[2].id, data['_id'])

        data = c._api.find_one({'name': 'boss'})

        self.assertEqual(3, len(data['delegates']))

        for delegate in boss.delegates:
            self.assertIn(delegate.id, data['delegates'])

    def test_cascading_on_delete_with_some_deps(self):
        c = self.session.collection(Developer)

        boss = c.filter_one({'name': 'boss'})
        boss.delegates[0].name = 'assistant'

        boss.delegates.append(Developer('c'))

        self.session.persist(boss)

        architect = Developer('architect', delegates=[boss.delegates[0]])

        self.session.persist(architect)
        self.session.flush()

        self.assertEqual(5, len(c.filter()))

        self.session.delete(architect)
        self.session.flush()

        self.assertEqual(4, len(c.filter()), 'should have some dependencies left (but no orphan node)')

    def test_cascading_on_delete_with_no_deps(self):
        c = self.session.collection(Developer)

        boss = c.filter_one({'name': 'boss'})

        print('point a')

        for d in c._api.find():
            print(d)

        boss.delegates[0].name = 'assistant'

        boss.delegates.append(Developer('c'))

        self.session.persist(boss)

        print('point b')

        for d in c._api.find():
            print(d)

        architect = Developer('architect', delegates=[boss.delegates[0]])

        self.session.persist(architect)
        self.session.flush()

        print('point c')

        for d in c._api.find():
            print(d)

        self.session.delete(architect)
        self.session.delete(boss)
        self.session.flush()

        count = len(c.filter())

        print('point d')

        for d in c._api.find():
            print(d)

        self.assertEqual(0, count, 'There should not exist dependencies left (orphan removal). (remaining: {})'.format(count))

    def __inject_data_with_one_to_many_association(self):
        api = self.session.collection(Developer)._api

        api.remove()

        a_id = api.insert({'name': 'a'})
        b_id = api.insert({'name': 'b'})

        api.insert({'name': 'boss', 'delegates': [a_id, b_id]})
class TestDbUowCascadeOnRefresh(TestCase):
    connection = Connection()

    def setUp(self):
        self.session = Session(0, self.connection['test_tori_db_uow_cascade_on_refresh'])

        data_set = {
            'regions': [
                {'_id': 1, 'name': 'Asia'},
                {'_id': 2, 'name': 'Europe'},
                {'_id': 3, 'name': 'North America'}
            ],
            'countries': [
                {'_id': 1, 'region': 3, 'name': 'Canada'},
                {'_id': 2, 'region': 2, 'name': 'England'},
                {'_id': 3, 'region': 1, 'name': 'Japan'},
                {'_id': 4, 'region': 1, 'name': 'Thailand'}
            ]
        }

        self.session.collection(Region)._api.remove()

        for region in data_set['regions']:
            self.session.collection(Region)._api.insert(region)

        self.session.collection(Country)._api.remove()

        for country in data_set['countries']:
            self.session.collection(Country)._api.insert(country)

    def test_cascade_from_owning_side(self):
        japan = self.session.collection(Country).get(3)

        self.assertEqual('Japan', japan.name)
        self.assertEqual('Asia', japan.region.name)

        # At this point, Region 1 is loaded into the memory.
        # Bypass the identity map and then update the data manually.
        self.session.collection(Region)._api.update({'_id': 1}, {'$set': {'name': 'Asia and Oceanic'}})

        # Now, try to persist the data.
        japan.name = u'日本'

        self.session.persist(japan)
        self.session.flush()

        # Confirm that only the name of the country is updated
        self.assertEqual(u'日本', japan.name)
        self.assertEqual('Asia', japan.region.name)

        # Refresh the entity
        self.session.refresh(japan)

        # Confirm that only the name of the region is updated after refreshing
        self.assertEqual(u'日本', japan.name)
        self.assertEqual('Asia and Oceanic', japan.region.name)

    def _test_cascade_from_inverted_side(self):
        europe = self.session.collection(Region).get(2)

        self.assertEqual('Europe', europe.name)
        self.assertEqual('England', europe.countries[0].name)

        # At this point, Region 1 is loaded into the memory.
        # Bypass the identity map and then update the data manually.
        self.session.collection(Region)._api.update({'_id': 2}, {'$set': {'name': 'United Kingdom of Great Britain and Ireland'}})

        # Now, try to persist the data.
        europe.name = 'Europian Union'

        self.session.persist(europe)
        self.session.flush()

        # Confirm that only the name of the country is updated
        self.assertEqual('Europian Union', europe.name)
        self.assertEqual('England', europe.countries[0].name)

        # Refresh the entity
        self.session.refresh(europe)

        # Confirm that refreshing doesn't work with reverse-mapping properties.
        self.assertEqual('Europian Union', europe.name)
        self.assertEqual('England', europe.countries[0].name)
Beispiel #8
0
class TestDbMapperLink(unittest.TestCase):
    connection       = Connection()
    registered_types = {
        'c': Character,
        'w': Weapon,
        'j': Job,
        's': Skill
    }

    ts_character = {
        '_id':   1,
        'name':  'Shiroyuki',
        'level': 82,
        'job':   1,
        'left_hand':  2,
        'right_hand': 1
    }

    ts_job = {
        '_id':    1,
        'name':   'Knight',
        'level':  8,
        'skills': [
            {'name': 'Attack'},
            {'name': 'Charge'}
        ]
    }

    ts_shield = {
        '_id':    2,
        'name':   'Shield',
        'attack': 76,
        'defend': 234
    }

    ts_sword = {
        '_id':    1,
        'name':   'Sword',
        'attack': 495,
        'defend': 89
    }

    def setUp(self):
        self.session = Session(0, self.connection['test_tori_db_mapper_link'], self.registered_types)

        for collection in self.session.collections:
            collection._api.remove() # Reset the database

        self.session.collection(Character)._api.insert(self.ts_character)
        self.session.collection(Job)._api.insert(self.ts_job)
        self.session.collection(Weapon)._api.insert(self.ts_shield)
        self.session.collection(Weapon)._api.insert(self.ts_sword)

    def tearDown(self):
        pass

    def test_get(self):
        character = self.session.collection(Character).filter_one()

        self.assertEqual('Shiroyuki', character.name)
        self.assertIsInstance(character.job, ProxyObject) # Check the type of the proxy object
        self.assertIsInstance(character.job._actual, Job) # Check the type of the actual object
        self.assertEqual(1, character.job.id) # Check if the property of the actual object is accessible via the proxy
        self.assertEqual('Knight', character.job.name) # Check if the property of the actual object is accessible via the proxy
        self.assertFalse(character.job._read_only) # Check if the proxy setting is readable
Beispiel #9
0
    def setUp(self):
        self.session = Session(0, self.connection['test_tori_db_session'], self.registered_types)

        for collection in self.session.collections:
            collection._api.remove() # Reset the database
Beispiel #10
0
class TestDbSession(TestCase):
    connection       = Connection()
    registered_types = {
        'developer': Developer,
        'computer':  Computer,
        'testnode':  TestNode
    }

    def setUp(self):
        self.session = Session(0, self.connection['test_tori_db_session'], self.registered_types)

        for collection in self.session.collections:
            collection._api.remove() # Reset the database

    def test_commit_with_insert_with_cascading(self):
        reference_map = self.__inject_data_with_cascading()

        collection = self.session.collection(TestNode)
        doc        = collection.filter_one({'name': 'a'})

        self.assertEqual(len(reference_map), len(collection.filter()))
        self.assertEqual(reference_map['a'].id, doc.id)

    def test_commit_with_insert_without_cascading(self):
        reference_map = self.__mock_data_without_cascading()

        developer_collection = self.session.collection(Developer)
        computer_collection = self.session.collection(Computer)

        self.session.persist(reference_map['d1'])
        self.session.flush()

        self.assertEqual(1, len(developer_collection.filter()))
        self.assertEqual(0, len(computer_collection.filter()))

        developer = developer_collection.filter_one({'name': 'Shiroyuki'})

        self.assertIsNone(developer.computer.id)

        raw_data = developer_collection._api.find_one({'_id': developer.id})

        self.assertIsNone(raw_data['computer'])

    def test_commit_with_update(self):
        reference_map = self.__inject_data_with_cascading()

        doc = self.session.collection(TestNode).filter_one({'name': 'a'})
        doc.name = 'root'

        self.session.persist(doc)
        self.session.flush()

        docs = self.session.collection(TestNode).filter()

        self.assertEqual(len(reference_map), len(docs))
        self.assertEqual(reference_map['a'].id, doc.id)
        self.assertEqual(reference_map['a'].name, doc.name)

        doc = self.session.collection(TestNode).filter_one({'name': 'root'})

        self.assertEqual(reference_map['a'].id, doc.id)

    def test_commit_with_update_with_cascading(self):
        reference_map = self.__inject_data_with_cascading()

        doc = self.session.collection(TestNode).filter_one({'name': 'a'})
        doc.left.name = 'left'

        self.session.persist(doc)
        self.session.flush()

        docs = self.session.collection(TestNode).filter()

        self.assertEqual(len(reference_map), len(docs))
        self.assertEqual(reference_map['b'].id, doc.left.id)
        self.assertEqual(reference_map['b'].name, doc.left.name)

        doc = self.session.collection(TestNode).filter_one({'name': 'a'})

        self.assertEqual(reference_map['b'].id, doc.left.id)

    def test_commit_with_update_without_cascading(self):
        reference_map = self.__mock_data_without_cascading()

        developer_collection = self.session.collection(Developer)
        computer_collection = self.session.collection(Computer)

        self.session.persist(reference_map['d1'], reference_map['c1'])
        self.session.flush()

        self.assertEqual(1, len(developer_collection.filter()))
        self.assertEqual(1, len(computer_collection.filter()))

        developer = developer_collection.filter_one({'name': 'Shiroyuki'})
        developer.computer.name = 'MacBook Pro'

        self.session.persist(developer)
        self.session.flush()

        record = self.session._uow.retrieve_record(developer.computer)

        self.assertEqual(Record.STATUS_CLEAN, record.status)

        raw_data = computer_collection._api.find_one({'_id': reference_map['c1'].id})

        self.assertNotEqual(raw_data['name'], developer.computer.name)

    def test_commit_with_delete(self):
        reference_map = self.__inject_data_with_cascading()

        collection = self.session.collection(TestNode)
        doc_g      = collection.filter_one({'name': 'g'})

        self.session.delete(doc_g)
        self.session.flush()

        self.assertEqual(len(reference_map) - 1, len(collection.filter()))

    def test_commit_with_delete_with_cascading(self):
        reference_map = self.__inject_data_with_cascading()

        collection = self.session.collection(TestNode)
        doc_a      = collection.filter_one({'name': 'a'})

        self.session.delete(doc_a)
        self.session.flush()

        self.assertEqual(len(reference_map) - 4, len(collection.filter()))

    def test_commit_with_delete_with_cascading_with_some_dependency_left(self):
        reference_map     = self.__inject_data_with_cascading()
        expected_max_size = len(reference_map) + 1

        collection = self.session.collection(TestNode)

        # Added an extra node that relies on node "f" without using the collection.
        collection._api.insert({'left': None, 'right': reference_map['f'].id, 'name': 'extra'})

        doc_h = collection.filter_one({'name': 'h'})

        self.session.delete(doc_h)
        self.session.flush()

        self.assertEqual(
            expected_max_size - 1,
            len(collection.filter()),
            'Expected for %s nodes remaining' % expected_max_size
        )

    def test_commit_with_delete_with_cascading_with_some_unsupervised_dependency_left(self):
        reference_map     = self.__inject_data_with_cascading()
        expected_max_size = len(reference_map) + 1

        collection = self.session.collection(TestNode)

        # Added an extra node that relies on node "f" without using the collection.
        collection._api.insert({'left': None, 'right': reference_map['f'].id, 'name': 'extra'})

        self.session.delete(reference_map['e'], reference_map['h'])
        self.session.flush()

        self.assertEqual(expected_max_size - 2, len(collection.filter()))

    def test_commit_with_delete_with_cascading_with_no_dependency_left(self):
        reference_map = self.__inject_data_with_cascading()

        collection = self.session.collection(TestNode)

        self.session.delete(reference_map['e'], reference_map['h'])
        self.session.flush()

        self.assertEqual(len(reference_map) - 3, len(collection.filter()))

    def __inject_data_with_cascading(self):
        reference_map = {}

        reference_map['g'] = TestNode('g', None, None)
        reference_map['f'] = TestNode('f', None, None)
        reference_map['e'] = TestNode('e', None, reference_map['f'])
        reference_map['d'] = TestNode('d', None, None)
        reference_map['c'] = TestNode('c', reference_map['d'], None)
        reference_map['b'] = TestNode('b', None, reference_map['d'])
        reference_map['a'] = TestNode('a', reference_map['b'], reference_map['c'])
        reference_map['h'] = TestNode('h', reference_map['f'], None)

        self.session.persist(reference_map['a'], reference_map['e'], reference_map['g'], reference_map['h'])
        self.session.flush()

        return reference_map

    def __mock_data_without_cascading(self):
        reference_map = {}

        reference_map['c1'] = Computer('MacBook Air')
        reference_map['d1'] = Developer('Shiroyuki', reference_map['c1'])

        return reference_map