moonstream/engineapi/engineapi/models.py

288 wiersze
8.5 KiB
Python

import uuid
from sqlalchemy import (
VARCHAR,
BigInteger,
Boolean,
Column,
DateTime,
ForeignKey,
Index,
MetaData,
String,
UniqueConstraint,
)
from sqlalchemy.dialects.postgresql import JSONB, UUID
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.sql import and_, expression
"""
Naming conventions doc
https://docs.sqlalchemy.org/en/13/core/constraints.html#configuring-constraint-naming-conventions
"""
convention = {
"ix": "ix_%(column_0_label)s",
"uq": "uq_%(table_name)s_%(column_0_name)s",
"ck": "ck_%(table_name)s_%(constraint_name)s",
"fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
"pk": "pk_%(table_name)s",
}
metadata = MetaData(naming_convention=convention)
Base = declarative_base(metadata=metadata)
"""
Creating a utcnow function which runs on the Posgres database server when created_at and updated_at
fields are populated.
Following:
1. https://docs.sqlalchemy.org/en/13/core/compiler.html#utc-timestamp-function
2. https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-CURRENT
3. https://stackoverflow.com/a/33532154/13659585
"""
class utcnow(expression.FunctionElement):
type = DateTime
@compiles(utcnow, "postgresql")
def pg_utcnow(element, compiler, **kwargs):
return "TIMEZONE('utc', statement_timestamp())"
class DropperContract(Base): # type: ignore
__tablename__ = "dropper_contracts"
__table_args__ = (UniqueConstraint("blockchain", "address"),)
id = Column(
UUID(as_uuid=True),
primary_key=True,
default=uuid.uuid4,
unique=True,
nullable=False,
)
blockchain = Column(VARCHAR(128), nullable=False)
address = Column(VARCHAR(256), index=True)
title = Column(VARCHAR(128), nullable=True)
description = Column(String, nullable=True)
image_uri = Column(String, nullable=True)
created_at = Column(
DateTime(timezone=True), server_default=utcnow(), nullable=False
)
updated_at = Column(
DateTime(timezone=True),
server_default=utcnow(),
onupdate=utcnow(),
nullable=False,
)
class DropperClaim(Base): # type: ignore
__tablename__ = "dropper_claims"
id = Column(
UUID(as_uuid=True),
primary_key=True,
default=uuid.uuid4,
unique=True,
nullable=False,
)
dropper_contract_id = Column(
UUID(as_uuid=True),
ForeignKey("dropper_contracts.id", ondelete="CASCADE"),
nullable=False,
)
claim_id = Column(BigInteger, nullable=True)
title = Column(VARCHAR(128), nullable=True)
description = Column(String, nullable=True)
terminus_address = Column(VARCHAR(256), nullable=True, index=True)
terminus_pool_id = Column(BigInteger, nullable=True, index=True)
claim_block_deadline = Column(BigInteger, nullable=True)
active = Column(Boolean, default=False, nullable=False)
created_at = Column(
DateTime(timezone=True), server_default=utcnow(), nullable=False
)
updated_at = Column(
DateTime(timezone=True),
server_default=utcnow(),
onupdate=utcnow(),
nullable=False,
)
__table_args__ = (
Index(
"uq_dropper_claims_dropper_contract_id_claim_id",
"dropper_contract_id",
"claim_id",
unique=True,
postgresql_where=and_(claim_id.isnot(None), active.is_(True)),
),
)
class DropperClaimant(Base): # type: ignore
__tablename__ = "dropper_claimants"
__table_args__ = (UniqueConstraint("dropper_claim_id", "address"),)
id = Column(
UUID(as_uuid=True),
primary_key=True,
default=uuid.uuid4,
unique=True,
nullable=False,
)
dropper_claim_id = Column(
UUID(as_uuid=True),
ForeignKey("dropper_claims.id", ondelete="CASCADE"),
nullable=False,
)
address = Column(VARCHAR(256), nullable=False, index=True)
amount = Column(BigInteger, nullable=False)
raw_amount = Column(String, nullable=True)
added_by = Column(VARCHAR(256), nullable=False, index=True)
signature = Column(String, nullable=True, index=True)
created_at = Column(
DateTime(timezone=True), server_default=utcnow(), nullable=False
)
updated_at = Column(
DateTime(timezone=True),
server_default=utcnow(),
onupdate=utcnow(),
nullable=False,
)
class RegisteredContract(Base): # type: ignore
__tablename__ = "registered_contracts"
__table_args__ = (
UniqueConstraint(
"blockchain",
"moonstream_user_id",
"address",
"contract_type",
),
)
id = Column(
UUID(as_uuid=True),
primary_key=True,
default=uuid.uuid4,
unique=True,
)
blockchain = Column(VARCHAR(128), nullable=False, index=True)
address = Column(VARCHAR(256), nullable=False, index=True)
contract_type = Column(VARCHAR(128), nullable=False, index=True)
title = Column(VARCHAR(128), nullable=False)
description = Column(String, nullable=True)
image_uri = Column(String, nullable=True)
# User ID of the Moonstream user who registered this contract.
moonstream_user_id = Column(UUID(as_uuid=True), nullable=False, index=True)
created_at = Column(
DateTime(timezone=True), server_default=utcnow(), nullable=False
)
updated_at = Column(
DateTime(timezone=True),
server_default=utcnow(),
onupdate=utcnow(),
nullable=False,
)
class CallRequest(Base):
__tablename__ = "call_requests"
id = Column(
UUID(as_uuid=True),
primary_key=True,
default=uuid.uuid4,
unique=True,
nullable=False,
)
registered_contract_id = Column(
UUID(as_uuid=True),
ForeignKey("registered_contracts.id", ondelete="CASCADE"),
nullable=False,
)
caller = Column(VARCHAR(256), nullable=False, index=True)
# User ID of the Moonstream user who requested this call.
# For now, this duplicates the moonstream_user_id in the registered_contracts table. Nevertheless,
# we keep this column here for auditing purposes. In the future, we will add a group_id column to
# the registered_contracts table, and this column will be used to track the user from that group
# who made each call request.
moonstream_user_id = Column(UUID(as_uuid=True), nullable=False, index=True)
method = Column(String, nullable=False, index=True)
# TODO(zomglings): Should we conditional indices on parameters depending on the contract type?
parameters = Column(JSONB, nullable=False)
expires_at = Column(DateTime(timezone=True), nullable=True, index=True)
created_at = Column(
DateTime(timezone=True), server_default=utcnow(), nullable=False
)
updated_at = Column(
DateTime(timezone=True),
server_default=utcnow(),
onupdate=utcnow(),
nullable=False,
)
class Leaderboard(Base): # type: ignore
__tablename__ = "leaderboards"
# __table_args__ = (UniqueConstraint("dropper_contract_id", "address"),)
id = Column(
UUID(as_uuid=True),
primary_key=True,
default=uuid.uuid4,
unique=True,
nullable=False,
)
title = Column(VARCHAR(128), nullable=False)
description = Column(String, nullable=True)
resource_id = Column(UUID(as_uuid=True), nullable=True, index=True)
created_at = Column(
DateTime(timezone=True), server_default=utcnow(), nullable=False
)
updated_at = Column(
DateTime(timezone=True),
server_default=utcnow(),
onupdate=utcnow(),
nullable=False,
)
class LeaderboardScores(Base): # type: ignore
__tablename__ = "leaderboard_scores"
__table_args__ = (UniqueConstraint("leaderboard_id", "address"),)
id = Column(
UUID(as_uuid=True),
primary_key=True,
default=uuid.uuid4,
unique=True,
nullable=False,
)
leaderboard_id = Column(
UUID(as_uuid=True),
ForeignKey("leaderboards.id", ondelete="CASCADE"),
nullable=False,
)
address = Column(VARCHAR(256), nullable=False, index=True)
score = Column(BigInteger, nullable=False)
points_data = Column(JSONB, nullable=True)
created_at = Column(
DateTime(timezone=True), server_default=utcnow(), nullable=False
)
updated_at = Column(
DateTime(timezone=True),
server_default=utcnow(),
onupdate=utcnow(),
nullable=False,
)