package org.projectbuendia.openmrs.sync;
import org.openmrs.BaseOpenmrsData;
import java.util.Date;
/**
* Represents incremental sync parameters for some type of OpenMRS data.
* <p>
* Most data types in OpenMRS have three timestamp fields that get updated when the record changes -
* dateCreated, dateChanged, and dateVoided. These values aren't usable for incremental paginated
* sync, because our pagination system needs to sort all records based on {@code GREATEST(
* dateCreated, dateChanged, dateVoided)}. It's not currently possible to create indexes on
* functions in MySQL [^1], thus adding this computation to every query means that MySQL would have
* to load every record of the given type for every page fetch. We work around this by creating a
* trigger on the relevant DB table that creates a record in `buendia_[type]_sync_map` with the ID
* of the record and the timestamp of the record update.
* <p>
* The records in `buendia_[type]_sync_map` are loadable by Hibernate, and have a link back to the
* record that they represent. Thus, by performing Hibernate queries on this class, it is possible
* to retrieve pages of records with relative ease.
* <p>
* This is a base class only - we use a different subclass for each data type, which allows us to
* use a different database table for each data type. See `PatientSyncParameters.hbm.xml` and
* {@link PatientSyncParameters} as an implementation example.
* <p>
* This class should be interpreted as read-only - all updates are done by the database triggers.
* The setters only exist so that the object can be instantiated by Hibernate.
* <p>
* [^1]: You can create indexes on generated columns in MySQL 5.7.5+, which is functionally
* equivalent, but the Buendia project won't be on 5.7.5+ at least until Debian is.
* Current MySQL version for Debian: http://distrowatch.com/table.php?distribution=debian
*
*/
public abstract class SyncParameters<T extends BaseOpenmrsData> {
private int itemId;
private Date dateUpdated;
private T item;
private String uuid;
public int getItemId() {
return itemId;
}
public Date getDateUpdated() {
return dateUpdated;
}
public T getItem() {
return item;
}
public String getUuid() {
return uuid;
}
protected void setItemId(int itemId) {
this.itemId = itemId;
}
protected void setDateUpdated(Date dateUpdated) {
this.dateUpdated = dateUpdated;
}
protected void setItem(T item) {
this.item = item;
}
protected void setUuid(String uuid) {
this.uuid = uuid;
}
}