예제 #1
0
    def get_page_by_filter(self, correlation_id: Optional[str],
                           filter: FilterParams,
                           paging: PagingParams) -> DataPage:
        filters = filter if filter is not None else FilterParams()
        key = filters.get_as_nullable_string("key")

        paging = paging if not (paging is None) else PagingParams()
        skip = paging.get_skip(0)
        take = paging.get_take(100)

        result = []
        self.__lock.acquire()
        try:
            for item in self.__items:
                if not (key is None) and key != item.key:
                    continue

                skip -= 1
                if skip >= 0: continue

                take -= 1
                if take < 0: break

                result.append(item)
        finally:
            self.__lock.release()

        return DataPage(result)
    def test_get_with_filter(self):
        # Create 3 beacons
        self.test_create_beacons()

        # Filter by id
        page = self._persistence.get_page_by_filter(
            None, FilterParams.from_tuples("id", "1"), PagingParams())
        assert page is not None
        assert len(page.data) == 1

        # Filter by udi
        page = self._persistence.get_page_by_filter(
            None, FilterParams.from_tuples("udi", "00002"), PagingParams())
        assert page is not None
        assert len(page.data) == 1

        # Filter by udis
        page = self._persistence.get_page_by_filter(
            None, FilterParams.from_tuples("udis", '00001,00003'),
            PagingParams())
        assert page is not None
        assert len(page.data) == 2

        # Filter by udi
        page = self._persistence.get_page_by_filter(
            None, FilterParams.from_tuples("site_id", "1"), PagingParams())
        assert page is not None
        assert len(page.data) == 2
    def get_page_by_filter(self,
                           correlation_id: Optional[str],
                           filter: Any,
                           paging: PagingParams,
                           sort: Any = None,
                           select: Any = None) -> DataPage:
        """
        Gets a page of data items retrieved by a given filter and sorted according to sort parameters.

        This method shall be called by a public :func:`get_page_by_filter` method from child class that
        receives :class:`FilterParams <pip_services3_commons.data.FilterParams.FilterParams>` and converts them into a filter function.

        :param correlation_id: (optional) transaction id to trace execution through call chain.

        :param filter: (optional) a filter function to filter items

        :param paging: (optional) paging parameters

        :param sort: (optional) sorting parameters

        :param select: (optional) projection parameters (not used yet)

        :return: a data page of result by filter.
        """
        with self._lock:
            items = deepcopy(self._items)

        # Filter and sort
        if filter is not None:
            items = list(filtered(filter, items))
        if sort is not None:
            items = list(filtered(sort, items))
            # items = sorted(items, sort)

        # Prepare paging parameters
        paging = paging if paging is not None else PagingParams()
        skip = paging.get_skip(-1)
        take = paging.get_take(self._max_page_size)

        # Get a page
        data = items
        if skip > 0:
            data = data[skip:]
        if take > 0:
            data = data[:take]

        # Convert values
        if not (select is None):
            data = map(select, data)

        self._logger.trace(correlation_id,
                           "Retrieved " + str(len(data)) + " items")

        # Return a page
        return DataPage(data, len(items))
예제 #4
0
    def get_page_by_filter(self, correlation_id: Optional[str], filter: Any, paging: PagingParams,
                           sort: Any, select: Any) -> DataPage:
        """
        Gets a page of data items retrieved by a given filter and sorted according to sort parameters.
        This method shall be called by a public getPageByFilter method from child class that
        receives FilterParams and converts them into a filter function.

        :param correlation_id: (optional) transaction id to trace execution through call chain.
        :param filter: (optional) a filter JSON object
        :param paging: (optional) paging parameters
        :param sort: (optional) sorting JSON object
        :param select: (optional) projection JSON object
        :return: a data page or raise error
        """
        select = select if select and len(select) > 0 else '*'
        query = "SELECT " + select + " FROM " + self._quoted_table_name()

        # Adjust max item count based on configuration
        paging = paging or PagingParams()
        skip = paging.get_skip(-1)
        take = paging.get_take(self._max_page_size)
        paging_enabled = paging.total

        if filter and filter != '':
            query += " WHERE " + filter

        if sort:
            query += " ORDER BY " + sort

        query += " LIMIT " + str(take)
        
        if skip >= 0:
            query += " OFFSET " + str(skip)

        result = self._request(query)
        items = result['items']

        if items is not None:
            self._logger.trace(correlation_id, "Retrieved %d from %s", len(items), self._table_name)

        items = list(map(self._convert_to_public, items))

        if paging_enabled:
            query = 'SELECT COUNT(*) AS count FROM ' + self._quoted_table_name()
            if filter is not None and filter != '':
                query += " WHERE " + filter
            result = self._request(query)
            count = LongConverter.to_long(len(result['items'][0])) if result and len(result['items']) == 1 else 0

            return DataPage(items, count)
        else:
            return DataPage(items)
예제 #5
0
    def get_page_by_filter(self,
                           correlation_id: Optional[str],
                           filter: Any,
                           paging: PagingParams,
                           sort: Any = None,
                           select: Any = None) -> DataPage:
        """
        Gets a page of data items retrieved by a given filter and sorted according to sort parameters.

        This method shall be called by a public get_page_by_filter method from child class that
        receives FilterParams and converts them into a filter function.

        :param correlation_id: (optional) transaction id to trace execution through call chain.
        :param filter: (optional) a filter JSON object
        :param paging: (optional) paging parameters
        :param sort: (optional) sorting JSON object
        :param select: (optional) projection JSON object
        :return: a data page of result by filter
        """
        # Adjust max item count based on configuration
        paging = paging if paging is not None else PagingParams()
        skip = paging.get_skip(-1)
        take = paging.get_take(self._max_page_size)
        paging_enabled = paging.total

        # Configure statement
        statement = self._collection.find(filter, projection=select or {})

        if skip >= 0:
            statement = statement.skip(skip)
        statement = statement.limit(take)
        if sort is not None:
            statement = statement.sort(sort)

        # Retrive page items
        items = []
        for item in statement:
            item = self._convert_to_public(item)
            items.append(item)

        if items:
            self._logger.trace(correlation_id, "Retrieved %d from %s",
                               len(items), self._collection_name)

        # Calculate total if needed
        total = None
        if paging_enabled:
            total = self._collection.count_documents(filter)

        return DataPage(items, total)
    def calculate_position(self, correlation_id: Optional[str], site_id: str, udis: List[str]) -> Any:
        beacons: List[BeaconV1] = []
        position = None

        if udis is None or len(udis) == 0:
            return

        page = self.get_beacons(correlation_id,
                                  FilterParams.from_tuples(
                                      'site_id', site_id,
                                      'udis', udis
                                  ), PagingParams())

        beacons = page.data or []

        lat = 0
        lng = 0
        count = 0

        for beacon in beacons:
            if beacon.center is not None and beacon.center['type'] == 'Point' and isinstance(
                    beacon.center['coordinates'], list):
                lng += beacon.center['coordinates'][0]
                lat += beacon.center['coordinates'][1]
                count += 1

        if count > 0:
            position = {
                'type': 'Point',
                'coordinates': [lng / count, lat / count]
            }

        return position or None
    def test_crud_operations(self):
        # Create 3 beacons
        self.test_create_beacons()

        # Get all beacons
        page = self._persistence.get_page_by_filter(None, FilterParams(),
                                                    PagingParams())
        assert page is not None
        assert len(page.data) == 3

        beacon1 = page.data[0]

        # Update the beacon
        beacon1['label'] = "ABC"
        beacon = self._persistence.update(None, beacon1)
        assert beacon is not None
        assert beacon1['id'] == beacon['id']
        assert "ABC" == beacon['label']

        # Get beacon by udi
        beacon = self._persistence.get_one_by_udi(None, beacon1['udi'])
        assert beacon is not None
        assert beacon['id'] == beacon1['id']

        # Delete beacon
        self._persistence.delete_by_id(None, beacon1['id'])

        # Try to get deleted beacon
        beacon = self._persistence.get_one_by_id(None, beacon1['id'])
        assert beacon is None
예제 #8
0
    def get_page_by_filter(self, correlation_id, filter, paging):
        filter = filter if filter is not None else FilterParams()
        key = filter.get_as_nullable_string("key")

        paging = paging if paging is not None else PagingParams()
        skip = paging.get_skip(0)
        take = paging.get_take(100)

        result = []
        self._lock.acquire()
        try:
            for item in self._items:
                if key is not None and key != item['key']:
                    continue

                skip -= 1
                if skip >= 0:
                    continue

                take -= 1
                if take < 0:
                    break

                result.append(item)
        finally:
            self._lock.release()

        return DataPage(result, len(result))
    def get_beacons_by_filter(self, correlation_id, filter, paging, sort=None, select=None):
        items = list(self._items)

        # Filter and sort
        if not (filter is None):
            items = list(filtered(filter, items))
        if not (sort is None):
            items = list(items.sort(key=sort))
            # items = sorted(items, sort)

        # Prepare paging parameters
        paging = paging if not (paging is None) else PagingParams()
        skip = paging.get_skip(-1)
        take = paging.get_take(self._max_page_size)

        # Get a page
        data = items
        if skip > 0:
            data = data[skip:]
        if take > 0:
            data = data[:take + 1]

        # Convert values
        if not (select is None):
            data = map(select, data)

        # Return a page
        return DataPage(data, len(items))
예제 #10
0
    def test_get_skip_and_get_take(self):
        paging = PagingParams(25, 50, False)
        assert 50 == paging.get_skip(50)
        assert 25 == paging.get_skip(10)
        assert 50 == paging.get_take(100)
        assert 25 == paging.get_take(25)

        paging = PagingParams()
        assert 10 == paging.get_skip(10)
        assert 10 == paging.get_skip(10)
    def __get_page_by_filter(self):
        result = self._controller.get_page_by_filter(
            self._get_correlation_id(),
            FilterParams(bottle.request.query.dict),
            PagingParams(bottle.request.query.get('skip'),
                         bottle.request.query.get('take'),
                         bottle.request.query.get('total')),
        )

        return self.send_result(result)
    def get_page_by_filter(self, correlation_id, filter, paging, sort = None, select = None):
        """
        Gets a page of data items retrieved by a given filter and sorted according to sort parameters.

        This method shall be called by a public getPageByFilter method from child class that
        receives FilterParams and converts them into a filter function.

        :param correlation_id: (optional) transaction id to trace execution through call chain.

        :param filter: (optional) a filter function to filter items

        :param paging: (optional) paging parameters

        :param sort: (optional) sorting parameters

        :param select: (optional) projection parameters (not used yet)

        :return: a data page of result by filter.
        """
        self._lock.acquire()
        try:
            items = list(self._items)
        finally:
            self._lock.release()
            
        # Filter and sort
        if filter != None:
            items = list(filtered(filter, items))
        if sort != None:
            items = list(items.sort(key=sort))
            # items = sorted(items, sort)

        # Prepare paging parameters
        paging = paging if paging != None else PagingParams()
        skip = paging.get_skip(-1)
        take = paging.get_take(self._max_page_size)
        
        # Get a page
        data = items
        if skip > 0:
            data = data[skip:]
        if take > 0:
            data = data[:take+1]
                
        # Convert values
        if select != None:
            data = map(select, data)
                
        self._logger.trace(correlation_id, "Retrieved " + str(len(data)) + " items")

        # Return a page
        return DataPage(data, len(items))
예제 #13
0
    def get_accounts(self, correlation_id: Optional[str],
                     filter_params: FilterParams,
                     paging: PagingParams) -> DataPage:
        filter_curl = self.__compose_filter(filter_params)
        accounts = list(filter(filter_curl, self.__accounts))

        # Extract a page
        paging = PagingParams() if paging is None else paging
        skip = paging.get_skip(-1)
        take = paging.get_take(self.__max_page_size)

        total = None
        if paging.total:
            total = len(accounts)

        if skip > 0:
            accounts = accounts[skip:]

        accounts = accounts[:take]

        page = DataPage(accounts, total)

        return page
예제 #14
0
    def test_crud_operations(self):
        # Create the first beacon
        beacon1 = self._controller.create_beacon(None, BEACON1)

        assert beacon1 != None
        assert beacon1['id'] == BEACON1['id']
        assert beacon1['site_id'] == BEACON1['site_id']
        assert beacon1['udi'] == BEACON1['udi']
        assert beacon1['type'] == BEACON1['type']
        assert beacon1['label'] == BEACON1['label']
        assert beacon1['center'] != None

        # Create the second beacon
        beacon2 = self._controller.create_beacon(None, BEACON2)

        assert beacon2 != None
        assert beacon2['id'] == BEACON2['id']
        assert beacon2['site_id'] == BEACON2['site_id']
        assert beacon2['udi'] == BEACON2['udi']
        assert beacon2['type'] == BEACON2['type']
        assert beacon2['label'] == BEACON2['label']
        assert beacon2['center'] != None

        # Get all beacons
        page = self._controller.get_beacons_by_filter(None, FilterParams(),
                                                      PagingParams())
        assert page != None
        assert len(page.data) == 2

        beacon1 = page.data[0]

        # Update the beacon
        beacon1['label'] = "ABC"
        beacon = self._controller.update_beacon(None, beacon1)
        assert beacon != None
        assert beacon1['id'] == beacon['id']
        assert "ABC" == beacon['label']

        # Get beacon by udi
        beacon = self._controller.get_beacon_by_udi(None, beacon1['udi'])
        assert beacon != None
        assert beacon['id'] == beacon1['id']

        # Delete beacon
        self._controller.delete_beacon_by_id(None, beacon1['id'])

        # Try to get deleted beacon
        beacon = self._controller.get_beacon_by_id(None, beacon1['id'])
        assert beacon == None
예제 #15
0
    def test_crud_operations(self):
        # Create the first beacon
        beacon1 = self._controller.create_beacon(None, BEACON1)

        assert beacon1 is not None
        assert beacon1.id == BEACON1.id
        assert beacon1.site_id == BEACON1.site_id
        assert beacon1.udi == BEACON1.udi
        assert beacon1.type == BEACON1.type
        assert beacon1.label == BEACON1.label
        assert beacon1.center is not None

        # Create the second beacon
        beacon2 = self._controller.create_beacon(None, BEACON2)

        assert beacon2 != None
        assert beacon2.id == BEACON2.id
        assert beacon2.site_id == BEACON2.site_id
        assert beacon2.udi == BEACON2.udi
        assert beacon2.type == BEACON2.type
        assert beacon2.label == BEACON2.label
        assert beacon2.center is not None

        # Get all beacons
        page = self._controller.get_beacons_by_filter(None, FilterParams(),
                                                      PagingParams())
        assert page is not None
        assert len(page.data) == 2

        beacon1 = page.data[0]

        # Update the beacon
        beacon1.label = "ABC"
        beacon = self._controller.update_beacon(None, beacon1)
        assert beacon is not None
        assert beacon1.id == beacon.id
        assert "ABC" == beacon.label

        # Get beacon by udi
        beacon = self._controller.get_beacon_by_udi(None, beacon1.udi)
        assert beacon is not None
        assert beacon.id == beacon1.id

        # Delete beacon
        self._controller.delete_beacon_by_id(None, beacon1.id)

        # Try to get deleted beacon
        beacon = self._controller.get_beacon_by_id(None, beacon1.id)
        assert beacon is None
    def get_beacons(self, correlation_id, filter, paging):
        filter_beacons = self.compose_filter(filter)
        beacons = [item for item in self._items if filter_beacons(item) is True]

        # Extract a page
        paging = paging if paging is not None else PagingParams()
        skip = paging.get_skip(-1)
        take = paging.get_take(self._max_page_size)
        total = None
        if paging.total:
            total = len(beacons)
        if skip > 0:
            beacons = beacons[skip:]
            beacons = beacons[:take]

        page = DataPage(beacons, total)
        return page
예제 #17
0
    def test_crud_operations(self):
        # Create one dummy
        dummy1 = self._client.create(None, DUMMY1)

        assert dummy1 is not None
        assert dummy1.id is not None
        assert DUMMY1.key == dummy1.key
        assert DUMMY1.content == dummy1.content

        # Create another dummy
        dummy2 = self._client.create(None, DUMMY2)

        assert dummy2 is not None
        assert dummy2.id is not None
        assert DUMMY2.key == dummy2.key
        assert DUMMY2.content == dummy2.content

        # Get all dummies
        dummies = self._client.get_page_by_filter(None, FilterParams(),
                                                  PagingParams(0, 5, False))
        assert dummies is not None
        assert len(dummies.data) >= 2

        # Update the dummy
        dummy1.content = "Updated Content 1"
        dummy = self._client.update(None, dummy1)

        assert dummy is not None
        assert dummy1.id == dummy.id
        assert dummy1.key == dummy.key
        assert "Updated Content 1" == dummy.content

        # Delete the dummy
        self._client.delete_by_id(None, dummy1.id)

        # Try to get deleted dummy
        dummy = self._client.get_one_by_id(None, dummy1.id)
        assert dummy is None

        # Check correlation id
        result = self._client.check_correlation_id('test_cor_id')
        assert result is not None
        assert 'test_cor_id' == result
예제 #18
0
 def test_create_empty_PagingParams_gRPC(self):
     paging = PagingParams(0, 0, False)
     assert 0 == paging.skip
     assert paging.take is None
     assert paging.total is False
예제 #19
0
 def test_create_PagingParams_with_set_skip_take_values(self):
     paging = PagingParams(25, 50, False)
     assert 25 == paging.skip
     assert 50 == paging.take
     assert paging.total is False
예제 #20
0
 def test_create_empty_PagingParams_regular(self):
     paging = PagingParams()
     assert paging.skip is None
     assert paging.take is None
     assert paging.total is False
예제 #21
0
 def handler(correlation_id, args):
     filter = FilterParams.from_value(args.get("filter"))
     paging = PagingParams.from_value(args.get("paging"))
     return self._controller.get_beacons_by_filter(
         correlation_id, filter, paging)
 def handler(correlation_id: Optional[str], args: Parameters):
     filter = FilterParams.from_value(args.get("filter"))
     paging = PagingParams.from_value(args.get("paging"))
     page = self._controller.get_page_by_filter(correlation_id, filter,
                                                paging)
     return page