def _invalidate_drill_instance(drill_instance_id: Optional[uuid.UUID], connection): if drill_instance_id is None: return connection.execute(drill_instances.update().where( drill_instances.c.drill_instance_id == func.uuid( str(drill_instance_id))).values(is_valid=False))
def _update_current_prompt_response_time(event: Union[FailedPrompt, CompletedPrompt], connection): connection.execute(drill_instances.update().where( drill_instances.c.drill_instance_id == func.uuid( str(event.drill_instance_id))).values( current_prompt_last_response_time=event.created_time))
def _update_current_prompt(event: AdvancedToNextPrompt, connection): connection.execute(drill_instances.update().where( drill_instances.c.drill_instance_id == func.uuid( str(event.drill_instance_id))).values( current_prompt_last_response_time=None, current_prompt_start_time=event.created_time, current_prompt_slug=event.prompt.slug, ))
def _mark_drill_started(user_id: uuid.UUID, event: DrillStarted, connection): connection.execute(drill_statuses.update().where( and_( drill_statuses.c.user_id == func.uuid(str(user_id)), drill_statuses.c.drill_slug == event.drill.slug, )).values(started_time=event.created_time, drill_instance_id=str(event.drill_instance_id)))
def delete_user_info(self, phone_number: str) -> Optional[uuid.UUID]: # useful for backfills and rebuilding users. Shouldn't be called regularly. with self.engine.connect() as connection: with connection.begin(): user = self.get_user_for_phone_number(phone_number, connection) if user is None: logging.info(f"No user exists for {phone_number}") return None connection.execute(phone_numbers.delete().where( phone_numbers.c.user_id == func.uuid(str(user.user_id)))) connection.execute(drill_statuses.delete().where( drill_statuses.c.user_id == func.uuid(str(user.user_id)))) connection.execute(drill_instances.delete().where( drill_instances.c.user_id == func.uuid(str(user.user_id)))) connection.execute(users.delete().where( users.c.user_id == func.uuid(str(user.user_id)))) return user.user_id
def _mark_drill_instance_complete(event: DrillCompleted, connection): connection.execute(drill_instances.update().where( drill_instances.c.drill_instance_id == func.uuid( str(event.drill_instance_id))).values( completion_time=event.created_time, current_prompt_slug=None, current_prompt_start_time=None, current_prompt_last_response_time=None, ))
def get_user(self, user_id: uuid.UUID) -> Optional[User]: result = self.engine.execute( select([users]).where(users.c.user_id == func.uuid(str(user_id)))) row = result.fetchone() if row is None: return None return User( user_id=uuid.UUID(row["user_id"]), profile=row["profile"], last_interacted_time=row["last_interacted_time"], seq=row["seq"], )
def get_drill_instance(self, drill_instance_id: uuid.UUID, connection=None) -> Optional[DrillInstance]: if connection is None: connection = self.engine result = connection.execute( select([drill_instances ]).where(drill_instances.c.drill_instance_id == func.uuid( str(drill_instance_id)))) row = result.fetchone() if row is None: return None return self._deserialize(row)
def _create_or_update_user(self, batch: DialogEventBatch, ensure_user_id: Optional[uuid.UUID], connection) -> uuid.UUID: event = batch.events[-1] phone_number = event.phone_number profile = event.user_profile.to_dict() result = connection.execute( select([phone_numbers ]).where(phone_numbers.c.phone_number == phone_number)) row = result.fetchone() if row is None: logging.info(f"No record of {phone_number}. Creating a new entry.") user_record = User(profile=profile, seq=batch.seq) if ensure_user_id: user_record.user_id = ensure_user_id phone_number_record = PhoneNumber(phone_number=phone_number, user_id=user_record.user_id) connection.execute(users.insert().values( user_id=str(user_record.user_id), profile=user_record.profile, seq=batch.seq)) connection.execute(phone_numbers.insert().values( id=str(phone_number_record.id), user_id=str(phone_number_record.user_id), is_primary=phone_number_record.is_primary, phone_number=phone_number_record.phone_number, )) for i, slug in enumerate(get_all_drill_slugs()): connection.execute(drill_statuses.insert().values( id=str(uuid.uuid4()), user_id=str(user_record.user_id), drill_slug=slug, place_in_sequence=i, )) logging.info( f"New user ID for {phone_number} is {user_record.user_id}") return user_record.user_id phone_number_record = PhoneNumber(**row) user_record = self.get_user(phone_number_record.user_id) if int(user_record.seq) >= int(batch.seq): logging.info( f"Ignoring batch at {batch.seq} because a more recent user exists " f"(seq {user_record.seq}") return phone_number_record.user_id connection.execute(users.update().where(users.c.user_id == func.uuid( str(phone_number_record.user_id))).values(profile=profile, seq=batch.seq)) return phone_number_record.user_id
def get_progress_for_user(self, phone_number: str) -> DrillProgress: user = self.get_user_for_phone_number(phone_number) user_id = user.user_id result = self.engine.execute( select([ drill_statuses ]).where(drill_statuses.c.user_id == func.uuid(( str(user_id)))).order_by(drill_statuses.c.place_in_sequence)) progress = DrillProgress(phone_number=phone_number, user_id=user_id) for row in result: if progress.first_incomplete_drill_slug is None and row[ "completed_time"] is None: progress.first_incomplete_drill_slug = row["drill_slug"] if progress.first_unstarted_drill_slug is None and row[ "started_time"] is None: progress.first_unstarted_drill_slug = row["drill_slug"] return progress
class Airdrop(db.Model): __table_args__ = ( Index('idx_user_symbol', 'user_id', 'token', unique=True), ) initialized = 0 done = 1 id = Column(Integer, autoincrement=True, primary_key=True) user_id = Column(String(50), nullable=False) token = Column(String(50), nullable=False) trace_id = Column(String(50), default=func.uuid(), nullable=False) state = Column(Integer, nullable=False) created_at = Column(DateTime, default=func.now(), nullable=False) updated_at = Column(DateTime, default=func.now(), onupdate=func.now(), nullable=False) pass
def get_drill_status(self, user_id: uuid.UUID, drill_slug: str) -> Optional[DrillStatus]: result = self.engine.execute( select([drill_statuses]).where( and_( drill_statuses.c.user_id == func.uuid(str(user_id)), drill_statuses.c.drill_slug == drill_slug, ))) row = result.fetchone() if row is None: return None drill_instance_id = (uuid.UUID(row["drill_instance_id"]) if row["drill_instance_id"] else None) return DrillStatus( id=uuid.UUID(row["id"]), user_id=uuid.UUID(row["user_id"]), drill_instance_id=drill_instance_id, drill_slug=row["drill_slug"], place_in_sequence=row["place_in_sequence"], started_time=row["started_time"], completed_time=row["completed_time"], )
def _mark_interacted_time(user_id, event: DialogEvent, connection): connection.execute(users.update().where( users.c.user_id == func.uuid(str(user_id))).values( last_interacted_time=event.created_time))
class UuidMixin(object): uuid = Column(VARCHAR(36), nullable=False, default=func.uuid())
def _reset_drill_statuses(user_id: uuid.UUID, connection): connection.execute(drill_statuses.update().where( drill_statuses.c.user_id == func.uuid(str(user_id))).values( started_time=None, completed_time=None, drill_instance_id=None))
def _unmark_drill_started(event: OptedOut, connection): connection.execute(drill_statuses.update().where( drill_statuses.c.drill_instance_id == func.uuid( str(event.drill_instance_id))).values(started_time=None))
def _mark_drill_completed(event: DrillCompleted, connection): connection.execute(drill_statuses.update().where( (drill_statuses.c.drill_instance_id == func.uuid( str(event.drill_instance_id)))).values( completed_time=event.created_time))
def _invalidate_prior_drills(user_id: uuid.UUID, connection): connection.execute(drill_instances.update().where( and_( drill_instances.c.user_id == func.uuid(str(user_id)), drill_instances.c.is_valid.is_(True), )).values(is_valid=False))