Interface CaldavObjectSyncDAO

All Superinterfaces:
org.springframework.data.repository.CrudRepository<CaldavObjectSyncEntity,Long>, org.springframework.data.jpa.repository.JpaRepository<CaldavObjectSyncEntity,Long>, org.springframework.data.repository.ListCrudRepository<CaldavObjectSyncEntity,Long>, org.springframework.data.repository.ListPagingAndSortingRepository<CaldavObjectSyncEntity,Long>, org.springframework.data.repository.PagingAndSortingRepository<CaldavObjectSyncEntity,Long>, org.springframework.data.repository.query.QueryByExampleExecutor<CaldavObjectSyncEntity>, org.springframework.data.repository.Repository<CaldavObjectSyncEntity,Long>

public interface CaldavObjectSyncDAO extends org.springframework.data.jpa.repository.JpaRepository<CaldavObjectSyncEntity,Long>
Persistence access to the object mappings.

Every listing here is paginated without exception: a calendar's object count is the user's, not the developer's, to decide, and a busy shared calendar is exactly the one whose full read would hurt.

  • Method Summary

    Modifier and Type
    Method
    Description
    long
    countByCalendarSyncId(long calendarSyncId)
    How many objects a pair maps.
    long
    countByOwnerAndOriginAndIcsUid(long userIdentityId, long serverId, org.exoplatform.caldav.model.SyncOrigin origin, String icsUid)
    How many of this user's pairs of one origin, on one server, already map this iCalendar UID.
    int
    deleteByCalendarSyncId(long calendarSyncId)
    Drops every mapping of a pair.
    boolean
    existsByLocalEventId(long localEventId)
    Whether an eXo event is already mapped anywhere.
    org.springframework.data.domain.Page<CaldavObjectSyncEntity>
    findByCalendarSyncId(long calendarSyncId, org.springframework.data.domain.Pageable pageable)
    One page of a pair's object mappings.
    findByCalendarSyncIdAndIcsUid(long calendarSyncId, String icsUid)
    The mapping for one iCalendar object inside a pair.
    findByCalendarSyncIdAndLocalEventId(long calendarSyncId, long localEventId)
    The mapping for one eXo event inside a pair.
    org.springframework.data.domain.Page<CaldavObjectSyncEntity>
    findByLocalEventId(long localEventId, org.springframework.data.domain.Pageable pageable)
    Every mapping of one eXo event, across the collections of every user.
    findEventIdsByOwnerAndOriginAndIcsUid(long userIdentityId, long serverId, org.exoplatform.caldav.model.SyncOrigin origin, String icsUid)
    Which eXo events this user's pairs of one origin, on one server, hold that iCalendar UID for.
    Which of these eXo events are already mapped.
    findMappedLocalEventIdsOfUser(long userIdentityId, Collection<Long> localEventIds)
    Which of these eXo events this user already holds a copy of.

    Methods inherited from interface org.springframework.data.repository.CrudRepository

    count, delete, deleteAll, deleteAll, deleteAllById, deleteById, existsById, findById, save

    Methods inherited from interface org.springframework.data.jpa.repository.JpaRepository

    deleteAllByIdInBatch, deleteAllInBatch, deleteAllInBatch, deleteInBatch, findAll, findAll, flush, getById, getOne, getReferenceById, saveAllAndFlush, saveAndFlush

    Methods inherited from interface org.springframework.data.repository.ListCrudRepository

    findAll, findAllById, saveAll

    Methods inherited from interface org.springframework.data.repository.ListPagingAndSortingRepository

    findAll

    Methods inherited from interface org.springframework.data.repository.PagingAndSortingRepository

    findAll

    Methods inherited from interface org.springframework.data.repository.query.QueryByExampleExecutor

    count, exists, findAll, findBy, findOne
  • Method Details

    • findByCalendarSyncIdAndIcsUid

      Optional<CaldavObjectSyncEntity> findByCalendarSyncIdAndIcsUid(long calendarSyncId, String icsUid)
      The mapping for one iCalendar object inside a pair. The identity lookup the engine performs before every write.
      Parameters:
      calendarSyncId - the pair
      icsUid - the iCalendar UID
      Returns:
      the mapping, if the object is already known
    • findByCalendarSyncIdAndLocalEventId

      Optional<CaldavObjectSyncEntity> findByCalendarSyncIdAndLocalEventId(long calendarSyncId, long localEventId)
      The mapping for one eXo event inside a pair.
      Parameters:
      calendarSyncId - the pair
      localEventId - the eXo event
      Returns:
      the mapping, if the event has been pushed
    • findByLocalEventId

      org.springframework.data.domain.Page<CaldavObjectSyncEntity> findByLocalEventId(long localEventId, org.springframework.data.domain.Pageable pageable)
      Every mapping of one eXo event, across the collections of every user.

      The query the propagation of an edit is driven from: the rows it answers are the set of people who already hold a copy of that meeting, which is the only set an edit is allowed to write to. Asked of the mapping table rather than of agenda's attendee list on purpose — an attendee without a copy must not acquire one from an edit, and a meeting destroyed in eXo has no attendee list left to ask.

      Paginated like every other listing here: the row count is the number of attendees who connected a calendar account, which is the users' number to decide and not the developer's.

      Parameters:
      localEventId - the eXo event
      pageable - page and sort; required
      Returns:
      one page of mappings
    • findByCalendarSyncId

      org.springframework.data.domain.Page<CaldavObjectSyncEntity> findByCalendarSyncId(long calendarSyncId, org.springframework.data.domain.Pageable pageable)
      One page of a pair's object mappings.
      Parameters:
      calendarSyncId - the pair
      pageable - page and sort; required
      Returns:
      one page of mappings
    • countByCalendarSyncId

      long countByCalendarSyncId(long calendarSyncId)
      How many objects a pair maps.
      Parameters:
      calendarSyncId - the pair
      Returns:
      the mapping count
    • existsByLocalEventId

      boolean existsByLocalEventId(long localEventId)
      Whether an eXo event is already mapped anywhere. The backfill's idempotence check, asked once per event rather than per pair.
      Parameters:
      localEventId - the eXo event
      Returns:
      true when a mapping exists
    • findMappedLocalEventIds

      @Query("SELECT DISTINCT o.localEventId FROM CaldavObjectSyncEntity o WHERE o.localEventId IN :localEventIds") List<Long> findMappedLocalEventIds(@Param("localEventIds") Collection<Long> localEventIds)
      Which of these eXo events are already mapped. The same question as existsByLocalEventId(long) asked once for a whole batch. The seeding pass reads a user's upcoming meetings on every sweep and, in the steady state, finds that all of them already have a copy — so asking one event at a time made the cost of doing nothing grow with how much had already been done, which is the wrong direction for work that repeats for ever.
      Parameters:
      localEventIds - the eXo events to ask about
      Returns:
      the identifiers among them that carry a mapping
    • findMappedLocalEventIdsOfUser

      @Query("SELECT DISTINCT o.localEventId FROM CaldavObjectSyncEntity o, CaldavCalendarSyncEntity p WHERE o.calendarSyncId = p.id AND p.userIdentityId = :userIdentityId AND o.localEventId IN :localEventIds") List<Long> findMappedLocalEventIdsOfUser(@Param("userIdentityId") long userIdentityId, @Param("localEventIds") Collection<Long> localEventIds)
      Which of these eXo events this user already holds a copy of. Scoped through the pair to its owner, and that scope is the whole point: a mapping says "somebody has a copy of this event", and every attendee of a meeting needs one of their own. Asking the unscoped question in a per-user pass meant the first attendee to be copied answered for all the others, who were then skipped and never got their copy.
      Parameters:
      userIdentityId - the user whose copies are asked about
      localEventIds - the eXo events to ask about
      Returns:
      the identifiers this user already has a copy of
    • countByOwnerAndOriginAndIcsUid

      @Query("SELECT COUNT(o) FROM CaldavObjectSyncEntity o, CaldavCalendarSyncEntity p WHERE o.calendarSyncId = p.id AND p.userIdentityId = :userIdentityId AND p.serverId = :serverId AND p.origin = :origin AND o.icsUid = :icsUid") long countByOwnerAndOriginAndIcsUid(@Param("userIdentityId") long userIdentityId, @Param("serverId") long serverId, @Param("origin") org.exoplatform.caldav.model.SyncOrigin origin, @Param("icsUid") String icsUid)
      How many of this user's pairs of one origin, on one server, already map this iCalendar UID.

      The ownership question the inbound half asks before importing an object: "did eXo write this?". Every other lookup here is scoped to a single pair, which is precisely why it cannot answer it — a copy eXo wrote carries its mapping on the pair it was written into, and the pair asking is a different one. Pointed at a collection both halves read, the pair-scoped question finds nothing and the import creates a duplicate of eXo's own event.

      A count rather than the rows: the caller only ever asks whether the object is ours, and the row it would be handed belongs to another pair, so returning it would invite writing to a mapping this pair does not own.

      Parameters:
      userIdentityId - the user whose pairs are asked about
      serverId - the declared server registration; a UID on one account says nothing about an object on another
      origin - which side created the collections that count as owning
      icsUid - the iCalendar UID looked for
      Returns:
      how many mappings of that origin carry the UID, zero when none do
    • findEventIdsByOwnerAndOriginAndIcsUid

      @Query("SELECT DISTINCT o.localEventId FROM CaldavObjectSyncEntity o, CaldavCalendarSyncEntity p WHERE o.calendarSyncId = p.id AND p.userIdentityId = :userIdentityId AND p.serverId = :serverId AND p.origin = :origin AND o.icsUid = :icsUid AND o.localEventId IS NOT NULL") List<Long> findEventIdsByOwnerAndOriginAndIcsUid(@Param("userIdentityId") long userIdentityId, @Param("serverId") long serverId, @Param("origin") org.exoplatform.caldav.model.SyncOrigin origin, @Param("icsUid") String icsUid)
      Which eXo events this user's pairs of one origin, on one server, hold that iCalendar UID for.

      The question above answers "did eXo write this object?"; this one answers "and what did it write it for?" (EXO-89807). The inbound half needs the second because the owner's answer arrives on an object it is about to drop as one of eXo's own, and an answer can only be recorded against the event the copy stands for — which lives on a different pair from the one doing the reading, and so is out of reach of every pair-scoped lookup here.

      The event identifiers and nothing else, deliberately, for the reason the count above records: the caller must not be handed a mapping row belonging to another pair, because a row it holds is a row it can write to. An identifier is a fact it can only read.

      Parameters:
      userIdentityId - the user whose pairs are asked about
      serverId - the declared server registration
      origin - which side created the collections that count as owning
      icsUid - the iCalendar UID looked for
      Returns:
      the events those mappings name, empty when the UID is not ours
    • deleteByCalendarSyncId

      @Modifying @Transactional @Query("DELETE FROM CaldavObjectSyncEntity o WHERE o.calendarSyncId = :calendarSyncId") int deleteByCalendarSyncId(@Param("calendarSyncId") long calendarSyncId)
      Drops every mapping of a pair. Called when a pair is unbound; the foreign key would cascade on a row delete, but a pair is often kept as a tombstone while its objects are not.
      Parameters:
      calendarSyncId - the pair
      Returns:
      how many mappings were removed