diff --git a/engine/schemas/com.google.android.fhir.db.impl.ResourceDatabase/9.json b/engine/schemas/com.google.android.fhir.db.impl.ResourceDatabase/9.json new file mode 100644 index 0000000000..0478221de1 --- /dev/null +++ b/engine/schemas/com.google.android.fhir.db.impl.ResourceDatabase/9.json @@ -0,0 +1,1024 @@ +{ + "formatVersion": 1, + "database": { + "version": 9, + "identityHash": "79670df517ddfc83ca717c035a38c798", + "entities": [ + { + "tableName": "ResourceEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `resourceUuid` BLOB NOT NULL, `resourceType` TEXT NOT NULL, `resourceId` TEXT NOT NULL, `serializedResource` TEXT NOT NULL, `versionId` TEXT, `lastUpdatedRemote` INTEGER, `lastUpdatedLocal` INTEGER)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "resourceUuid", + "columnName": "resourceUuid", + "affinity": "BLOB", + "notNull": true + }, + { + "fieldPath": "resourceType", + "columnName": "resourceType", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "resourceId", + "columnName": "resourceId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "serializedResource", + "columnName": "serializedResource", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "versionId", + "columnName": "versionId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "lastUpdatedRemote", + "columnName": "lastUpdatedRemote", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "lastUpdatedLocal", + "columnName": "lastUpdatedLocal", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [ + { + "name": "index_ResourceEntity_resourceUuid", + "unique": true, + "columnNames": [ + "resourceUuid" + ], + "orders": [], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_ResourceEntity_resourceUuid` ON `${TABLE_NAME}` (`resourceUuid`)" + }, + { + "name": "index_ResourceEntity_resourceType_resourceId", + "unique": true, + "columnNames": [ + "resourceType", + "resourceId" + ], + "orders": [], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_ResourceEntity_resourceType_resourceId` ON `${TABLE_NAME}` (`resourceType`, `resourceId`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "StringIndexEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `resourceUuid` BLOB NOT NULL, `resourceType` TEXT NOT NULL, `index_name` TEXT NOT NULL, `index_path` TEXT NOT NULL, `index_value` TEXT NOT NULL, FOREIGN KEY(`resourceUuid`) REFERENCES `ResourceEntity`(`resourceUuid`) ON UPDATE NO ACTION ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "resourceUuid", + "columnName": "resourceUuid", + "affinity": "BLOB", + "notNull": true + }, + { + "fieldPath": "resourceType", + "columnName": "resourceType", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "index.name", + "columnName": "index_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "index.path", + "columnName": "index_path", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "index.value", + "columnName": "index_value", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [ + { + "name": "index_StringIndexEntity_resourceType_index_name_index_value", + "unique": false, + "columnNames": [ + "resourceType", + "index_name", + "index_value" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_StringIndexEntity_resourceType_index_name_index_value` ON `${TABLE_NAME}` (`resourceType`, `index_name`, `index_value`)" + }, + { + "name": "index_StringIndexEntity_resourceUuid", + "unique": false, + "columnNames": [ + "resourceUuid" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_StringIndexEntity_resourceUuid` ON `${TABLE_NAME}` (`resourceUuid`)" + } + ], + "foreignKeys": [ + { + "table": "ResourceEntity", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "resourceUuid" + ], + "referencedColumns": [ + "resourceUuid" + ] + } + ] + }, + { + "tableName": "ReferenceIndexEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `resourceUuid` BLOB NOT NULL, `resourceType` TEXT NOT NULL, `index_name` TEXT NOT NULL, `index_path` TEXT NOT NULL, `index_value` TEXT NOT NULL, FOREIGN KEY(`resourceUuid`) REFERENCES `ResourceEntity`(`resourceUuid`) ON UPDATE NO ACTION ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "resourceUuid", + "columnName": "resourceUuid", + "affinity": "BLOB", + "notNull": true + }, + { + "fieldPath": "resourceType", + "columnName": "resourceType", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "index.name", + "columnName": "index_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "index.path", + "columnName": "index_path", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "index.value", + "columnName": "index_value", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [ + { + "name": "index_ReferenceIndexEntity_resourceType_index_name_index_value", + "unique": false, + "columnNames": [ + "resourceType", + "index_name", + "index_value" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_ReferenceIndexEntity_resourceType_index_name_index_value` ON `${TABLE_NAME}` (`resourceType`, `index_name`, `index_value`)" + }, + { + "name": "index_ReferenceIndexEntity_resourceUuid", + "unique": false, + "columnNames": [ + "resourceUuid" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_ReferenceIndexEntity_resourceUuid` ON `${TABLE_NAME}` (`resourceUuid`)" + } + ], + "foreignKeys": [ + { + "table": "ResourceEntity", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "resourceUuid" + ], + "referencedColumns": [ + "resourceUuid" + ] + } + ] + }, + { + "tableName": "TokenIndexEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `resourceUuid` BLOB NOT NULL, `resourceType` TEXT NOT NULL, `index_name` TEXT NOT NULL, `index_path` TEXT NOT NULL, `index_system` TEXT, `index_value` TEXT NOT NULL, FOREIGN KEY(`resourceUuid`) REFERENCES `ResourceEntity`(`resourceUuid`) ON UPDATE NO ACTION ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "resourceUuid", + "columnName": "resourceUuid", + "affinity": "BLOB", + "notNull": true + }, + { + "fieldPath": "resourceType", + "columnName": "resourceType", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "index.name", + "columnName": "index_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "index.path", + "columnName": "index_path", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "index.system", + "columnName": "index_system", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "index.value", + "columnName": "index_value", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [ + { + "name": "index_TokenIndexEntity_resourceType_index_name_index_value_resourceUuid", + "unique": false, + "columnNames": [ + "resourceType", + "index_name", + "index_value", + "resourceUuid" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_TokenIndexEntity_resourceType_index_name_index_value_resourceUuid` ON `${TABLE_NAME}` (`resourceType`, `index_name`, `index_value`, `resourceUuid`)" + }, + { + "name": "index_TokenIndexEntity_resourceUuid", + "unique": false, + "columnNames": [ + "resourceUuid" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_TokenIndexEntity_resourceUuid` ON `${TABLE_NAME}` (`resourceUuid`)" + } + ], + "foreignKeys": [ + { + "table": "ResourceEntity", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "resourceUuid" + ], + "referencedColumns": [ + "resourceUuid" + ] + } + ] + }, + { + "tableName": "QuantityIndexEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `resourceUuid` BLOB NOT NULL, `resourceType` TEXT NOT NULL, `index_name` TEXT NOT NULL, `index_path` TEXT NOT NULL, `index_system` TEXT NOT NULL, `index_code` TEXT NOT NULL, `index_value` REAL NOT NULL, FOREIGN KEY(`resourceUuid`) REFERENCES `ResourceEntity`(`resourceUuid`) ON UPDATE NO ACTION ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "resourceUuid", + "columnName": "resourceUuid", + "affinity": "BLOB", + "notNull": true + }, + { + "fieldPath": "resourceType", + "columnName": "resourceType", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "index.name", + "columnName": "index_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "index.path", + "columnName": "index_path", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "index.system", + "columnName": "index_system", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "index.code", + "columnName": "index_code", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "index.value", + "columnName": "index_value", + "affinity": "REAL", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [ + { + "name": "index_QuantityIndexEntity_resourceType_index_name_index_value_index_code", + "unique": false, + "columnNames": [ + "resourceType", + "index_name", + "index_value", + "index_code" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_QuantityIndexEntity_resourceType_index_name_index_value_index_code` ON `${TABLE_NAME}` (`resourceType`, `index_name`, `index_value`, `index_code`)" + }, + { + "name": "index_QuantityIndexEntity_resourceUuid", + "unique": false, + "columnNames": [ + "resourceUuid" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_QuantityIndexEntity_resourceUuid` ON `${TABLE_NAME}` (`resourceUuid`)" + } + ], + "foreignKeys": [ + { + "table": "ResourceEntity", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "resourceUuid" + ], + "referencedColumns": [ + "resourceUuid" + ] + } + ] + }, + { + "tableName": "UriIndexEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `resourceUuid` BLOB NOT NULL, `resourceType` TEXT NOT NULL, `index_name` TEXT NOT NULL, `index_path` TEXT NOT NULL, `index_value` TEXT NOT NULL, FOREIGN KEY(`resourceUuid`) REFERENCES `ResourceEntity`(`resourceUuid`) ON UPDATE NO ACTION ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "resourceUuid", + "columnName": "resourceUuid", + "affinity": "BLOB", + "notNull": true + }, + { + "fieldPath": "resourceType", + "columnName": "resourceType", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "index.name", + "columnName": "index_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "index.path", + "columnName": "index_path", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "index.value", + "columnName": "index_value", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [ + { + "name": "index_UriIndexEntity_resourceType_index_name_index_value", + "unique": false, + "columnNames": [ + "resourceType", + "index_name", + "index_value" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_UriIndexEntity_resourceType_index_name_index_value` ON `${TABLE_NAME}` (`resourceType`, `index_name`, `index_value`)" + }, + { + "name": "index_UriIndexEntity_resourceUuid", + "unique": false, + "columnNames": [ + "resourceUuid" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_UriIndexEntity_resourceUuid` ON `${TABLE_NAME}` (`resourceUuid`)" + } + ], + "foreignKeys": [ + { + "table": "ResourceEntity", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "resourceUuid" + ], + "referencedColumns": [ + "resourceUuid" + ] + } + ] + }, + { + "tableName": "DateIndexEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `resourceUuid` BLOB NOT NULL, `resourceType` TEXT NOT NULL, `index_name` TEXT NOT NULL, `index_path` TEXT NOT NULL, `index_from` INTEGER NOT NULL, `index_to` INTEGER NOT NULL, FOREIGN KEY(`resourceUuid`) REFERENCES `ResourceEntity`(`resourceUuid`) ON UPDATE NO ACTION ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "resourceUuid", + "columnName": "resourceUuid", + "affinity": "BLOB", + "notNull": true + }, + { + "fieldPath": "resourceType", + "columnName": "resourceType", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "index.name", + "columnName": "index_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "index.path", + "columnName": "index_path", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "index.from", + "columnName": "index_from", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "index.to", + "columnName": "index_to", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [ + { + "name": "index_DateIndexEntity_resourceType_index_name_resourceUuid_index_from_index_to", + "unique": false, + "columnNames": [ + "resourceType", + "index_name", + "resourceUuid", + "index_from", + "index_to" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_DateIndexEntity_resourceType_index_name_resourceUuid_index_from_index_to` ON `${TABLE_NAME}` (`resourceType`, `index_name`, `resourceUuid`, `index_from`, `index_to`)" + }, + { + "name": "index_DateIndexEntity_resourceUuid", + "unique": false, + "columnNames": [ + "resourceUuid" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_DateIndexEntity_resourceUuid` ON `${TABLE_NAME}` (`resourceUuid`)" + } + ], + "foreignKeys": [ + { + "table": "ResourceEntity", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "resourceUuid" + ], + "referencedColumns": [ + "resourceUuid" + ] + } + ] + }, + { + "tableName": "DateTimeIndexEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `resourceUuid` BLOB NOT NULL, `resourceType` TEXT NOT NULL, `index_name` TEXT NOT NULL, `index_path` TEXT NOT NULL, `index_from` INTEGER NOT NULL, `index_to` INTEGER NOT NULL, FOREIGN KEY(`resourceUuid`) REFERENCES `ResourceEntity`(`resourceUuid`) ON UPDATE NO ACTION ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "resourceUuid", + "columnName": "resourceUuid", + "affinity": "BLOB", + "notNull": true + }, + { + "fieldPath": "resourceType", + "columnName": "resourceType", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "index.name", + "columnName": "index_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "index.path", + "columnName": "index_path", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "index.from", + "columnName": "index_from", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "index.to", + "columnName": "index_to", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [ + { + "name": "index_DateTimeIndexEntity_resourceType_index_name_resourceUuid_index_from_index_to", + "unique": false, + "columnNames": [ + "resourceType", + "index_name", + "resourceUuid", + "index_from", + "index_to" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_DateTimeIndexEntity_resourceType_index_name_resourceUuid_index_from_index_to` ON `${TABLE_NAME}` (`resourceType`, `index_name`, `resourceUuid`, `index_from`, `index_to`)" + }, + { + "name": "index_DateTimeIndexEntity_resourceUuid", + "unique": false, + "columnNames": [ + "resourceUuid" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_DateTimeIndexEntity_resourceUuid` ON `${TABLE_NAME}` (`resourceUuid`)" + } + ], + "foreignKeys": [ + { + "table": "ResourceEntity", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "resourceUuid" + ], + "referencedColumns": [ + "resourceUuid" + ] + } + ] + }, + { + "tableName": "NumberIndexEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `resourceUuid` BLOB NOT NULL, `resourceType` TEXT NOT NULL, `index_name` TEXT NOT NULL, `index_path` TEXT NOT NULL, `index_value` REAL NOT NULL, FOREIGN KEY(`resourceUuid`) REFERENCES `ResourceEntity`(`resourceUuid`) ON UPDATE NO ACTION ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "resourceUuid", + "columnName": "resourceUuid", + "affinity": "BLOB", + "notNull": true + }, + { + "fieldPath": "resourceType", + "columnName": "resourceType", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "index.name", + "columnName": "index_name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "index.path", + "columnName": "index_path", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "index.value", + "columnName": "index_value", + "affinity": "REAL", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [ + { + "name": "index_NumberIndexEntity_resourceType_index_name_index_value", + "unique": false, + "columnNames": [ + "resourceType", + "index_name", + "index_value" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_NumberIndexEntity_resourceType_index_name_index_value` ON `${TABLE_NAME}` (`resourceType`, `index_name`, `index_value`)" + }, + { + "name": "index_NumberIndexEntity_resourceUuid", + "unique": false, + "columnNames": [ + "resourceUuid" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_NumberIndexEntity_resourceUuid` ON `${TABLE_NAME}` (`resourceUuid`)" + } + ], + "foreignKeys": [ + { + "table": "ResourceEntity", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "resourceUuid" + ], + "referencedColumns": [ + "resourceUuid" + ] + } + ] + }, + { + "tableName": "LocalChangeEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `resourceType` TEXT NOT NULL, `resourceId` TEXT NOT NULL, `resourceUuid` BLOB NOT NULL, `timestamp` INTEGER NOT NULL, `type` INTEGER NOT NULL, `payload` TEXT NOT NULL, `versionId` TEXT)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "resourceType", + "columnName": "resourceType", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "resourceId", + "columnName": "resourceId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "resourceUuid", + "columnName": "resourceUuid", + "affinity": "BLOB", + "notNull": true + }, + { + "fieldPath": "timestamp", + "columnName": "timestamp", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "payload", + "columnName": "payload", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "versionId", + "columnName": "versionId", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [ + { + "name": "index_LocalChangeEntity_resourceType_resourceId", + "unique": false, + "columnNames": [ + "resourceType", + "resourceId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_LocalChangeEntity_resourceType_resourceId` ON `${TABLE_NAME}` (`resourceType`, `resourceId`)" + }, + { + "name": "index_LocalChangeEntity_resourceUuid", + "unique": false, + "columnNames": [ + "resourceUuid" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_LocalChangeEntity_resourceUuid` ON `${TABLE_NAME}` (`resourceUuid`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "PositionIndexEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `resourceUuid` BLOB NOT NULL, `resourceType` TEXT NOT NULL, `index_latitude` REAL NOT NULL, `index_longitude` REAL NOT NULL, FOREIGN KEY(`resourceUuid`) REFERENCES `ResourceEntity`(`resourceUuid`) ON UPDATE NO ACTION ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "resourceUuid", + "columnName": "resourceUuid", + "affinity": "BLOB", + "notNull": true + }, + { + "fieldPath": "resourceType", + "columnName": "resourceType", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "index.latitude", + "columnName": "index_latitude", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "index.longitude", + "columnName": "index_longitude", + "affinity": "REAL", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [ + { + "name": "index_PositionIndexEntity_resourceType_index_latitude_index_longitude", + "unique": false, + "columnNames": [ + "resourceType", + "index_latitude", + "index_longitude" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_PositionIndexEntity_resourceType_index_latitude_index_longitude` ON `${TABLE_NAME}` (`resourceType`, `index_latitude`, `index_longitude`)" + }, + { + "name": "index_PositionIndexEntity_resourceUuid", + "unique": false, + "columnNames": [ + "resourceUuid" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_PositionIndexEntity_resourceUuid` ON `${TABLE_NAME}` (`resourceUuid`)" + } + ], + "foreignKeys": [ + { + "table": "ResourceEntity", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "resourceUuid" + ], + "referencedColumns": [ + "resourceUuid" + ] + } + ] + }, + { + "tableName": "LocalChangeResourceReferenceEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `localChangeId` INTEGER NOT NULL, `resourceReferenceValue` TEXT NOT NULL, `resourceReferencePath` TEXT, FOREIGN KEY(`localChangeId`) REFERENCES `LocalChangeEntity`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "localChangeId", + "columnName": "localChangeId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "resourceReferenceValue", + "columnName": "resourceReferenceValue", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "resourceReferencePath", + "columnName": "resourceReferencePath", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [ + { + "name": "index_LocalChangeResourceReferenceEntity_resourceReferenceValue", + "unique": false, + "columnNames": [ + "resourceReferenceValue" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_LocalChangeResourceReferenceEntity_resourceReferenceValue` ON `${TABLE_NAME}` (`resourceReferenceValue`)" + }, + { + "name": "index_LocalChangeResourceReferenceEntity_localChangeId", + "unique": false, + "columnNames": [ + "localChangeId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_LocalChangeResourceReferenceEntity_localChangeId` ON `${TABLE_NAME}` (`localChangeId`)" + } + ], + "foreignKeys": [ + { + "table": "LocalChangeEntity", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "localChangeId" + ], + "referencedColumns": [ + "id" + ] + } + ] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '79670df517ddfc83ca717c035a38c798')" + ] + } +} \ No newline at end of file diff --git a/engine/src/androidTest/java/com/google/android/fhir/db/impl/ResourceDatabaseMigrationTest.kt b/engine/src/androidTest/java/com/google/android/fhir/db/impl/ResourceDatabaseMigrationTest.kt index 56487f5ecb..01b9312cf2 100644 --- a/engine/src/androidTest/java/com/google/android/fhir/db/impl/ResourceDatabaseMigrationTest.kt +++ b/engine/src/androidTest/java/com/google/android/fhir/db/impl/ResourceDatabaseMigrationTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2023-2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -369,6 +369,55 @@ class ResourceDatabaseMigrationTest { assertThat(localChangeReferences[localChange2Id]!!).containsExactly("Practitioner/345") } + @Test + fun migrate8To9_should_execute_with_no_exception(): Unit = runBlocking { + val taskId = "bed-net-001" + val taskResourceUuid = "8593abf6-b8dd-44d7-a35f-1c8843bc2c45" + val date = Date() + val bedNetTask = + Task() + .apply { + id = taskId + status = Task.TaskStatus.READY + meta.lastUpdated = date + } + .let { iParser.encodeResourceToString(it) } + + helper.createDatabase(DB_NAME, 8).apply { + execSQL( + "INSERT INTO ResourceEntity (resourceUuid, resourceType, resourceId, serializedResource, lastUpdatedLocal) VALUES ('$taskResourceUuid', 'Task', '$taskId', '$bedNetTask', '${DbTypeConverters.instantToLong(date.toInstant())}' );", + ) + execSQL( + "INSERT INTO TokenIndexEntity (resourceUuid, resourceType, index_name, index_path, index_system, index_value) VALUES ('$taskResourceUuid', 'Task', 'status', 'Task.status', 'http://hl7.org/fhir/task-status', 'ready');", + ) + close() + } + + val migratedDatabase = helper.runMigrationsAndValidate(DB_NAME, 9, true, Migration_8_9) + + val retrievedTask: String? + migratedDatabase.let { database -> + database + .query( + """ + SELECT a.serializedResource FROM ResourceEntity a + WHERE a.resourceType = 'Task' + AND a.resourceUuid IN (SELECT resourceUuid FROM TokenIndexEntity + WHERE resourceType = 'Task' AND index_name = 'status' AND index_value = 'ready' + AND IFNULL(index_system, '') = 'http://hl7.org/fhir/task-status') + """ + .trimIndent(), + ) + .let { + it.moveToFirst() + retrievedTask = it.getString(0) + } + } + migratedDatabase.close() + + assertThat(retrievedTask).isEqualTo(bedNetTask) + } + companion object { const val DB_NAME = "migration_tests.db" } diff --git a/engine/src/main/java/com/google/android/fhir/db/impl/DatabaseImpl.kt b/engine/src/main/java/com/google/android/fhir/db/impl/DatabaseImpl.kt index 40de8d320b..a9c27fdc4c 100644 --- a/engine/src/main/java/com/google/android/fhir/db/impl/DatabaseImpl.kt +++ b/engine/src/main/java/com/google/android/fhir/db/impl/DatabaseImpl.kt @@ -116,6 +116,7 @@ internal class DatabaseImpl( MIGRATION_5_6, MIGRATION_6_7, MIGRATION_7_8, + Migration_8_9, ) } .build() diff --git a/engine/src/main/java/com/google/android/fhir/db/impl/ResourceDatabase.kt b/engine/src/main/java/com/google/android/fhir/db/impl/ResourceDatabase.kt index 158bb4b146..8b6c6a483d 100644 --- a/engine/src/main/java/com/google/android/fhir/db/impl/ResourceDatabase.kt +++ b/engine/src/main/java/com/google/android/fhir/db/impl/ResourceDatabase.kt @@ -54,7 +54,7 @@ import org.json.JSONObject PositionIndexEntity::class, LocalChangeResourceReferenceEntity::class, ], - version = 8, + version = 9, exportSchema = true, ) @TypeConverters(DbTypeConverters::class) @@ -208,3 +208,21 @@ internal val MIGRATION_7_8 = } } } + +internal val Migration_8_9 = + object : Migration(8, 9) { + override fun migrate(database: SupportSQLiteDatabase) { + database.beginTransaction() + try { + database.execSQL( + "DROP INDEX IF EXISTS `index_TokenIndexEntity_resourceType_index_name_index_system_index_value_resourceUuid`;", + ) + database.execSQL( + "CREATE INDEX IF NOT EXISTS `index_TokenIndexEntity_resourceType_index_name_index_value_resourceUuid` ON `TokenIndexEntity` (`resourceType`, `index_name`, `index_value`, `resourceUuid`);", + ) + database.setTransactionSuccessful() + } finally { + database.endTransaction() + } + } + } diff --git a/engine/src/main/java/com/google/android/fhir/db/impl/entities/TokenIndexEntity.kt b/engine/src/main/java/com/google/android/fhir/db/impl/entities/TokenIndexEntity.kt index c08d360f5d..2c495ab146 100644 --- a/engine/src/main/java/com/google/android/fhir/db/impl/entities/TokenIndexEntity.kt +++ b/engine/src/main/java/com/google/android/fhir/db/impl/entities/TokenIndexEntity.kt @@ -1,5 +1,5 @@ /* - * Copyright 2023 Google LLC + * Copyright 2023-2024 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,7 +28,7 @@ import org.hl7.fhir.r4.model.ResourceType @Entity( indices = [ - Index(value = ["resourceType", "index_name", "index_system", "index_value", "resourceUuid"]), + Index(value = ["resourceType", "index_name", "index_value", "resourceUuid"]), // Keep this index for faster foreign lookup Index(value = ["resourceUuid"]), ],