示例#1
0
    def _parse_asset_data(self, insert_text: str) -> ParsedAssetData:
        match = self.assets_re.match(insert_text)
        if match is None:
            raise DeserializationError(
                f'At asset DB update could not parse asset data out of {insert_text}',
            )
        if len(match.groups()) != 9:
            raise DeserializationError(
                f'At asset DB update could not parse asset data out of {insert_text}',
            )

        raw_type = self._parse_str(match.group(2), 'asset type', insert_text)
        asset_type = AssetType.deserialize_from_db(raw_type)
        raw_started = self._parse_optional_int(match.group(5), 'started', insert_text)
        started = Timestamp(raw_started) if raw_started else None
        return ParsedAssetData(
            identifier=self._parse_str(match.group(1), 'identifier', insert_text),
            asset_type=asset_type,
            name=self._parse_str(match.group(3), 'name', insert_text),
            symbol=self._parse_str(match.group(4), 'symbol', insert_text),
            started=started,
            swapped_for=self._parse_optional_str(match.group(6), 'swapped_for', insert_text),
            coingecko=self._parse_optional_str(match.group(7), 'coingecko', insert_text),
            cryptocompare=self._parse_optional_str(match.group(8), 'cryptocompare', insert_text),
        )
示例#2
0
文件: handler.py 项目: step21/rotki
    def get_all_asset_data(
            mapping: bool
    ) -> Union[List[AssetData], Dict[str, Dict[str, Any]]]:
        """Return all asset data from the DB

        TODO: This can be improved. Too many sql queries.

        If mapping is True, return them as a Dict of identifier to data
        If mapping is False, return them as a List of AssetData
        """
        result: Union[List[AssetData], Dict[str, Dict[str, Any]]]
        if mapping:
            result = {}
        else:
            result = []
        cursor = GlobalDBHandler()._conn.cursor()
        querystr = """
        SELECT A.identifier, A.type, B.address, B.decimals, A.name, A.symbol, A.started, null, A.swapped_for, A.coingecko, A.cryptocompare, B.protocol from assets as A LEFT OUTER JOIN ethereum_tokens as B
        ON B.address = A.details_reference WHERE A.type=?
        UNION ALL
        SELECT A.identifier, A.type, null, null, A.name, A.symbol, A.started, B.forked, A.swapped_for, A.coingecko, A.cryptocompare, null from assets as A LEFT OUTER JOIN common_asset_details as B
        ON B.asset_id = A.identifier WHERE A.type!=?;
        """  # noqa: E501
        eth_token_type = AssetType.ETHEREUM_TOKEN.serialize_for_db()  # pylint: disable=no-member
        query = cursor.execute(querystr, (eth_token_type, eth_token_type))
        for entry in query:
            asset_type = AssetType.deserialize_from_db(entry[1])
            ethereum_address: Optional[ChecksumEthAddress]
            if asset_type == AssetType.ETHEREUM_TOKEN:
                ethereum_address = string_to_ethereum_address(entry[2])
            else:
                ethereum_address = None
            data = AssetData(
                identifier=entry[0],
                asset_type=asset_type,
                ethereum_address=ethereum_address,
                decimals=entry[3],
                name=entry[4],
                symbol=entry[5],
                started=entry[6],
                forked=entry[7],
                swapped_for=entry[8],
                coingecko=entry[9],
                cryptocompare=entry[10],
                protocol=entry[11],
            )
            if mapping:
                result[entry[0]] = data.serialize()  # type: ignore
            else:
                result.append(data)  # type: ignore

        return result
示例#3
0
文件: handler.py 项目: step21/rotki
    def get_assets_with_symbol(
        symbol: str,
        asset_type: Optional[AssetType] = None
    ) -> List[AssetData]:  # noqa: E501
        """Find all asset entries that have the given symbol"""
        connection = GlobalDBHandler()._conn
        cursor = connection.cursor()
        query_tuples: Union[Tuple[str, str, str, str], Tuple[str, str, str,
                                                             str, str]]
        eth_token_type = AssetType.ETHEREUM_TOKEN.serialize_for_db()  # pylint: disable=no-member
        if asset_type is not None:
            asset_type_check = ' AND A.type=?'
            query_tuples = (symbol, eth_token_type, symbol, eth_token_type,
                            asset_type.serialize_for_db())  # noqa: E501
        else:
            asset_type_check = ''
            query_tuples = (symbol, eth_token_type, symbol, eth_token_type)
        querystr = f"""
        SELECT A.identifier, A.type, B.address, B.decimals, A.name, A.symbol, A.started, null, A.swapped_for, A.coingecko, A.cryptocompare, B.protocol from assets as A LEFT OUTER JOIN ethereum_tokens as B
        ON B.address = A.details_reference WHERE A.symbol=? COLLATE NOCASE AND A.type=?
        UNION ALL
        SELECT A.identifier, A.type, null, null, A.name, A.symbol, A.started, B.forked, A.swapped_for, A.coingecko, A.cryptocompare, null from assets as A LEFT OUTER JOIN common_asset_details as B
        ON B.asset_id = A.identifier WHERE A.symbol=? COLLATE NOCASE AND A.type!=?{asset_type_check};
        """  # noqa: E501
        query = cursor.execute(querystr, query_tuples)
        assets = []
        for entry in query:
            asset_type = AssetType.deserialize_from_db(entry[1])
            ethereum_address: Optional[ChecksumEthAddress]
            if asset_type == AssetType.ETHEREUM_TOKEN:
                ethereum_address = string_to_ethereum_address(entry[2])
            else:
                ethereum_address = None
            assets.append(
                AssetData(
                    identifier=entry[0],
                    asset_type=asset_type,
                    ethereum_address=ethereum_address,
                    decimals=entry[3],
                    name=entry[4],
                    symbol=entry[5],
                    started=entry[6],
                    forked=entry[7],
                    swapped_for=entry[8],
                    coingecko=entry[9],
                    cryptocompare=entry[10],
                    protocol=entry[11],
                ))

        return assets
示例#4
0
文件: handler.py 项目: step21/rotki
    def get_asset_data(
        identifier: str,
        form_with_incomplete_data: bool,
    ) -> Optional[AssetData]:
        """Get all details of a single asset by identifier

        Returns None if identifier can't be matched to an asset
        """
        cursor = GlobalDBHandler()._conn.cursor()
        query = cursor.execute(
            'SELECT identifier, type, name, symbol, started, swapped_for, coingecko, '
            'cryptocompare, details_reference from assets WHERE identifier=?;',
            (identifier, ),
        )
        result = query.fetchone()
        if result is None:
            return None

        # Since comparison is case insensitive let's return original identifier
        saved_identifier = result[0]  # get the identifier as saved in the DB.
        db_serialized_type = result[1]
        name = result[2]
        symbol = result[3]
        started = result[4]
        swapped_for = result[5]
        coingecko = result[6]
        cryptocompare = result[7]
        details_reference = result[8]
        forked = None
        decimals = None
        protocol = None
        ethereum_address = None

        try:
            asset_type = AssetType.deserialize_from_db(db_serialized_type)
        except DeserializationError as e:
            log.debug(
                f'Failed to read asset {identifier} from the DB due to '
                f'{str(e)}. Skipping', )
            return None

        if asset_type == AssetType.ETHEREUM_TOKEN:
            ethereum_address = details_reference
            cursor.execute(
                'SELECT decimals, protocol from ethereum_tokens '
                'WHERE address=?',
                (ethereum_address, ),
            )
            result = query.fetchone()
            if result is None:
                log.error(
                    f'Found token {saved_identifier} in the DB assets table but not '
                    f'in the token details table.', )
                return None

            decimals = result[0]
            protocol = result[1]
            missing_basic_data = name is None or symbol is None or decimals is None
            if missing_basic_data and form_with_incomplete_data is False:
                log.debug(
                    f'Considering ethereum token with address {details_reference} '
                    f'as unknown since its missing either decimals or name or symbol',
                )
                return None
        else:
            cursor = GlobalDBHandler()._conn.cursor()
            query = cursor.execute(
                'SELECT forked FROM common_asset_details WHERE asset_id = ?;',
                (details_reference, ),
            )
            result = query.fetchone()
            if result is None:
                log.error(
                    f'Found asset {saved_identifier} in the DB assets table but not '
                    f'in the common asset details table.', )
                return None
            forked = result[0]

        return AssetData(
            identifier=saved_identifier,
            name=name,
            symbol=symbol,
            asset_type=asset_type,
            started=started,
            forked=forked,
            swapped_for=swapped_for,
            ethereum_address=ethereum_address,
            decimals=decimals,
            coingecko=coingecko,
            cryptocompare=cryptocompare,
            protocol=protocol,
        )