Lorenz Herzberger 11cf86464f
Add utxo migration (#379)
* added migration script for utxo space
* added migration commands
* changelog and version bump
* added db call to command

Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com>
2023-04-14 11:34:36 +02:00

207 lines
4.7 KiB
Python

# 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
"""Database creation and schema-providing interfaces for backends."""
import logging
from functools import singledispatch
from planetmint.config import Config
from transactions.common.exceptions import ValidationError
from transactions.common.utils import (
validate_all_values_for_key_in_obj,
validate_all_values_for_key_in_list,
)
logger = logging.getLogger(__name__)
# Tables/collections that every backend database must create
TABLES = (
"transactions",
"blocks",
"assets",
"metadata",
"validators",
"elections",
"pre_commit",
"utxos",
"abci_chains",
)
SPACE_NAMES = (
"abci_chains",
"assets",
"blocks",
"blocks_tx",
"elections",
"meta_data",
"pre_commits",
"validators",
"transactions",
"inputs",
"outputs",
"keys",
"utxos",
)
VALID_LANGUAGES = (
"danish",
"dutch",
"english",
"finnish",
"french",
"german",
"hungarian",
"italian",
"norwegian",
"portuguese",
"romanian",
"russian",
"spanish",
"swedish",
"turkish",
"none",
"da",
"nl",
"en",
"fi",
"fr",
"de",
"hu",
"it",
"nb",
"pt",
"ro",
"ru",
"es",
"sv",
"tr",
)
@singledispatch
def create_database(connection, dbname):
"""Create database to be used by Planetmint.
Args:
dbname (str): the name of the database to create.
"""
raise NotImplementedError
@singledispatch
def create_tables(connection, dbname):
"""Create the tables to be used by Planetmint.
Args:
dbname (str): the name of the database to create tables for.
"""
raise NotImplementedError
@singledispatch
def drop_database(connection, dbname):
"""Drop the database used by Planetmint.
Args:
dbname (str): the name of the database to drop.
Raises:
:exc:`~DatabaseDoesNotExist`: If the given :attr:`dbname` does not
exist as a database.
"""
raise NotImplementedError
@singledispatch
def init_database(connection, dbname):
"""Initialize the configured backend for use with Planetmint.
Creates a database with :attr:`dbname` with any required tables
and supporting indexes.
Args:
connection (:class:`~planetmint.backend.connection.Connection`): an
existing connection to use to initialize the database.
Creates one if not given.
dbname (str): the name of the database to create.
Defaults to the database name given in the Planetmint
configuration.
"""
raise NotImplementedError
@singledispatch
def migrate_up(connection):
"""Migrate database up
Args:
connection (:class:`~planetmint.backend.connection.Connection`): an
existing connection to use to migrate the database.
Creates one if not given.
"""
raise NotImplementedError
@singledispatch
def migrate_down(connection):
"""Migrate database down
Args:
connection (:class:`~planetmint.backend.connection.Connection`): an
existing connection to use to migrate the database.
Creates one if not given.
"""
raise NotImplementedError
def validate_language_key(obj, key):
"""Validate all nested "language" key in `obj`.
Args:
obj (dict): dictionary whose "language" key is to be validated.
Returns:
None: validation successful
Raises:
ValidationError: will raise exception in case language is not valid.
"""
backend = Config().get()["database"]["backend"]
if backend == "localmongodb":
data = obj.get(key, {})
if isinstance(data, dict):
validate_all_values_for_key_in_obj(data, "language", validate_language)
elif isinstance(data, list):
validate_all_values_for_key_in_list(data, "language", validate_language)
def validate_language(value):
"""Check if `value` is a valid language.
https://docs.mongodb.com/manual/reference/text-search-languages/
Args:
value (str): language to validated
Returns:
None: validation successful
Raises:
ValidationError: will raise exception in case language is not valid.
"""
if value not in VALID_LANGUAGES:
error_str = (
"MongoDB does not support text search for the "
'language "{}". If you do not understand this error '
'message then please rename key/field "language" to '
'something else like "lang".'
).format(value)
raise ValidationError(error_str)