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))
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)
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
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))
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))
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
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
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
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
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
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
def test_create_empty_PagingParams_regular(self): paging = PagingParams() assert paging.skip is None assert paging.take is None assert paging.total is False
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