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)
}
}
Related Components
- See the Domain Model Overview for more information on how this component fits into the overall domain model.