Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
moisses89 committed Dec 11, 2024
1 parent d388110 commit b825684
Show file tree
Hide file tree
Showing 8 changed files with 168 additions and 45 deletions.
34 changes: 31 additions & 3 deletions app/datasources/db/models.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,37 @@
from typing import Optional
from sqlmodel import JSON, Column, Field, SQLModel, UniqueConstraint

from sqlmodel import Field, SQLModel

class AbiSource(SQLModel, table=True):
id: int | None = Field(default=None, primary_key=True)
name: str = Field(nullable=False)
url: str = Field(nullable=False)


class Abi(SQLModel, table=True):
abi_hash: bytes = Field(nullable=False, primary_key=True)
relevance: int = Field(nullable=False, default=0)
abi_json: dict = Field(default_factory=dict, sa_column=Column(JSON))
source_id: int = Field(default=None, foreign_key="abisource.id")


class Chain(SQLModel, table=True):
id: int = Field(primary_key=True) # Chain ID
name: str = Field(nullable=False)


class Contract(SQLModel, table=True):
__table_args__ = (
UniqueConstraint("address", "chain_id", name="address_chain_unique"),
)

address: bytes = Field(nullable=False, primary_key=True)
name: str = Field(nullable=False)
description: Optional[str] = None
display_name: str | None = None
description: str | None = None
trusted_for_delegate: bool = Field(nullable=False, default=False)
proxy: bool = Field(nullable=False, default=False)
fetch_retries: int = Field(nullable=False, default=0)
abi_id: bytes | None = Field(
nullable=True, default=None, foreign_key="abi.abi_hash"
)
chain_id: int = Field(default=None, foreign_key="chain.id")
Empty file added app/services/abi.py
Empty file.
36 changes: 36 additions & 0 deletions app/services/chain.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from typing import Sequence

from sqlmodel import select
from sqlmodel.ext.asyncio.session import AsyncSession

from app.datasources.db.database import get_database_session
from app.datasources.db.models import Chain


class ChainService:

@staticmethod
@get_database_session
async def get_all(session: AsyncSession) -> Sequence[Chain]:
"""
Get all chains
:param session: passed by the decorator
:return:
"""
result = await session.exec(select(Chain))
return result.all()

@staticmethod
@get_database_session
async def create(chain: Chain, session: AsyncSession) -> Chain:
"""
Create a new chain
:param chain:
:param session:
:return:
"""
session.add(chain)
await session.commit()
return chain
11 changes: 11 additions & 0 deletions app/tests/db/factories.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from factory.alchemy import SQLAlchemyModelFactory
from sqlmodel import Session

from app.datasources.db.models import Chain


class ChainFactory(SQLAlchemyModelFactory):
class Meta:
model = Chain
sqlalchemy_session_factory = Session
sqlalchemy_session_persistence = "commit"
6 changes: 4 additions & 2 deletions app/tests/db/test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@
from sqlmodel.ext.asyncio.session import AsyncSession

from app.datasources.db.database import database_session
from app.datasources.db.models import Contract
from app.datasources.db.models import Chain, Contract
from app.tests.db.db_async_conn import DbAsyncConn


class TestModel(DbAsyncConn):
@database_session
async def test_contract(self, session: AsyncSession):
contract = Contract(address=b"a", name="A Test Contracts")
chain = Chain(id=1, name="mainnet")
session.add(chain)
contract = Contract(address=b"a", name="A Test Contracts", chain_id=chain.id)
session.add(contract)
await session.commit()
statement = select(Contract).where(Contract.address == b"a")
Expand Down
9 changes: 6 additions & 3 deletions app/tests/routers/test_contracts.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from fastapi.testclient import TestClient

from sqlmodel.ext.asyncio.session import AsyncSession

from ...datasources.db.database import database_session
from ...datasources.db.models import Contract
from ...datasources.db.models import Chain, Contract
from ...main import app
from ...services.chain import ChainService
from ...services.contract import ContractService
from ..db.db_async_conn import DbAsyncConn

Expand All @@ -16,9 +16,12 @@ class TestRouterContract(DbAsyncConn):
def setUpClass(cls):
cls.client = TestClient(app)


@database_session
async def test_view_contracts(self, session: AsyncSession):
contract = Contract(address=b"a", name="A Test Contracts")
chain = Chain(id=1, name="mainnet")
await ChainService.create(chain)
contract = Contract(address=b"a", name="A Test Contracts", chain_id=1)
expected_response = {
"name": "A Test Contracts",
"description": None,
Expand Down
80 changes: 80 additions & 0 deletions migrations/versions/c52699d26409_init.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
"""init
Revision ID: c52699d26409
Revises:
Create Date: 2024-12-11 10:58:44.921603
"""

from typing import Sequence, Union

import sqlalchemy as sa
import sqlmodel
from alembic import op

# revision identifiers, used by Alembic.
revision: str = "c52699d26409"
down_revision: Union[str, None] = None
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table(
"abisource",
sa.Column("id", sa.Integer(), nullable=False),
sa.Column("name", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
sa.Column("url", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
sa.PrimaryKeyConstraint("id"),
)
op.create_table(
"chain",
sa.Column("id", sa.Integer(), nullable=False),
sa.Column("name", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
sa.PrimaryKeyConstraint("id"),
)
op.create_table(
"abi",
sa.Column("abi_hash", sa.LargeBinary(), nullable=False),
sa.Column("relevance", sa.Integer(), nullable=False),
sa.Column("abi_json", sa.JSON(), nullable=True),
sa.Column("source_id", sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(
["source_id"],
["abisource.id"],
),
sa.PrimaryKeyConstraint("abi_hash"),
)
op.create_table(
"contract",
sa.Column("address", sa.LargeBinary(), nullable=False),
sa.Column("name", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
sa.Column("display_name", sqlmodel.sql.sqltypes.AutoString(), nullable=True),
sa.Column("description", sqlmodel.sql.sqltypes.AutoString(), nullable=True),
sa.Column("trusted_for_delegate", sa.Boolean(), nullable=False),
sa.Column("proxy", sa.Boolean(), nullable=False),
sa.Column("fetch_retries", sa.Integer(), nullable=False),
sa.Column("abi_id", sa.LargeBinary(), nullable=True),
sa.Column("chain_id", sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(
["abi_id"],
["abi.abi_hash"],
),
sa.ForeignKeyConstraint(
["chain_id"],
["chain.id"],
),
sa.PrimaryKeyConstraint("address"),
sa.UniqueConstraint("address", "chain_id", name="address_chain_unique"),
)
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table("contract")
op.drop_table("abi")
op.drop_table("chain")
op.drop_table("abisource")
# ### end Alembic commands ###
37 changes: 0 additions & 37 deletions migrations/versions/d0c5d72aa50b_init.py

This file was deleted.

0 comments on commit b825684

Please sign in to comment.