From caa2fc54fc360e16fb1a91e3b3852827a6a8ba03 Mon Sep 17 00:00:00 2001 From: Lorenz Herzberger Date: Wed, 16 Nov 2022 11:08:56 +0100 Subject: [PATCH] adjusted input dataclass, added queries, removed convert Signed-off-by: Lorenz Herzberger --- planetmint/backend/__init__.py | 2 +- planetmint/backend/convert.py | 26 ----------- planetmint/backend/interfaces.py | 16 ++++--- planetmint/backend/localmongodb/__init__.py | 2 +- planetmint/backend/localmongodb/convert.py | 24 ---------- planetmint/backend/query.py | 15 +++++-- planetmint/backend/tarantool/__init__.py | 2 +- planetmint/backend/tarantool/convert.py | 25 ----------- planetmint/backend/tarantool/query.py | 49 ++++++++++++++++----- planetmint/lib.py | 15 +++---- 10 files changed, 70 insertions(+), 106 deletions(-) delete mode 100644 planetmint/backend/convert.py delete mode 100644 planetmint/backend/localmongodb/convert.py delete mode 100644 planetmint/backend/tarantool/convert.py diff --git a/planetmint/backend/__init__.py b/planetmint/backend/__init__.py index 4f3e4fd..4f55715 100644 --- a/planetmint/backend/__init__.py +++ b/planetmint/backend/__init__.py @@ -12,5 +12,5 @@ configuration or the ``PLANETMINT_DATABASE_BACKEND`` environment variable. """ # Include the backend interfaces -from planetmint.backend import schema, query, convert # noqa +from planetmint.backend import schema, query # noqa from planetmint.backend.connection import Connection diff --git a/planetmint/backend/convert.py b/planetmint/backend/convert.py deleted file mode 100644 index 6ec074f..0000000 --- a/planetmint/backend/convert.py +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright © 2020 Interplanetary Database Association e.V., -# Planetmint and IPDB software contributors. -# SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0) -# Code is Apache-2.0 and docs are CC-BY-4.0 - -"""Convert interfaces for backends.""" - -from functools import singledispatch - - -@singledispatch -def prepare_asset(connection, transaction_type, transaction_id, filter_operation, asset): - """ - This function is used for preparing assets, - before storing them to database. - """ - raise NotImplementedError - - -@singledispatch -def prepare_metadata(connection, transaction_id, metadata): - """ - This function is used for preparing metadata, - before storing them to database. - """ - raise NotImplementedError diff --git a/planetmint/backend/interfaces.py b/planetmint/backend/interfaces.py index c20f2f0..ddf7f0a 100644 --- a/planetmint/backend/interfaces.py +++ b/planetmint/backend/interfaces.py @@ -4,6 +4,7 @@ # Code is Apache-2.0 and docs are CC-BY-4.0 from dataclasses import dataclass +from typing import Union # Asset should represent a single asset (e.g.: tarantool tuple (data, tx_id, asset_id)) # If multiple assets are stored at once this should remain the same. @@ -11,18 +12,21 @@ from dataclasses import dataclass @dataclass class Asset: - id: str = None - tx_id: str = None - data: dict = None + id: str = "" + tx_id: str = "" + data: str = "" @dataclass class MetaData: - id: str = None - metadata: str = None + id: str = "" + metadata: str = "" @dataclass class Input: - id: str = None + tx_id: str = "" + fulfills: Union[dict, None] = None + owners_before: list[str] = None + fulfillment: str = "" @dataclass class Output: diff --git a/planetmint/backend/localmongodb/__init__.py b/planetmint/backend/localmongodb/__init__.py index 97b45cd..ebbe6e9 100644 --- a/planetmint/backend/localmongodb/__init__.py +++ b/planetmint/backend/localmongodb/__init__.py @@ -22,7 +22,7 @@ generic backend interfaces to the implementations in this module. """ # Register the single dispatched modules on import. -from planetmint.backend.localmongodb import schema, query, convert # noqa +from planetmint.backend.localmongodb import schema, query # noqa # MongoDBConnection should always be accessed via # ``planetmint.backend.connect()``. diff --git a/planetmint/backend/localmongodb/convert.py b/planetmint/backend/localmongodb/convert.py deleted file mode 100644 index d8121fb..0000000 --- a/planetmint/backend/localmongodb/convert.py +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright © 2020 Interplanetary Database Association e.V., -# Planetmint and IPDB software contributors. -# SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0) -# Code is Apache-2.0 and docs are CC-BY-4.0 - -"""Convert implementation for MongoDb""" - -from planetmint.backend.utils import module_dispatch_registrar -from planetmint.backend import convert -from planetmint.backend.localmongodb.connection import LocalMongoDBConnection - -register_query = module_dispatch_registrar(convert) - - -@register_query(LocalMongoDBConnection) -def prepare_asset(connection, transaction_type, transaction_id, filter_operation, asset): - if transaction_type not in filter_operation: - asset["id"] = transaction_id - return asset - - -@register_query(LocalMongoDBConnection) -def prepare_metadata(connection, transaction_id, metadata): - return {"id": transaction_id, "metadata": metadata} diff --git a/planetmint/backend/query.py b/planetmint/backend/query.py index b36b787..d1412d7 100644 --- a/planetmint/backend/query.py +++ b/planetmint/backend/query.py @@ -7,7 +7,7 @@ from functools import singledispatch from planetmint.backend.exceptions import OperationError -from planetmint.backend.interfaces import Asset, MetaData +from planetmint.backend.interfaces import Asset, Block, MetaData, Input @singledispatch def store_asset(connection, asset: dict) -> Asset: @@ -148,7 +148,7 @@ def get_owned_ids(connection, owner): @singledispatch -def get_block(connection, block_id): +def get_block(connection, block_id) -> Block: """Get a block from the planet table. Args: @@ -176,7 +176,7 @@ def get_block_with_transaction(connection, txid): @singledispatch -def get_metadata(connection, transaction_ids): +def get_metadata(connection, transaction_ids) -> list[MetaData]: """Get a list of metadata from the metadata table. Args: @@ -435,6 +435,15 @@ def get_latest_abci_chain(conn): """ raise NotImplementedError +@singledispatch +def get_inputs_by_tx_id(connection, tx_id) -> list[Input]: + """Retrieve inputs for a transaction by its id""" + raise NotImplementedError + +@singledispatch +def store_transaction_inputs(connection, inputs: list[Input]): + """Store inputs for a transaction""" + raise NotImplementedError @singledispatch def _group_transaction_by_ids(txids: list, connection): diff --git a/planetmint/backend/tarantool/__init__.py b/planetmint/backend/tarantool/__init__.py index 1e667c0..63392db 100644 --- a/planetmint/backend/tarantool/__init__.py +++ b/planetmint/backend/tarantool/__init__.py @@ -1,5 +1,5 @@ # Register the single dispatched modules on import. -from planetmint.backend.tarantool import query, connection, schema, convert # noqa +from planetmint.backend.tarantool import query, connection, schema # noqa # MongoDBConnection should always be accessed via # ``planetmint.backend.connect()``. diff --git a/planetmint/backend/tarantool/convert.py b/planetmint/backend/tarantool/convert.py deleted file mode 100644 index 571ef3f..0000000 --- a/planetmint/backend/tarantool/convert.py +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright © 2020 Interplanetary Database Association e.V., -# Planetmint and IPDB software contributors. -# SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0) -# Code is Apache-2.0 and docs are CC-BY-4.0 - -"""Convert implementation for Tarantool""" - -from planetmint.backend.utils import module_dispatch_registrar -from planetmint.backend import convert -from planetmint.backend.tarantool.connection import TarantoolDBConnection - -register_query = module_dispatch_registrar(convert) - - -@register_query(TarantoolDBConnection) -def prepare_asset(connection, transaction_type, transaction_id, filter_operation, assets): - asset_id = transaction_id - if transaction_type not in filter_operation: - asset_id = assets[0]["id"] - return tuple([assets, transaction_id, asset_id]) - - -@register_query(TarantoolDBConnection) -def prepare_metadata(connection, transaction_id, metadata): - return {"id": transaction_id, "metadata": metadata} diff --git a/planetmint/backend/tarantool/query.py b/planetmint/backend/tarantool/query.py index 1d0f054..5a230a8 100644 --- a/planetmint/backend/tarantool/query.py +++ b/planetmint/backend/tarantool/query.py @@ -12,7 +12,7 @@ from operator import itemgetter from tarantool.error import DatabaseError from planetmint.backend import query from planetmint.backend.utils import module_dispatch_registrar -from planetmint.backend.interfaces import Asset, MetaData +from planetmint.backend.interfaces import Asset, MetaData, Input from planetmint.backend.tarantool.connection import TarantoolDBConnection from planetmint.backend.tarantool.transaction.tools import TransactionCompose, TransactionDecompose @@ -50,6 +50,40 @@ def _group_transaction_by_ids(connection, txids: list): _transactions.append(_transaction) return _transactions +@register_query(TarantoolDBConnection) +def get_inputs_by_tx_id(connection, tx_id: str) -> list[Input]: + _inputs = connection.run(connection.space("inputs").select(tx_id, index="id_search")) + _sorted_inputs = sorted(_inputs, key=itemgetter(6)) + + inputs = [] + + for input in _sorted_inputs: + tx_id = input[0] + fulfillment = input[1] + owners_before = input[2] + fulfills = None + fulfills_tx_id = input[3] + + if fulfills_tx_id: + fulfills = { + "transaction_id": fulfills_tx_id, + "output_index": int(input[4]) + } + + inputs.append(Input(tx_id, fulfills, owners_before, fulfillment)) + + return inputs + +@register_query(TarantoolDBConnection) +def store_transaction_inputs(connection, inputs: list[Input]): + for index, input in enumerate(inputs): + connection.run(connection.space("inputs").insert(( + input.tx_id, + input.fulfillment, + input.fulfills["transaction_id"] if input.fulfills else "", + input.fulfills["output_index"] if input.fulfills else "", + index + ))) @register_query(TarantoolDBConnection) def store_transactions(connection, signed_transactions: list): @@ -101,7 +135,7 @@ def store_metadatas(connection, metadata: list[MetaData]): @register_query(TarantoolDBConnection) -def get_metadata(connection, transaction_ids: list): +def get_metadata(connection, transaction_ids: list) -> list[MetaData]: _returned_data = [] for _id in transaction_ids: metadata = connection.run(connection.space("meta_data").select(_id, index="id_search")) @@ -109,16 +143,16 @@ def get_metadata(connection, transaction_ids: list): if len(metadata) > 0: metadata[0] = list(metadata[0]) metadata[0][1] = json.loads(metadata[0][1]) - metadata[0] = tuple(metadata[0]) + metadata = MetaData(metadata[0][0], metadata[0][1]) _returned_data.append(metadata) return _returned_data @register_query(TarantoolDBConnection) def store_asset(connection, asset: Asset): - asset = (json.dumps(asset.data), asset.tx_id, asset.id) + tuple_asset = (json.dumps(asset.data), asset.tx_id, asset.id) try: - return connection.run(connection.space("assets").insert(asset), only_data=False) + return connection.run(connection.space("assets").insert(tuple_asset), only_data=False) except DatabaseError: pass @@ -238,11 +272,6 @@ def text_search(conn, search, table="assets", limit=0): return to_return if limit == 0 else to_return[:limit] -def _remove_text_score(asset): - asset.pop("score", None) - return asset - - @register_query(TarantoolDBConnection) def get_owned_ids(connection, owner: str): _keys = connection.run(connection.space("keys").select(owner, index="keys_search")) diff --git a/planetmint/lib.py b/planetmint/lib.py index 10271db..bd72a1a 100644 --- a/planetmint/lib.py +++ b/planetmint/lib.py @@ -483,7 +483,7 @@ class Planetmint(object): """ return backend.query.get_assets(self.connection, asset_ids) - def get_metadata(self, txn_ids): + def get_metadata(self, txn_ids) -> list[MetaData]: """Return a list of metadata that match the transaction ids (txn_ids) Args: @@ -595,16 +595,13 @@ class Planetmint(object): # TODO: this will break if more than one asset is used assets = self.get_assets(tx_ids) for asset in assets: - if asset is not None: - tx = tx_map[asset.id] - tx["assets"] = [asset.data] + tx = tx_map[asset.id] + tx["assets"] = [asset.data] - tx_ids = list(tx_map.keys()) - metadata_list = list(self.get_metadata(tx_ids)) + metadata_list = self.get_metadata(tx_ids) for metadata in metadata_list: - if "id" in metadata: - tx = tx_map[metadata["id"]] - tx.update({"metadata": metadata.get("metadata")}) + tx = tx_map[metadata.id] + tx["metadata"] = metadata.metadata if return_list: tx_list = []