diff --git a/lib/__pycache__/db.cpython-38.pyc b/lib/__pycache__/db.cpython-38.pyc new file mode 100644 index 000000000..b61cfbfd0 Binary files /dev/null and b/lib/__pycache__/db.cpython-38.pyc differ diff --git a/lib/__pycache__/debug.cpython-38.pyc b/lib/__pycache__/debug.cpython-38.pyc new file mode 100644 index 000000000..2103b1eae Binary files /dev/null and b/lib/__pycache__/debug.cpython-38.pyc differ diff --git a/lib/__pycache__/models.cpython-38.pyc b/lib/__pycache__/models.cpython-38.pyc new file mode 100644 index 000000000..46da21232 Binary files /dev/null and b/lib/__pycache__/models.cpython-38.pyc differ diff --git a/lib/db.py b/lib/db.py new file mode 100644 index 000000000..7e022c6b1 --- /dev/null +++ b/lib/db.py @@ -0,0 +1,9 @@ +from sqlalchemy import create_engine +from sqlalchemy.orm import sessionmaker + +# Default DB URL for the freebie tracker +DB_URL = 'sqlite:///freebies.db' + +engine = create_engine(DB_URL) +Session = sessionmaker(bind=engine) +session = Session() diff --git a/lib/debug.py b/lib/debug.py index 4f922eb69..784317a19 100644 --- a/lib/debug.py +++ b/lib/debug.py @@ -2,8 +2,11 @@ from sqlalchemy import create_engine -from models import Company, Dev +from models import Company, Dev, Freebie, Base +from db import engine, session if __name__ == '__main__': - engine = create_engine('sqlite:///freebies.db') + # ensure tables exist + Base.metadata.create_all(engine) + import ipdb; ipdb.set_trace() diff --git a/lib/migrations/versions/8a1b2c3d4e5f_create_freebies.py b/lib/migrations/versions/8a1b2c3d4e5f_create_freebies.py new file mode 100644 index 000000000..0f4381799 --- /dev/null +++ b/lib/migrations/versions/8a1b2c3d4e5f_create_freebies.py @@ -0,0 +1,31 @@ +"""create freebies table + +Revision ID: 8a1b2c3d4e5f +Revises: 5f72c58bf48c +Create Date: 2026-01-22 00:00:00.000000 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '8a1b2c3d4e5f' +down_revision = '5f72c58bf48c' +branch_labels = None +depends_on = None + + +def upgrade() -> None: + op.create_table( + 'freebies', + sa.Column('id', sa.Integer(), primary_key=True), + sa.Column('item_name', sa.String(), nullable=True), + sa.Column('value', sa.Integer(), nullable=True), + sa.Column('dev_id', sa.Integer(), sa.ForeignKey('devs.id')), + sa.Column('company_id', sa.Integer(), sa.ForeignKey('companies.id')), + ) + + +def downgrade() -> None: + op.drop_table('freebies') diff --git a/lib/models.py b/lib/models.py index 2681bee5a..a4a808a5e 100644 --- a/lib/models.py +++ b/lib/models.py @@ -19,6 +19,36 @@ class Company(Base): def __repr__(self): return f'' + def give_freebie(self, dev, item_name, value): + """Create and return a Freebie associated with this company and the given dev. + + This will add the Freebie to the current session if one is available as + the global `session` variable (as created in `debug.py`). If no session + is present, the Freebie instance will be returned but not persisted. + """ + freebie = Freebie(item_name=item_name, value=value, dev=dev, company=self) + try: + # If a shared session exists in db.py, persist and commit + from db import session + session.add(freebie) + session.commit() + except Exception: + # No session available; return uncommitted instance + pass + return freebie + + @classmethod + def oldest_company(cls): + """Return the Company with the earliest founding_year. + + Requires a global `session` variable (created in `debug.py`) to query. + """ + try: + from db import session + return session.query(cls).order_by(cls.founding_year).first() + except Exception: + return None + class Dev(Base): __tablename__ = 'devs' @@ -27,3 +57,48 @@ class Dev(Base): def __repr__(self): return f'' + + def received_one(self, item_name): + """Return True if this Dev has received a freebie with item_name.""" + return any(f.item_name == item_name for f in getattr(self, 'freebies', [])) + + def give_away(self, dev, freebie): + """Give away a freebie to another dev. + + Only performs the transfer if the freebie currently belongs to self. + If a session exists, the change will be committed. + Returns the updated Freebie or None if transfer not allowed. + """ + if freebie in getattr(self, 'freebies', []): + freebie.dev = dev + try: + from db import session + session.add(freebie) + session.commit() + except Exception: + pass + return freebie + return None + + +class Freebie(Base): + __tablename__ = 'freebies' + + id = Column(Integer(), primary_key=True) + item_name = Column(String()) + value = Column(Integer()) + dev_id = Column(Integer(), ForeignKey('devs.id')) + company_id = Column(Integer(), ForeignKey('companies.id')) + + # relationships + dev = relationship('Dev', backref=backref('freebies', cascade='all, delete-orphan')) + company = relationship('Company', backref=backref('freebies', cascade='all, delete-orphan')) + + def print_details(self): + """Return a string: {dev name} owns a {freebie item_name} from {company name}.""" + dev_name = self.dev.name if self.dev else 'Unknown Dev' + comp_name = self.company.name if self.company else 'Unknown Company' + return f"{dev_name} owns a {self.item_name} from {comp_name}." + +# establish many-to-many view: Dev.companies via freebies +Dev.companies = relationship('Company', secondary='freebies', backref='devs', viewonly=True) diff --git a/lib/seed.py b/lib/seed.py index b16becbbb..122fff179 100644 --- a/lib/seed.py +++ b/lib/seed.py @@ -1,3 +1,51 @@ #!/usr/bin/env python3 -# Script goes here! +from sqlalchemy import create_engine +from sqlalchemy.orm import sessionmaker + +from models import Company, Dev, Freebie, Base + + +def seed(db_url: str = 'sqlite:///freebies.db'): + engine = create_engine(db_url) + Session = sessionmaker(bind=engine) + session = Session() + + Base.metadata.create_all(engine) + + # Clear existing data for a fresh seed + session.query(Freebie).delete() + session.query(Dev).delete() + session.query(Company).delete() + session.commit() + + # Create some companies and devs + c1 = Company(name='GitHub', founding_year=2008) + c2 = Company(name='Google', founding_year=1998) + c3 = Company(name='ACME Corp', founding_year=1970) + + d1 = Dev(name='Ada') + d2 = Dev(name='Grace') + + session.add_all([c1, c2, c3, d1, d2]) + session.commit() + + # Create freebies + f1 = Freebie(item_name='Sticker Pack', value=1, dev=d1, company=c1) + f2 = Freebie(item_name='T-Shirt', value=25, dev=d1, company=c2) + f3 = Freebie(item_name='Coffee Mug', value=10, dev=d2, company=c3) + + session.add_all([f1, f2, f3]) + session.commit() + + return { + 'companies': session.query(Company).count(), + 'devs': session.query(Dev).count(), + 'freebies': session.query(Freebie).count(), + } + + +if __name__ == '__main__': + print('Seeding freebie tracker...') + res = seed() + print('Seeded:', res)