Skip to main content

Colony Event Repository

Repositories Definition

This file defines the colony event repository structure within the Roll Claw domain model.

Implementation

Colony Event Repository Definition

File: domain/repositories/colony_event_repository.pseudo

// ColonyEventRepository Implementation - Specialized for temporal queries

class ColonyEventRepositoryImpl implements ColonyEventRepository {
// Basic storage
private Map<string, ColonyEvent> events

// Temporal indexes for efficient retrieval
private Map<string, Map<Date, List<string>>> eventsByTypeAndDate
private Map<string, Map<string, List<string>>> eventsByCatId
private Map<string, List<string>> eventsByYearMonth
private Map<string, List<string>> eventsByLocation

// Basic event operations
function findById(string id) {
return events.get(id)
}

function findByType(string type) {
List<ColonyEvent> result = []
for (event in events.values()) {
if (event.type == type) {
result.add(event)
}
}
return result
}

function findByCat(Cat cat) {
List<string> eventIds = eventsByCatId.get(cat.id) || []
return eventIds.map(id => events.get(id))
}

function findByLocation(Location location) {
List<string> eventIds = eventsByLocation.get(location.id) || []
return eventIds.map(id => events.get(id))
}

function findLatest(int count) {
return events.values()
.sortBy(e => e.date + " " + e.time)
.reverse()
.take(count)
}

function save(ColonyEvent event) {
// Store the event
events.put(event.id, event)

// Update indexes
updateTypeAndDateIndex(event)
updateCatIndex(event)
updateLocationIndex(event)
updateYearMonthIndex(event)
}

function delete(ColonyEvent event) {
// Remove from indexes
removeFromIndexes(event)

// Remove the event
events.remove(event.id)
}

// Enhanced temporal query capabilities
function findByDateRange(Date startDate, Date endDate, string eventType = null) {
List<ColonyEvent> result = []

// Find events in date range
for (event in events.values()) {
if (event.date >= startDate && event.date <= endDate) {
if (eventType == null || event.type == eventType) {
result.add(event)
}
}
}

return result.sortBy(e => e.date + " " + e.time)
}

function findByDateAndCat(Date date, Cat cat, string eventType = null) {
// Format date to string for lookup
string dateStr = formatDateToString(date)
string catId = cat.id
List<ColonyEvent> result = []

// Use cat index for efficiency
for (eventId in eventsByCatId.get(catId) || []) {
ColonyEvent event = events.get(eventId)
if (formatDateToString(event.date) == dateStr) {
if (eventType == null || event.type == eventType) {
result.add(event)
}
}
}

return result
}

function findInYearMonth(int year, int month, string eventType = null) {
string yearMonthKey = formatYearMonth(year, month)
List<string> eventIds = eventsByYearMonth.get(yearMonthKey) || []
List<ColonyEvent> result = []

for (eventId in eventIds) {
ColonyEvent event = events.get(eventId)
if (eventType == null || event.type == eventType) {
result.add(event)
}
}

return result.sortBy(e => e.date + " " + e.time)
}

function findInSpecificDate(int year, int month, int day) {
Date specificDate = createDate(year, month, day)
return findByDateRange(specificDate, specificDate)
}

// Correlation methods
function findRelatedEvents(ColonyEvent event, string relationshipType) {
// Implementation depends on relationship type
if (relationshipType == "same_cats") {
return findEventsByInvolvedCats(event.involvedCats)
} else if (relationshipType == "same_location") {
return findByLocation(event.location)
} else if (relationshipType == "sequential") {
// Find events that occurred after this one
return findByDateRange(event.date, null)
.filter(e => e.date > event.date ||
(e.date == event.date && e.time > event.time))
.take(10)
}
}

function getEventTimeline(Cat cat, Date startDate = null, Date endDate = null) {
List<ColonyEvent> catEvents = findByCat(cat)

// Filter by date range if specified
if (startDate != null) {
catEvents = catEvents.filter(e => e.date >= startDate)
}

if (endDate != null) {
catEvents = catEvents.filter(e => e.date <= endDate)
}

return catEvents.sortBy(e => e.date + " " + e.time)
}

function findSequentialEvents(Cat cat, string firstEventType, string secondEventType) {
List<ColonyEvent> timeline = getEventTimeline(cat)
List<Pair<ColonyEvent, ColonyEvent>> results = []

// Find pairs of events that match the sequence
for (int i = 0; i < timeline.size() - 1; i++) {
if (timeline[i].type == firstEventType &&
timeline[i+1].type == secondEventType) {
results.add(new Pair(timeline[i], timeline[i+1]))
}
}

return results
}

// Specialized temporal queries
function getQuarantinePeriod(Cat cat, Date approximateStartDate) {
// Find quarantine events around the approximate date
List<ColonyEvent> events = findByDateRange(
subtractDays(approximateStartDate, 30),
addDays(approximateStartDate, 30)
)
.filter(e => e.type == "quarantine" && e.involvedCats.contains(cat))

if (events.isEmpty()) {
return null
}

// Get the most relevant quarantine event
QuarantineEvent quarantine = (QuarantineEvent)events
.filter(e => e instanceof QuarantineEvent)
.sortBy(e => Math.abs(daysBetween(e.date, approximateStartDate)))
.first()

return quarantine
}

function getMedicalHistory(Cat cat, Date startDate = null, Date endDate = null) {
return getEventTimeline(cat, startDate, endDate)
.filter(e => isMedicalEvent(e.type))
}

function getCatLocationHistory(Cat cat) {
List<ColonyEvent> timeline = getEventTimeline(cat)
Map<Date, Location> locationsByDate = new Map()

// Extract location changes
for (event in timeline) {
if (event.type == "territory_change" ||
event.type == "relocation" ||
event.type == "access_change") {
locationsByDate.put(event.date, event.location)
}
}

return locationsByDate
}

function getStatusChanges(Cat cat) {
return getEventTimeline(cat)
.filter(e => e.type == "birth" ||
e.type == "death" ||
e.type == "adoption" ||
e.type == "disappearance" ||
e.type == "relocation")
}

// Multi-entity temporal correlation
function findConcurrentEvents(Date date, string eventType = null) {
// Find all events on the specific date
return findByDateRange(date, date, eventType)
}

function findEventsByCatGroup(List<Cat> catGroup, Date startDate = null, Date endDate = null) {
// Find events that involve any cat in the group
Set<string> catIds = catGroup.map(c => c.id).toSet()
List<ColonyEvent> result = []

for (event in events.values()) {
// Check if any involved cat is in the group
boolean isGroupEvent = false
for (cat in event.involvedCats) {
if (catIds.contains(cat.id)) {
isGroupEvent = true
break
}
}

// Filter by date if needed
if (isGroupEvent &&
(startDate == null || event.date >= startDate) &&
(endDate == null || event.date <= endDate)) {
result.add(event)
}
}

return result.sortBy(e => e.date + " " + e.time)
}

function findEventsByDateKeyword(string keyword) {
// For example: "2018-07" should find all events in July 2018
List<ColonyEvent> result = []

// Parse the keyword to extract year/month/day components
if (keyword.matches("\d{4}-\d{2}")) {
// Year-month format
int year = parseInt(keyword.substring(0, 4))
int month = parseInt(keyword.substring(5, 7))
return findInYearMonth(year, month)
} else if (keyword.matches("\d{4}-\d{2}-\d{2}")) {
// Year-month-day format
int year = parseInt(keyword.substring(0, 4))
int month = parseInt(keyword.substring(5, 7))
int day = parseInt(keyword.substring(8, 10))
return findInSpecificDate(year, month, day)
}

return result
}

// Helper methods
private boolean isMedicalEvent(string eventType) {
return eventType == "medical_procedure" ||
eventType == "vaccination" ||
eventType == "tnr" ||
eventType == "quarantine" ||
eventType == "illness" ||
eventType == "injury"
}

private void updateTypeAndDateIndex(ColonyEvent event) {
// Get or create the map for this event type
Map<Date, List<string>> dateMap = eventsByTypeAndDate.get(event.type)
if (dateMap == null) {
dateMap = new HashMap<>()
eventsByTypeAndDate.put(event.type, dateMap)
}

// Get or create the list for this date
List<string> eventIds = dateMap.get(event.date)
if (eventIds == null) {
eventIds = new ArrayList<>()
dateMap.put(event.date, eventIds)
}

// Add the event ID to the list
eventIds.add(event.id)
}

private void updateCatIndex(ColonyEvent event) {
// Update the cat index for each involved cat
for (Cat cat in event.involvedCats) {
Map<string, List<string>> typeMap = eventsByCatId.get(cat.id)
if (typeMap == null) {
typeMap = new HashMap<>()
eventsByCatId.put(cat.id, typeMap)
}

List<string> eventIds = typeMap.get(event.type)
if (eventIds == null) {
eventIds = new ArrayList<>()
typeMap.put(event.type, eventIds)
}

eventIds.add(event.id)
}
}

private void updateLocationIndex(ColonyEvent event) {
// Get or create the list for this location
List<string> eventIds = eventsByLocation.get(event.location.id)
if (eventIds == null) {
eventIds = new ArrayList<>()
eventsByLocation.put(event.location.id, eventIds)
}

// Add the event ID to the list
eventIds.add(event.id)
}

private void updateYearMonthIndex(ColonyEvent event) {
string yearMonth = formatDateToYearMonth(event.date)

// Get or create the list for this year-month
List<string> eventIds = eventsByYearMonth.get(yearMonth)
if (eventIds == null) {
eventIds = new ArrayList<>()
eventsByYearMonth.put(yearMonth, eventIds)
}

// Add the event ID to the list
eventIds.add(event.id)
}

private void removeFromIndexes(ColonyEvent event) {
// Remove from type-date index
Map<Date, List<string>> dateMap = eventsByTypeAndDate.get(event.type)
if (dateMap != null) {
List<string> dateEvents = dateMap.get(event.date)
if (dateEvents != null) {
dateEvents.remove(event.id)
}
}

// Remove from cat index
for (Cat cat in event.involvedCats) {
Map<string, List<string>> typeMap = eventsByCatId.get(cat.id)
if (typeMap != null) {
List<string> catEvents = typeMap.get(event.type)
if (catEvents != null) {
catEvents.remove(event.id)
}
}
}

// Remove from location index
List<string> locationEvents = eventsByLocation.get(event.location.id)
if (locationEvents != null) {
locationEvents.remove(event.id)
}

// Remove from year-month index
string yearMonth = formatDateToYearMonth(event.date)
List<string> yearMonthEvents = eventsByYearMonth.get(yearMonth)
if (yearMonthEvents != null) {
yearMonthEvents.remove(event.id)
}
}

// Format helpers
private string formatDateToString(Date date) {
// Format: YYYY-MM-DD
return date.toString()
}

private string formatYearMonth(int year, int month) {
// Format: YYYY-MM
return year + "-" + (month < 10 ? "0" + month : month)
}

private string formatDateToYearMonth(Date date) {
// Extract year and month from date
// Format: YYYY-MM
return date.getYear() + "-" + (date.getMonth() < 10 ? "0" + date.getMonth() : date.getMonth())
}

private Date createDate(int year, int month, int day) {
// Create a date object from components
// Implementation depends on the language
return new Date(year, month, day)
}

private Date subtractDays(Date date, int days) {
// Subtract days from a date
// Implementation depends on the language
return new Date(date.getTime() - days * 86400000)
}

private Date addDays(Date date, int days) {
// Add days to a date
// Implementation depends on the language
return new Date(date.getTime() + days * 86400000)
}

private int daysBetween(Date date1, Date date2) {
// Calculate days between two dates
// Implementation depends on the language
return (int)((date2.getTime() - date1.getTime()) / 86400000)
}
}
  • See the Domain Model Overview for more information on how this component fits into the overall domain model.