Skip to content

Commit

Permalink
Include time_created/time_updated on every model 🛢 (#225)
Browse files Browse the repository at this point in the history
* Include time_created/time_updated on every model.

* Client-side updates don't do anything in migrations.

* Don't drop slot's time_updated because we didn't make it!

* Migration merge commit.
  • Loading branch information
MelissaAutumn authored Jan 12, 2024
1 parent c687fde commit 8bd4106
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 14 deletions.
3 changes: 0 additions & 3 deletions backend/src/appointment/database/database.py

This file was deleted.

23 changes: 12 additions & 11 deletions backend/src/appointment/database/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@
from sqlalchemy import Column, ForeignKey, Integer, String, DateTime, Enum, Boolean, JSON, Date, Time
from sqlalchemy_utils import StringEncryptedType, ChoiceType
from sqlalchemy_utils.types.encrypted.encrypted_type import AesEngine
from sqlalchemy.orm import relationship
from sqlalchemy.orm import relationship, as_declarative, declared_attr
from sqlalchemy.sql import func
from .database import Base


def secret():
Expand Down Expand Up @@ -73,6 +72,17 @@ class MeetingLinkProviderType(enum.StrEnum):
google_meet = 'google_meet'


@as_declarative()
class Base:
"""Base model, contains anything we want to be on every model."""
@declared_attr
def __tablename__(cls):
return cls.__name__.lower()

time_created = Column(DateTime, server_default=func.now(), index=True)
time_updated = Column(DateTime, server_default=func.now(), onupdate=func.now(), index=True)


class Subscriber(Base):
__tablename__ = "subscribers"

Expand Down Expand Up @@ -128,8 +138,6 @@ class Appointment(Base):

id = Column(Integer, primary_key=True, index=True)
calendar_id = Column(Integer, ForeignKey("calendars.id"))
time_created = Column(DateTime, server_default=func.now())
time_updated = Column(DateTime, server_default=func.now(), onupdate=func.now())
duration = Column(Integer)
title = Column(StringEncryptedType(String, secret, AesEngine, "pkcs5", length=255))
location_type = Column(Enum(LocationType), default=LocationType.inperson)
Expand Down Expand Up @@ -207,8 +215,6 @@ class Schedule(Base):
farthest_booking = Column(Integer, default=20160) # in minutes, defaults to 2 weeks
weekdays = Column(JSON, default="[1,2,3,4,5]") # list of ISO weekdays, Mo-Su => 1-7
slot_duration = Column(Integer, default=30) # defaults to 30 minutes
time_created = Column(DateTime, server_default=func.now())
time_updated = Column(DateTime, server_default=func.now(), onupdate=func.now())

# What (if any) meeting link will we generate once the meeting is booked
meeting_link_provider = Column(StringEncryptedType(ChoiceType(MeetingLinkProviderType), secret, AesEngine, "pkcs5", length=255), default=MeetingLinkProviderType.none, index=False)
Expand All @@ -233,8 +239,6 @@ class Availability(Base):
# Can't book if it's less than X minutes before start time:
min_time_before_meeting = Column(StringEncryptedType(String, secret, AesEngine, "pkcs5", length=255), index=True)
slot_duration = Column(Integer) # Size of the Slot that can be booked.
time_created = Column(DateTime, server_default=func.now())
time_updated = Column(DateTime, server_default=func.now(), onupdate=func.now())

schedule = relationship("Schedule", back_populates="availabilities")

Expand All @@ -249,7 +253,4 @@ class ExternalConnections(Base):
type = Column(Enum(ExternalConnectionType), index=True)
type_id = Column(StringEncryptedType(String, secret, AesEngine, "pkcs5", length=255), index=True)
token = Column(StringEncryptedType(String, secret, AesEngine, "pkcs5", length=2048), index=False)
time_created = Column(DateTime, server_default=func.now())
time_updated = Column(DateTime, server_default=func.now(), onupdate=func.now())

owner = relationship("Subscriber", back_populates="external_connections")
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
"""add time_created and time_updated to tables
Revision ID: 502c76bc79e0
Revises: 0dc429ca07f5
Create Date: 2024-01-10 22:59:02.194281
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy import func

# revision identifiers, used by Alembic.
revision = '502c76bc79e0'
down_revision = '0dc429ca07f5'
branch_labels = None
depends_on = None

affected_tables = ['attendees', 'calendars', 'slots', 'subscribers']
index_tables = ['appointments', 'availabilities', 'external_connections', 'schedules', 'slots', ]

def upgrade() -> None:
for table in affected_tables:
op.add_column(table, sa.Column('time_created', sa.DateTime, server_default=func.now(), index=True))
# Slots already has this column...
if table != 'slots':
op.add_column(table, sa.Column('time_updated', sa.DateTime, server_default=func.now(), index=True))

# Fix some existing time_* columns
for table in index_tables:
op.create_index('ix_time_created', table, ['time_created'])
op.create_index('ix_time_updated', table, ['time_updated'])


def downgrade() -> None:
for table in affected_tables:
op.drop_column(table, 'time_created')
if table != 'slots':
op.drop_column(table, 'time_updated')

for table in index_tables:
op.drop_index('ix_time_created', table)
op.drop_index('ix_time_updated', table)
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"""Merge Commit
Revision ID: ea551afc14fc
Revises: ad7cc2de5ff8, 502c76bc79e0
Create Date: 2024-01-12 18:01:38.962773
"""
from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = 'ea551afc14fc'
down_revision = ('ad7cc2de5ff8', '502c76bc79e0')
branch_labels = None
depends_on = None


def upgrade() -> None:
pass


def downgrade() -> None:
pass

0 comments on commit 8bd4106

Please sign in to comment.