diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/filters/FilterHistoryRepository.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/filters/FilterHistoryRepository.kt new file mode 100644 index 000000000000..858fa6d5d833 --- /dev/null +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/filters/FilterHistoryRepository.kt @@ -0,0 +1,87 @@ +package com.woocommerce.android.ui.filters + +import android.os.Parcelable +import com.woocommerce.android.tools.SelectedSite +import dagger.Reusable +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map +import kotlinx.parcelize.Parcelize +import org.wordpress.android.fluxc.model.LocalOrRemoteId.LocalId +import org.wordpress.android.fluxc.persistence.dao.FilterHistoryDao +import org.wordpress.android.fluxc.persistence.entity.FilterHistoryEntity +import org.wordpress.android.fluxc.utils.CurrentTimeProvider +import javax.inject.Inject + +/** + * Per-site store for "filter history" — the previously applied filter selections on the order and + * product lists, gated by [com.woocommerce.android.util.FeatureFlag.FILTER_HISTORY]. + * + * History is unlimited, deduped and newest-first (matching iOS): [save] upserts by [SavedFilter.payload], + * so re-saving an identical selection bumps it to the top instead of creating a duplicate. + * + * Callers own the [SavedFilter.payload] contract: it must be a canonical, normalized serialization of + * the active (non-empty) selection so that logically-identical filters dedup reliably across app + * versions. The per-surface encoders/decoders live with the order and product filter screens. + */ +@Reusable +class FilterHistoryRepository @Inject constructor( + private val filterHistoryDao: FilterHistoryDao, + private val selectedSite: SelectedSite, + private val currentTimeProvider: CurrentTimeProvider +) { + fun observeHistory(type: FilterHistoryType): Flow> = + filterHistoryDao.observeForSite(currentSiteId(), type.name) + .map { entities -> entities.map { it.toSavedFilter() } } + + suspend fun save( + type: FilterHistoryType, + payload: String, + readableString: String + ) { + filterHistoryDao.insertOrReplace( + FilterHistoryEntity( + localSiteId = currentSiteId(), + filterType = type.name, + payload = payload, + readableString = readableString, + dateModified = currentTimeProvider.currentDate().time + ) + ) + } + + suspend fun remove(type: FilterHistoryType, filter: SavedFilter) { + filterHistoryDao.delete(currentSiteId(), type.name, filter.payload) + } + + suspend fun clear(type: FilterHistoryType) { + filterHistoryDao.clear(currentSiteId(), type.name) + } + + private fun currentSiteId() = LocalId(selectedSite.get().id) + + private fun FilterHistoryEntity.toSavedFilter() = SavedFilter( + readableString = readableString, + payload = payload + ) +} + +/** + * Which list a filter history entry belongs to. Persisted as the entity's `filterType` column. + */ +enum class FilterHistoryType { + ORDERS, + PRODUCTS +} + +/** + * A single persisted filter history entry. + * + * @param readableString human-readable summary of the filter, shown in the history list. + * @param payload canonical serialization of the selection; also the identity used to + * [FilterHistoryRepository.remove] a specific entry (unique per site and filter type). + */ +@Parcelize +data class SavedFilter( + val readableString: String, + val payload: String +) : Parcelable diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/util/FeatureFlag.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/util/FeatureFlag.kt index 8438d705d97f..04d3636e9eb5 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/util/FeatureFlag.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/util/FeatureFlag.kt @@ -41,4 +41,5 @@ enum class FeatureFlag( AI_SUPPORT_CHAT("ai_support_chat"), SMARTER_NOTIFICATIONS("smarter_notifications", localValue = PackageUtils.isDebugBuild()), QR_LOGIN("woo_qr_code_login"), + FILTER_HISTORY("woo_filter_history", localValue = PackageUtils.isDebugBuild()), } diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/support/MobileStatusProviderTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/support/MobileStatusProviderTest.kt index 45a996920a0a..1abdd0695b6b 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/support/MobileStatusProviderTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/support/MobileStatusProviderTest.kt @@ -628,6 +628,7 @@ class MobileStatusProviderTest : BaseUnitTest() { smarter_notifications: true (remote) wc_shipping_banner: true (remote) woo_app_passwords_for_jetpack_sites: true (remote) + woo_filter_history: true (remote) woo_mobile_ai_assistant: true (remote) woo_notification_1d_after_free_trial_expires: true (remote) woo_notification_1d_before_free_trial_expires: true (remote) diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/filters/FilterHistoryRepositoryTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/filters/FilterHistoryRepositoryTest.kt new file mode 100644 index 000000000000..4a9fad1a8ed5 --- /dev/null +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/filters/FilterHistoryRepositoryTest.kt @@ -0,0 +1,90 @@ +package com.woocommerce.android.ui.filters + +import com.woocommerce.android.tools.SelectedSite +import com.woocommerce.android.viewmodel.BaseUnitTest +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.flowOf +import org.assertj.core.api.Assertions.assertThat +import org.junit.Test +import org.mockito.kotlin.doReturn +import org.mockito.kotlin.mock +import org.mockito.kotlin.verify +import org.mockito.kotlin.whenever +import org.wordpress.android.fluxc.model.LocalOrRemoteId.LocalId +import org.wordpress.android.fluxc.model.SiteModel +import org.wordpress.android.fluxc.persistence.dao.FilterHistoryDao +import org.wordpress.android.fluxc.persistence.entity.FilterHistoryEntity +import org.wordpress.android.fluxc.utils.CurrentTimeProvider +import java.util.Date + +@OptIn(ExperimentalCoroutinesApi::class) +class FilterHistoryRepositoryTest : BaseUnitTest() { + private val filterHistoryDao: FilterHistoryDao = mock() + private val selectedSite: SelectedSite = mock { + on { get() } doReturn SiteModel().apply { id = SITE_ID } + } + private val currentTimeProvider: CurrentTimeProvider = mock { + on { currentDate() } doReturn Date(NOW) + } + + private val sut = FilterHistoryRepository(filterHistoryDao, selectedSite, currentTimeProvider) + + @Test + fun `given stored entries for the current site, when observing, then they are mapped to saved filters`() = + testBlocking { + whenever(filterHistoryDao.observeForSite(LocalId(SITE_ID), "ORDERS")).thenReturn( + flowOf( + listOf( + FilterHistoryEntity( + localSiteId = LocalId(SITE_ID), + filterType = "ORDERS", + payload = "payload", + readableString = "Processing", + dateModified = 10 + ) + ) + ) + ) + + val result = sut.observeHistory(FilterHistoryType.ORDERS).first() + + assertThat(result).isEqualTo( + listOf(SavedFilter(readableString = "Processing", payload = "payload")) + ) + } + + @Test + fun `when saving, then it is inserted for the current site with the current time`() = testBlocking { + sut.save(FilterHistoryType.ORDERS, payload = "payload", readableString = "Processing") + + verify(filterHistoryDao).insertOrReplace( + FilterHistoryEntity( + localSiteId = LocalId(SITE_ID), + filterType = "ORDERS", + payload = "payload", + readableString = "Processing", + dateModified = NOW + ) + ) + } + + @Test + fun `when removing a filter, then it is deleted by its site, type and payload`() = testBlocking { + sut.remove(FilterHistoryType.ORDERS, SavedFilter(readableString = "Processing", payload = "payload")) + + verify(filterHistoryDao).delete(LocalId(SITE_ID), "ORDERS", "payload") + } + + @Test + fun `when clearing, then the current site and type are cleared`() = testBlocking { + sut.clear(FilterHistoryType.PRODUCTS) + + verify(filterHistoryDao).clear(LocalId(SITE_ID), "PRODUCTS") + } + + private companion object { + const val SITE_ID = 123 + const val NOW = 1_000L + } +} diff --git a/libs/fluxc-plugin/schemas/org.wordpress.android.fluxc.persistence.WCAndroidDatabase/92.json b/libs/fluxc-plugin/schemas/org.wordpress.android.fluxc.persistence.WCAndroidDatabase/92.json new file mode 100644 index 000000000000..1f19c7751a7f --- /dev/null +++ b/libs/fluxc-plugin/schemas/org.wordpress.android.fluxc.persistence.WCAndroidDatabase/92.json @@ -0,0 +1,4535 @@ +{ + "formatVersion": 1, + "database": { + "version": 92, + "identityHash": "5a184bbefdc60bba2154a2d2a4f7bda1", + "entities": [ + { + "tableName": "AddonEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`addonLocalId` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `globalGroupLocalId` INTEGER, `productRemoteId` INTEGER, `localSiteId` INTEGER, `type` TEXT NOT NULL, `display` TEXT, `name` TEXT NOT NULL, `titleFormat` TEXT NOT NULL, `description` TEXT, `required` INTEGER NOT NULL, `position` INTEGER NOT NULL, `restrictions` TEXT, `priceType` TEXT, `price` TEXT, `min` INTEGER, `max` INTEGER, FOREIGN KEY(`globalGroupLocalId`) REFERENCES `GlobalAddonGroupEntity`(`globalGroupLocalId`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "addonLocalId", + "columnName": "addonLocalId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "globalGroupLocalId", + "columnName": "globalGroupLocalId", + "affinity": "INTEGER" + }, + { + "fieldPath": "productRemoteId", + "columnName": "productRemoteId", + "affinity": "INTEGER" + }, + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER" + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "display", + "columnName": "display", + "affinity": "TEXT" + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "titleFormat", + "columnName": "titleFormat", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT" + }, + { + "fieldPath": "required", + "columnName": "required", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "position", + "columnName": "position", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "restrictions", + "columnName": "restrictions", + "affinity": "TEXT" + }, + { + "fieldPath": "priceType", + "columnName": "priceType", + "affinity": "TEXT" + }, + { + "fieldPath": "price", + "columnName": "price", + "affinity": "TEXT" + }, + { + "fieldPath": "min", + "columnName": "min", + "affinity": "INTEGER" + }, + { + "fieldPath": "max", + "columnName": "max", + "affinity": "INTEGER" + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "addonLocalId" + ] + }, + "indices": [ + { + "name": "index_AddonEntity_globalGroupLocalId", + "unique": false, + "columnNames": [ + "globalGroupLocalId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_AddonEntity_globalGroupLocalId` ON `${TABLE_NAME}` (`globalGroupLocalId`)" + } + ], + "foreignKeys": [ + { + "table": "GlobalAddonGroupEntity", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "globalGroupLocalId" + ], + "referencedColumns": [ + "globalGroupLocalId" + ] + } + ] + }, + { + "tableName": "AddonOptionEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`addonOptionLocalId` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `addonLocalId` INTEGER NOT NULL, `priceType` TEXT NOT NULL, `label` TEXT, `price` TEXT, `image` TEXT, FOREIGN KEY(`addonLocalId`) REFERENCES `AddonEntity`(`addonLocalId`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "addonOptionLocalId", + "columnName": "addonOptionLocalId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "addonLocalId", + "columnName": "addonLocalId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "priceType", + "columnName": "priceType", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "label", + "columnName": "label", + "affinity": "TEXT" + }, + { + "fieldPath": "price", + "columnName": "price", + "affinity": "TEXT" + }, + { + "fieldPath": "image", + "columnName": "image", + "affinity": "TEXT" + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "addonOptionLocalId" + ] + }, + "indices": [ + { + "name": "index_AddonOptionEntity_addonLocalId", + "unique": false, + "columnNames": [ + "addonLocalId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_AddonOptionEntity_addonLocalId` ON `${TABLE_NAME}` (`addonLocalId`)" + } + ], + "foreignKeys": [ + { + "table": "AddonEntity", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "addonLocalId" + ], + "referencedColumns": [ + "addonLocalId" + ] + } + ] + }, + { + "tableName": "Coupons", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `localSiteId` INTEGER NOT NULL, `code` TEXT, `amount` TEXT, `dateCreated` TEXT, `dateCreatedGmt` TEXT, `dateModified` TEXT, `dateModifiedGmt` TEXT, `discountType` TEXT, `description` TEXT, `dateExpires` TEXT, `dateExpiresGmt` TEXT, `usageCount` INTEGER, `isForIndividualUse` INTEGER, `usageLimit` INTEGER, `usageLimitPerUser` INTEGER, `limitUsageToXItems` INTEGER, `isShippingFree` INTEGER, `areSaleItemsExcluded` INTEGER, `minimumAmount` TEXT, `maximumAmount` TEXT, `includedProductIds` TEXT, `excludedProductIds` TEXT, `includedCategoryIds` TEXT, `excludedCategoryIds` TEXT, PRIMARY KEY(`id`, `localSiteId`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "code", + "columnName": "code", + "affinity": "TEXT" + }, + { + "fieldPath": "amount", + "columnName": "amount", + "affinity": "TEXT" + }, + { + "fieldPath": "dateCreated", + "columnName": "dateCreated", + "affinity": "TEXT" + }, + { + "fieldPath": "dateCreatedGmt", + "columnName": "dateCreatedGmt", + "affinity": "TEXT" + }, + { + "fieldPath": "dateModified", + "columnName": "dateModified", + "affinity": "TEXT" + }, + { + "fieldPath": "dateModifiedGmt", + "columnName": "dateModifiedGmt", + "affinity": "TEXT" + }, + { + "fieldPath": "discountType", + "columnName": "discountType", + "affinity": "TEXT" + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT" + }, + { + "fieldPath": "dateExpires", + "columnName": "dateExpires", + "affinity": "TEXT" + }, + { + "fieldPath": "dateExpiresGmt", + "columnName": "dateExpiresGmt", + "affinity": "TEXT" + }, + { + "fieldPath": "usageCount", + "columnName": "usageCount", + "affinity": "INTEGER" + }, + { + "fieldPath": "isForIndividualUse", + "columnName": "isForIndividualUse", + "affinity": "INTEGER" + }, + { + "fieldPath": "usageLimit", + "columnName": "usageLimit", + "affinity": "INTEGER" + }, + { + "fieldPath": "usageLimitPerUser", + "columnName": "usageLimitPerUser", + "affinity": "INTEGER" + }, + { + "fieldPath": "limitUsageToXItems", + "columnName": "limitUsageToXItems", + "affinity": "INTEGER" + }, + { + "fieldPath": "isShippingFree", + "columnName": "isShippingFree", + "affinity": "INTEGER" + }, + { + "fieldPath": "areSaleItemsExcluded", + "columnName": "areSaleItemsExcluded", + "affinity": "INTEGER" + }, + { + "fieldPath": "minimumAmount", + "columnName": "minimumAmount", + "affinity": "TEXT" + }, + { + "fieldPath": "maximumAmount", + "columnName": "maximumAmount", + "affinity": "TEXT" + }, + { + "fieldPath": "includedProductIds", + "columnName": "includedProductIds", + "affinity": "TEXT" + }, + { + "fieldPath": "excludedProductIds", + "columnName": "excludedProductIds", + "affinity": "TEXT" + }, + { + "fieldPath": "includedCategoryIds", + "columnName": "includedCategoryIds", + "affinity": "TEXT" + }, + { + "fieldPath": "excludedCategoryIds", + "columnName": "excludedCategoryIds", + "affinity": "TEXT" + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "id", + "localSiteId" + ] + } + }, + { + "tableName": "CouponEmails", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`couponId` INTEGER NOT NULL, `localSiteId` INTEGER NOT NULL, `email` TEXT NOT NULL, PRIMARY KEY(`couponId`, `localSiteId`, `email`), FOREIGN KEY(`couponId`, `localSiteId`) REFERENCES `Coupons`(`id`, `localSiteId`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "couponId", + "columnName": "couponId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "email", + "columnName": "email", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "couponId", + "localSiteId", + "email" + ] + }, + "foreignKeys": [ + { + "table": "Coupons", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "couponId", + "localSiteId" + ], + "referencedColumns": [ + "id", + "localSiteId" + ] + } + ] + }, + { + "tableName": "GlobalAddonGroupEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`globalGroupLocalId` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `restrictedCategoriesIds` TEXT NOT NULL, `localSiteId` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "globalGroupLocalId", + "columnName": "globalGroupLocalId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "restrictedCategoriesIds", + "columnName": "restrictedCategoriesIds", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "globalGroupLocalId" + ] + } + }, + { + "tableName": "OrderNotes", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`localSiteId` INTEGER NOT NULL, `noteId` INTEGER NOT NULL, `orderId` INTEGER NOT NULL, `dateCreated` TEXT, `note` TEXT, `author` TEXT, `isSystemNote` INTEGER NOT NULL, `isCustomerNote` INTEGER NOT NULL, PRIMARY KEY(`localSiteId`, `noteId`))", + "fields": [ + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "noteId", + "columnName": "noteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "orderId", + "columnName": "orderId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "dateCreated", + "columnName": "dateCreated", + "affinity": "TEXT" + }, + { + "fieldPath": "note", + "columnName": "note", + "affinity": "TEXT" + }, + { + "fieldPath": "author", + "columnName": "author", + "affinity": "TEXT" + }, + { + "fieldPath": "isSystemNote", + "columnName": "isSystemNote", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isCustomerNote", + "columnName": "isCustomerNote", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "localSiteId", + "noteId" + ] + } + }, + { + "tableName": "OrderEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`localSiteId` INTEGER NOT NULL, `orderId` INTEGER NOT NULL, `number` TEXT NOT NULL, `status` TEXT NOT NULL, `currency` TEXT NOT NULL, `orderKey` TEXT NOT NULL, `dateCreated` TEXT NOT NULL, `dateModified` TEXT NOT NULL, `total` TEXT NOT NULL, `totalTax` TEXT NOT NULL, `shippingTotal` TEXT NOT NULL, `paymentMethod` TEXT NOT NULL, `paymentMethodTitle` TEXT NOT NULL, `datePaid` TEXT NOT NULL, `pricesIncludeTax` INTEGER NOT NULL, `customerNote` TEXT NOT NULL, `discountTotal` TEXT NOT NULL, `discountCodes` TEXT NOT NULL, `refundTotal` TEXT NOT NULL, `customerId` INTEGER NOT NULL DEFAULT 0, `billingFirstName` TEXT NOT NULL, `billingLastName` TEXT NOT NULL, `billingCompany` TEXT NOT NULL, `billingAddress1` TEXT NOT NULL, `billingAddress2` TEXT NOT NULL, `billingCity` TEXT NOT NULL, `billingState` TEXT NOT NULL, `billingPostcode` TEXT NOT NULL, `billingCountry` TEXT NOT NULL, `billingEmail` TEXT NOT NULL, `billingPhone` TEXT NOT NULL, `shippingFirstName` TEXT NOT NULL, `shippingLastName` TEXT NOT NULL, `shippingCompany` TEXT NOT NULL, `shippingAddress1` TEXT NOT NULL, `shippingAddress2` TEXT NOT NULL, `shippingCity` TEXT NOT NULL, `shippingState` TEXT NOT NULL, `shippingPostcode` TEXT NOT NULL, `shippingCountry` TEXT NOT NULL, `shippingPhone` TEXT NOT NULL, `lineItems` TEXT NOT NULL, `shippingLines` TEXT NOT NULL, `feeLines` TEXT NOT NULL, `taxLines` TEXT NOT NULL, `couponLines` TEXT NOT NULL DEFAULT '', `giftCards` TEXT NOT NULL DEFAULT '', `metaData` TEXT NOT NULL, `paymentUrl` TEXT NOT NULL DEFAULT '', `isEditable` INTEGER NOT NULL DEFAULT 1, `needsPayment` INTEGER, `needsProcessing` INTEGER, `giftCardCode` TEXT NOT NULL DEFAULT '', `giftCardAmount` TEXT NOT NULL DEFAULT '', `shippingTax` TEXT NOT NULL DEFAULT '', `createdVia` TEXT NOT NULL DEFAULT '', PRIMARY KEY(`localSiteId`, `orderId`))", + "fields": [ + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "orderId", + "columnName": "orderId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "number", + "columnName": "number", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "status", + "columnName": "status", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "currency", + "columnName": "currency", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "orderKey", + "columnName": "orderKey", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "dateCreated", + "columnName": "dateCreated", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "dateModified", + "columnName": "dateModified", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "total", + "columnName": "total", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "totalTax", + "columnName": "totalTax", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "shippingTotal", + "columnName": "shippingTotal", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "paymentMethod", + "columnName": "paymentMethod", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "paymentMethodTitle", + "columnName": "paymentMethodTitle", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "datePaid", + "columnName": "datePaid", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "pricesIncludeTax", + "columnName": "pricesIncludeTax", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "customerNote", + "columnName": "customerNote", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "discountTotal", + "columnName": "discountTotal", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "discountCodes", + "columnName": "discountCodes", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "refundTotal", + "columnName": "refundTotal", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "customerId", + "columnName": "customerId", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "billingFirstName", + "columnName": "billingFirstName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "billingLastName", + "columnName": "billingLastName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "billingCompany", + "columnName": "billingCompany", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "billingAddress1", + "columnName": "billingAddress1", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "billingAddress2", + "columnName": "billingAddress2", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "billingCity", + "columnName": "billingCity", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "billingState", + "columnName": "billingState", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "billingPostcode", + "columnName": "billingPostcode", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "billingCountry", + "columnName": "billingCountry", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "billingEmail", + "columnName": "billingEmail", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "billingPhone", + "columnName": "billingPhone", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "shippingFirstName", + "columnName": "shippingFirstName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "shippingLastName", + "columnName": "shippingLastName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "shippingCompany", + "columnName": "shippingCompany", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "shippingAddress1", + "columnName": "shippingAddress1", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "shippingAddress2", + "columnName": "shippingAddress2", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "shippingCity", + "columnName": "shippingCity", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "shippingState", + "columnName": "shippingState", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "shippingPostcode", + "columnName": "shippingPostcode", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "shippingCountry", + "columnName": "shippingCountry", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "shippingPhone", + "columnName": "shippingPhone", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "lineItems", + "columnName": "lineItems", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "shippingLines", + "columnName": "shippingLines", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "feeLines", + "columnName": "feeLines", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "taxLines", + "columnName": "taxLines", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "couponLines", + "columnName": "couponLines", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "giftCards", + "columnName": "giftCards", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "metaData", + "columnName": "metaData", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "paymentUrl", + "columnName": "paymentUrl", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "isEditable", + "columnName": "isEditable", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "1" + }, + { + "fieldPath": "needsPayment", + "columnName": "needsPayment", + "affinity": "INTEGER" + }, + { + "fieldPath": "needsProcessing", + "columnName": "needsProcessing", + "affinity": "INTEGER" + }, + { + "fieldPath": "giftCardCode", + "columnName": "giftCardCode", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "giftCardAmount", + "columnName": "giftCardAmount", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "shippingTax", + "columnName": "shippingTax", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "createdVia", + "columnName": "createdVia", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "localSiteId", + "orderId" + ] + }, + "indices": [ + { + "name": "index_OrderEntity_localSiteId_orderId", + "unique": false, + "columnNames": [ + "localSiteId", + "orderId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_OrderEntity_localSiteId_orderId` ON `${TABLE_NAME}` (`localSiteId`, `orderId`)" + } + ] + }, + { + "tableName": "RefundEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`siteId` INTEGER NOT NULL, `orderId` INTEGER NOT NULL, `refundId` INTEGER NOT NULL, `data` TEXT NOT NULL, PRIMARY KEY(`siteId`, `orderId`, `refundId`))", + "fields": [ + { + "fieldPath": "siteId", + "columnName": "siteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "orderId", + "columnName": "orderId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "refundId", + "columnName": "refundId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "data", + "columnName": "data", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "siteId", + "orderId", + "refundId" + ] + } + }, + { + "tableName": "MetaData", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`localSiteId` INTEGER NOT NULL, `id` INTEGER NOT NULL, `parentItemId` INTEGER NOT NULL, `key` TEXT NOT NULL, `value` TEXT NOT NULL, `type` TEXT NOT NULL DEFAULT 'ORDER', PRIMARY KEY(`localSiteId`, `parentItemId`, `id`))", + "fields": [ + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "parentItemId", + "columnName": "parentItemId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "key", + "columnName": "key", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "value", + "columnName": "value", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "'ORDER'" + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "localSiteId", + "parentItemId", + "id" + ] + } + }, + { + "tableName": "InboxNotes", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`localId` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `remoteId` INTEGER NOT NULL, `localSiteId` INTEGER NOT NULL, `name` TEXT NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `dateCreated` TEXT NOT NULL, `status` TEXT NOT NULL, `source` TEXT, `type` TEXT, `dateReminder` TEXT)", + "fields": [ + { + "fieldPath": "localId", + "columnName": "localId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "remoteId", + "columnName": "remoteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "content", + "columnName": "content", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "dateCreated", + "columnName": "dateCreated", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "status", + "columnName": "status", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "source", + "columnName": "source", + "affinity": "TEXT" + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "TEXT" + }, + { + "fieldPath": "dateReminder", + "columnName": "dateReminder", + "affinity": "TEXT" + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "localId" + ] + }, + "indices": [ + { + "name": "index_InboxNotes_remoteId_localSiteId", + "unique": true, + "columnNames": [ + "remoteId", + "localSiteId" + ], + "orders": [], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_InboxNotes_remoteId_localSiteId` ON `${TABLE_NAME}` (`remoteId`, `localSiteId`)" + } + ] + }, + { + "tableName": "InboxNoteActions", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`remoteId` INTEGER NOT NULL, `inboxNoteLocalId` INTEGER NOT NULL, `localSiteId` INTEGER NOT NULL, `name` TEXT NOT NULL, `label` TEXT NOT NULL, `url` TEXT NOT NULL, `query` TEXT, `status` TEXT, `primary` INTEGER NOT NULL, `actionedText` TEXT, PRIMARY KEY(`remoteId`, `inboxNoteLocalId`), FOREIGN KEY(`inboxNoteLocalId`) REFERENCES `InboxNotes`(`localId`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "remoteId", + "columnName": "remoteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "inboxNoteLocalId", + "columnName": "inboxNoteLocalId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "label", + "columnName": "label", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "query", + "columnName": "query", + "affinity": "TEXT" + }, + { + "fieldPath": "status", + "columnName": "status", + "affinity": "TEXT" + }, + { + "fieldPath": "primary", + "columnName": "primary", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "actionedText", + "columnName": "actionedText", + "affinity": "TEXT" + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "remoteId", + "inboxNoteLocalId" + ] + }, + "indices": [ + { + "name": "index_InboxNoteActions_inboxNoteLocalId", + "unique": false, + "columnNames": [ + "inboxNoteLocalId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_InboxNoteActions_inboxNoteLocalId` ON `${TABLE_NAME}` (`inboxNoteLocalId`)" + } + ], + "foreignKeys": [ + { + "table": "InboxNotes", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "inboxNoteLocalId" + ], + "referencedColumns": [ + "localId" + ] + } + ] + }, + { + "tableName": "TopPerformerProducts", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`localSiteId` INTEGER NOT NULL, `datePeriod` TEXT NOT NULL, `productId` INTEGER NOT NULL, `name` TEXT NOT NULL, `imageUrl` TEXT, `quantity` INTEGER NOT NULL, `currency` TEXT NOT NULL, `total` REAL NOT NULL, `millisSinceLastUpdated` INTEGER NOT NULL, PRIMARY KEY(`datePeriod`, `productId`, `localSiteId`))", + "fields": [ + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "datePeriod", + "columnName": "datePeriod", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "productId", + "columnName": "productId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "imageUrl", + "columnName": "imageUrl", + "affinity": "TEXT" + }, + { + "fieldPath": "quantity", + "columnName": "quantity", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "currency", + "columnName": "currency", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "total", + "columnName": "total", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "millisSinceLastUpdated", + "columnName": "millisSinceLastUpdated", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "datePeriod", + "productId", + "localSiteId" + ] + } + }, + { + "tableName": "TaxBasedOnSetting", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`localSiteId` INTEGER NOT NULL, `selectedOption` TEXT NOT NULL, PRIMARY KEY(`localSiteId`))", + "fields": [ + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "selectedOption", + "columnName": "selectedOption", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "localSiteId" + ] + } + }, + { + "tableName": "TaxRate", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `localSiteId` INTEGER NOT NULL, `country` TEXT, `state` TEXT, `postcode` TEXT, `city` TEXT, `rate` TEXT, `name` TEXT, `taxClass` TEXT, PRIMARY KEY(`id`, `localSiteId`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "country", + "columnName": "country", + "affinity": "TEXT" + }, + { + "fieldPath": "state", + "columnName": "state", + "affinity": "TEXT" + }, + { + "fieldPath": "postcode", + "columnName": "postcode", + "affinity": "TEXT" + }, + { + "fieldPath": "city", + "columnName": "city", + "affinity": "TEXT" + }, + { + "fieldPath": "rate", + "columnName": "rate", + "affinity": "TEXT" + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT" + }, + { + "fieldPath": "taxClass", + "columnName": "taxClass", + "affinity": "TEXT" + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "id", + "localSiteId" + ] + } + }, + { + "tableName": "WooPaymentsDepositsOverview", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`localSiteId` INTEGER NOT NULL, `depositsEnabled` INTEGER, `depositsBlocked` INTEGER, `defaultCurrency` TEXT, `delayDays` INTEGER, `weeklyAnchor` TEXT, `monthlyAnchor` INTEGER, `interval` TEXT, PRIMARY KEY(`localSiteId`))", + "fields": [ + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "account.depositsEnabled", + "columnName": "depositsEnabled", + "affinity": "INTEGER" + }, + { + "fieldPath": "account.depositsBlocked", + "columnName": "depositsBlocked", + "affinity": "INTEGER" + }, + { + "fieldPath": "account.defaultCurrency", + "columnName": "defaultCurrency", + "affinity": "TEXT" + }, + { + "fieldPath": "account.depositsSchedule.delayDays", + "columnName": "delayDays", + "affinity": "INTEGER" + }, + { + "fieldPath": "account.depositsSchedule.weeklyAnchor", + "columnName": "weeklyAnchor", + "affinity": "TEXT" + }, + { + "fieldPath": "account.depositsSchedule.monthlyAnchor", + "columnName": "monthlyAnchor", + "affinity": "INTEGER" + }, + { + "fieldPath": "account.depositsSchedule.interval", + "columnName": "interval", + "affinity": "TEXT" + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "localSiteId" + ] + } + }, + { + "tableName": "WooPaymentsDeposits", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `localSiteId` INTEGER NOT NULL, `depositId` TEXT, `date` INTEGER, `type` TEXT, `amount` INTEGER, `status` TEXT, `bankAccount` TEXT, `currency` TEXT, `automatic` INTEGER, `fee` INTEGER, `feePercentage` REAL, `created` INTEGER, `depositType` TEXT NOT NULL, FOREIGN KEY(`localSiteId`) REFERENCES `WooPaymentsDepositsOverview`(`localSiteId`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "depositId", + "columnName": "depositId", + "affinity": "TEXT" + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER" + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "TEXT" + }, + { + "fieldPath": "amount", + "columnName": "amount", + "affinity": "INTEGER" + }, + { + "fieldPath": "status", + "columnName": "status", + "affinity": "TEXT" + }, + { + "fieldPath": "bankAccount", + "columnName": "bankAccount", + "affinity": "TEXT" + }, + { + "fieldPath": "currency", + "columnName": "currency", + "affinity": "TEXT" + }, + { + "fieldPath": "automatic", + "columnName": "automatic", + "affinity": "INTEGER" + }, + { + "fieldPath": "fee", + "columnName": "fee", + "affinity": "INTEGER" + }, + { + "fieldPath": "feePercentage", + "columnName": "feePercentage", + "affinity": "REAL" + }, + { + "fieldPath": "created", + "columnName": "created", + "affinity": "INTEGER" + }, + { + "fieldPath": "depositType", + "columnName": "depositType", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "foreignKeys": [ + { + "table": "WooPaymentsDepositsOverview", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "localSiteId" + ], + "referencedColumns": [ + "localSiteId" + ] + } + ] + }, + { + "tableName": "WooPaymentsManualDeposits", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `localSiteId` INTEGER NOT NULL, `currency` TEXT, `date` INTEGER, FOREIGN KEY(`localSiteId`) REFERENCES `WooPaymentsDepositsOverview`(`localSiteId`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "currency", + "columnName": "currency", + "affinity": "TEXT" + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "INTEGER" + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "foreignKeys": [ + { + "table": "WooPaymentsDepositsOverview", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "localSiteId" + ], + "referencedColumns": [ + "localSiteId" + ] + } + ] + }, + { + "tableName": "WooPaymentsBalance", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `localSiteId` INTEGER NOT NULL, `amount` INTEGER, `currency` TEXT, `fee` INTEGER, `feePercentage` REAL, `net` INTEGER, `balanceType` TEXT NOT NULL, `card` INTEGER, FOREIGN KEY(`localSiteId`) REFERENCES `WooPaymentsDepositsOverview`(`localSiteId`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "amount", + "columnName": "amount", + "affinity": "INTEGER" + }, + { + "fieldPath": "currency", + "columnName": "currency", + "affinity": "TEXT" + }, + { + "fieldPath": "fee", + "columnName": "fee", + "affinity": "INTEGER" + }, + { + "fieldPath": "feePercentage", + "columnName": "feePercentage", + "affinity": "REAL" + }, + { + "fieldPath": "net", + "columnName": "net", + "affinity": "INTEGER" + }, + { + "fieldPath": "balanceType", + "columnName": "balanceType", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "sourceTypes.card", + "columnName": "card", + "affinity": "INTEGER" + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "foreignKeys": [ + { + "table": "WooPaymentsDepositsOverview", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "localSiteId" + ], + "referencedColumns": [ + "localSiteId" + ] + } + ] + }, + { + "tableName": "VisitorSummaryStatsEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`localSiteId` INTEGER NOT NULL, `date` TEXT NOT NULL, `granularity` TEXT NOT NULL, `views` INTEGER NOT NULL, `visitors` INTEGER NOT NULL, PRIMARY KEY(`localSiteId`, `date`, `granularity`))", + "fields": [ + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "granularity", + "columnName": "granularity", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "views", + "columnName": "views", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "visitors", + "columnName": "visitors", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "localSiteId", + "date", + "granularity" + ] + } + }, + { + "tableName": "ShippingMethod", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `localSiteId` INTEGER NOT NULL, `title` TEXT NOT NULL, PRIMARY KEY(`localSiteId`, `id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "localSiteId", + "id" + ] + } + }, + { + "tableName": "CustomerFromAnalytics", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`localSiteId` INTEGER NOT NULL, `id` INTEGER NOT NULL, `userId` INTEGER NOT NULL, `avgOrderValue` REAL NOT NULL, `city` TEXT NOT NULL, `country` TEXT NOT NULL, `dateLastActive` TEXT NOT NULL, `dateLastActiveGmt` TEXT NOT NULL, `dateLastOrder` TEXT NOT NULL, `dateRegistered` TEXT NOT NULL, `dateRegisteredGmt` TEXT NOT NULL, `email` TEXT NOT NULL, `name` TEXT NOT NULL, `ordersCount` INTEGER NOT NULL, `postcode` TEXT NOT NULL, `state` TEXT NOT NULL, `totalSpend` REAL NOT NULL, `username` TEXT NOT NULL, PRIMARY KEY(`localSiteId`, `id`))", + "fields": [ + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "userId", + "columnName": "userId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "avgOrderValue", + "columnName": "avgOrderValue", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "city", + "columnName": "city", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "country", + "columnName": "country", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "dateLastActive", + "columnName": "dateLastActive", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "dateLastActiveGmt", + "columnName": "dateLastActiveGmt", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "dateLastOrder", + "columnName": "dateLastOrder", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "dateRegistered", + "columnName": "dateRegistered", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "dateRegisteredGmt", + "columnName": "dateRegisteredGmt", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "email", + "columnName": "email", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "ordersCount", + "columnName": "ordersCount", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "postcode", + "columnName": "postcode", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "state", + "columnName": "state", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "totalSpend", + "columnName": "totalSpend", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "username", + "columnName": "username", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "localSiteId", + "id" + ] + } + }, + { + "tableName": "ProductEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`localSiteId` INTEGER NOT NULL, `remoteId` INTEGER NOT NULL, `name` TEXT NOT NULL, `slug` TEXT NOT NULL, `permalink` TEXT NOT NULL, `dateCreated` TEXT NOT NULL, `dateModified` TEXT NOT NULL, `type` TEXT NOT NULL, `status` TEXT NOT NULL, `featured` INTEGER NOT NULL, `catalogVisibility` TEXT NOT NULL, `description` TEXT NOT NULL, `shortDescription` TEXT NOT NULL, `sku` TEXT NOT NULL, `globalUniqueId` TEXT NOT NULL, `price` TEXT NOT NULL, `regularPrice` TEXT NOT NULL, `salePrice` TEXT NOT NULL, `onSale` INTEGER NOT NULL, `totalSales` INTEGER NOT NULL, `purchasable` INTEGER NOT NULL, `dateOnSaleFrom` TEXT NOT NULL, `dateOnSaleTo` TEXT NOT NULL, `dateOnSaleFromGmt` TEXT NOT NULL, `dateOnSaleToGmt` TEXT NOT NULL, `virtual` INTEGER NOT NULL, `downloadable` INTEGER NOT NULL, `downloadLimit` INTEGER NOT NULL, `downloadExpiry` INTEGER NOT NULL, `soldIndividually` INTEGER NOT NULL, `externalUrl` TEXT NOT NULL, `buttonText` TEXT NOT NULL, `taxStatus` TEXT NOT NULL, `taxClass` TEXT NOT NULL, `manageStock` INTEGER NOT NULL, `stockQuantity` REAL NOT NULL, `stockStatus` TEXT NOT NULL, `backorders` TEXT NOT NULL, `backordersAllowed` INTEGER NOT NULL, `backordered` INTEGER NOT NULL, `shippingRequired` INTEGER NOT NULL, `shippingTaxable` INTEGER NOT NULL, `shippingClass` TEXT NOT NULL, `shippingClassId` INTEGER NOT NULL, `reviewsAllowed` INTEGER NOT NULL, `averageRating` TEXT NOT NULL, `ratingCount` INTEGER NOT NULL, `parentId` INTEGER NOT NULL, `purchaseNote` TEXT NOT NULL, `menuOrder` INTEGER NOT NULL, `categories` TEXT NOT NULL, `tags` TEXT NOT NULL, `images` TEXT NOT NULL, `attributes` TEXT NOT NULL, `variations` TEXT NOT NULL, `downloads` TEXT NOT NULL, `relatedIds` TEXT NOT NULL, `crossSellIds` TEXT NOT NULL, `upsellIds` TEXT NOT NULL, `groupedProductIds` TEXT NOT NULL, `weight` TEXT NOT NULL, `length` TEXT NOT NULL, `width` TEXT NOT NULL, `height` TEXT NOT NULL, `bundledItems` TEXT NOT NULL, `compositeComponents` TEXT NOT NULL, `specialStockStatus` TEXT NOT NULL, `bundleMinSize` REAL, `bundleMaxSize` REAL, `minAllowedQuantity` INTEGER NOT NULL, `maxAllowedQuantity` INTEGER NOT NULL, `groupOfQuantity` INTEGER NOT NULL, `combineVariationQuantities` INTEGER NOT NULL, `password` TEXT, `isSampleProduct` INTEGER NOT NULL, PRIMARY KEY(`localSiteId`, `remoteId`))", + "fields": [ + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "remoteId", + "columnName": "remoteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "slug", + "columnName": "slug", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "permalink", + "columnName": "permalink", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "dateCreated", + "columnName": "dateCreated", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "dateModified", + "columnName": "dateModified", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "status", + "columnName": "status", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "featured", + "columnName": "featured", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "catalogVisibility", + "columnName": "catalogVisibility", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "shortDescription", + "columnName": "shortDescription", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "sku", + "columnName": "sku", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "globalUniqueId", + "columnName": "globalUniqueId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "price", + "columnName": "price", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "regularPrice", + "columnName": "regularPrice", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "salePrice", + "columnName": "salePrice", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "onSale", + "columnName": "onSale", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "totalSales", + "columnName": "totalSales", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "purchasable", + "columnName": "purchasable", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "dateOnSaleFrom", + "columnName": "dateOnSaleFrom", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "dateOnSaleTo", + "columnName": "dateOnSaleTo", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "dateOnSaleFromGmt", + "columnName": "dateOnSaleFromGmt", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "dateOnSaleToGmt", + "columnName": "dateOnSaleToGmt", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "virtual", + "columnName": "virtual", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "downloadable", + "columnName": "downloadable", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "downloadLimit", + "columnName": "downloadLimit", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "downloadExpiry", + "columnName": "downloadExpiry", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "soldIndividually", + "columnName": "soldIndividually", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "externalUrl", + "columnName": "externalUrl", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "buttonText", + "columnName": "buttonText", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "taxStatus", + "columnName": "taxStatus", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "taxClass", + "columnName": "taxClass", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "manageStock", + "columnName": "manageStock", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "stockQuantity", + "columnName": "stockQuantity", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "stockStatus", + "columnName": "stockStatus", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "backorders", + "columnName": "backorders", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "backordersAllowed", + "columnName": "backordersAllowed", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "backordered", + "columnName": "backordered", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "shippingRequired", + "columnName": "shippingRequired", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "shippingTaxable", + "columnName": "shippingTaxable", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "shippingClass", + "columnName": "shippingClass", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "shippingClassId", + "columnName": "shippingClassId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "reviewsAllowed", + "columnName": "reviewsAllowed", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "averageRating", + "columnName": "averageRating", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "ratingCount", + "columnName": "ratingCount", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "parentId", + "columnName": "parentId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "purchaseNote", + "columnName": "purchaseNote", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "menuOrder", + "columnName": "menuOrder", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "categories", + "columnName": "categories", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "tags", + "columnName": "tags", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "images", + "columnName": "images", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "attributes", + "columnName": "attributes", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "variations", + "columnName": "variations", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "downloads", + "columnName": "downloads", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "relatedIds", + "columnName": "relatedIds", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "crossSellIds", + "columnName": "crossSellIds", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "upsellIds", + "columnName": "upsellIds", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "groupedProductIds", + "columnName": "groupedProductIds", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "weight", + "columnName": "weight", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "length", + "columnName": "length", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "width", + "columnName": "width", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "height", + "columnName": "height", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "bundledItems", + "columnName": "bundledItems", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "compositeComponents", + "columnName": "compositeComponents", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "specialStockStatus", + "columnName": "specialStockStatus", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "bundleMinSize", + "columnName": "bundleMinSize", + "affinity": "REAL" + }, + { + "fieldPath": "bundleMaxSize", + "columnName": "bundleMaxSize", + "affinity": "REAL" + }, + { + "fieldPath": "minAllowedQuantity", + "columnName": "minAllowedQuantity", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "maxAllowedQuantity", + "columnName": "maxAllowedQuantity", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "groupOfQuantity", + "columnName": "groupOfQuantity", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "combineVariationQuantities", + "columnName": "combineVariationQuantities", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "password", + "columnName": "password", + "affinity": "TEXT" + }, + { + "fieldPath": "isSampleProduct", + "columnName": "isSampleProduct", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "localSiteId", + "remoteId" + ] + } + }, + { + "tableName": "PosProductEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`localSiteId` INTEGER NOT NULL, `remoteId` INTEGER NOT NULL, `name` TEXT NOT NULL, `sku` TEXT NOT NULL, `globalUniqueId` TEXT NOT NULL, `type` TEXT NOT NULL, `price` TEXT NOT NULL, `downloadable` INTEGER NOT NULL, `images` TEXT NOT NULL, `attributes` TEXT NOT NULL, `parentId` INTEGER, `status` TEXT NOT NULL, `regularPrice` TEXT NOT NULL, `salePrice` TEXT NOT NULL, `onSale` INTEGER NOT NULL, `description` TEXT NOT NULL, `shortDescription` TEXT NOT NULL, `manageStock` INTEGER NOT NULL, `stockQuantity` REAL, `stockStatus` TEXT NOT NULL, `backordersAllowed` INTEGER NOT NULL, `backordered` INTEGER NOT NULL, `categories` TEXT NOT NULL, `tags` TEXT NOT NULL, `dateModified` TEXT NOT NULL, `variations` TEXT NOT NULL, PRIMARY KEY(`localSiteId`, `remoteId`))", + "fields": [ + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "remoteId", + "columnName": "remoteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "sku", + "columnName": "sku", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "globalUniqueId", + "columnName": "globalUniqueId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "price", + "columnName": "price", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "downloadable", + "columnName": "downloadable", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "images", + "columnName": "images", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "attributes", + "columnName": "attributes", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "parentId", + "columnName": "parentId", + "affinity": "INTEGER" + }, + { + "fieldPath": "status", + "columnName": "status", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "regularPrice", + "columnName": "regularPrice", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "salePrice", + "columnName": "salePrice", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "onSale", + "columnName": "onSale", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "shortDescription", + "columnName": "shortDescription", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "manageStock", + "columnName": "manageStock", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "stockQuantity", + "columnName": "stockQuantity", + "affinity": "REAL" + }, + { + "fieldPath": "stockStatus", + "columnName": "stockStatus", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "backordersAllowed", + "columnName": "backordersAllowed", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "backordered", + "columnName": "backordered", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "categories", + "columnName": "categories", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "tags", + "columnName": "tags", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "dateModified", + "columnName": "dateModified", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "variations", + "columnName": "variations", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "localSiteId", + "remoteId" + ] + } + }, + { + "tableName": "PosVariationEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`localSiteId` INTEGER NOT NULL, `remoteProductId` INTEGER NOT NULL, `remoteVariationId` INTEGER NOT NULL, `type` TEXT NOT NULL, `dateModified` TEXT NOT NULL, `sku` TEXT NOT NULL, `globalUniqueId` TEXT NOT NULL, `variationName` TEXT NOT NULL, `price` TEXT NOT NULL, `regularPrice` TEXT NOT NULL, `salePrice` TEXT NOT NULL, `description` TEXT NOT NULL, `stockQuantity` REAL NOT NULL, `stockStatus` TEXT NOT NULL, `manageStock` INTEGER NOT NULL, `backordered` INTEGER NOT NULL, `attributesJson` TEXT NOT NULL, `imageUrl` TEXT NOT NULL, `status` TEXT NOT NULL, `lastUpdated` TEXT NOT NULL, `downloadable` INTEGER NOT NULL, PRIMARY KEY(`localSiteId`, `remoteProductId`, `remoteVariationId`))", + "fields": [ + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "remoteProductId", + "columnName": "remoteProductId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "remoteVariationId", + "columnName": "remoteVariationId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "dateModified", + "columnName": "dateModified", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "sku", + "columnName": "sku", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "globalUniqueId", + "columnName": "globalUniqueId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "variationName", + "columnName": "variationName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "price", + "columnName": "price", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "regularPrice", + "columnName": "regularPrice", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "salePrice", + "columnName": "salePrice", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "stockQuantity", + "columnName": "stockQuantity", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "stockStatus", + "columnName": "stockStatus", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "manageStock", + "columnName": "manageStock", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "backordered", + "columnName": "backordered", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "attributesJson", + "columnName": "attributesJson", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "imageUrl", + "columnName": "imageUrl", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "status", + "columnName": "status", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "lastUpdated", + "columnName": "lastUpdated", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "downloadable", + "columnName": "downloadable", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "localSiteId", + "remoteProductId", + "remoteVariationId" + ] + } + }, + { + "tableName": "PosSearchableFts", + "createSql": "CREATE VIRTUAL TABLE IF NOT EXISTS `${TABLE_NAME}` USING FTS4(`localSiteId` TEXT NOT NULL, `itemId` TEXT NOT NULL, `parentProductId` TEXT NOT NULL, `name` TEXT NOT NULL, `sku` TEXT NOT NULL, `barcode` TEXT NOT NULL, `attributeValues` TEXT NOT NULL, tokenize=unicode61)", + "fields": [ + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "itemId", + "columnName": "itemId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "parentProductId", + "columnName": "parentProductId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "sku", + "columnName": "sku", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "barcode", + "columnName": "barcode", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "attributeValues", + "columnName": "attributeValues", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [] + }, + "ftsVersion": "FTS4", + "ftsOptions": { + "tokenizer": "unicode61", + "tokenizerArgs": [], + "contentTable": "", + "languageIdColumnName": "", + "matchInfo": "FTS4", + "notIndexedColumns": [], + "prefixSizes": [], + "preferredOrder": "ASC" + }, + "contentSyncTriggers": [] + }, + { + "tableName": "ProductCategoryEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`localSiteId` INTEGER NOT NULL, `remoteCategoryId` INTEGER NOT NULL, `name` TEXT NOT NULL, `slug` TEXT NOT NULL, `parent` INTEGER NOT NULL, PRIMARY KEY(`localSiteId`, `remoteCategoryId`))", + "fields": [ + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "remoteCategoryId", + "columnName": "remoteCategoryId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "slug", + "columnName": "slug", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "parent", + "columnName": "parent", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "localSiteId", + "remoteCategoryId" + ] + } + }, + { + "tableName": "ProductVariationEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`localSiteId` INTEGER NOT NULL, `remoteProductId` INTEGER NOT NULL, `remoteVariationId` INTEGER NOT NULL, `dateCreated` TEXT NOT NULL, `dateModified` TEXT NOT NULL, `description` TEXT NOT NULL, `permalink` TEXT NOT NULL, `sku` TEXT NOT NULL, `globalUniqueId` TEXT NOT NULL, `status` TEXT NOT NULL, `price` TEXT NOT NULL, `regularPrice` TEXT NOT NULL, `salePrice` TEXT NOT NULL, `dateOnSaleFrom` TEXT NOT NULL, `dateOnSaleTo` TEXT NOT NULL, `dateOnSaleFromGmt` TEXT NOT NULL, `dateOnSaleToGmt` TEXT NOT NULL, `taxStatus` TEXT NOT NULL, `taxClass` TEXT NOT NULL, `onSale` INTEGER NOT NULL, `purchasable` INTEGER NOT NULL, `virtual` INTEGER NOT NULL, `downloadable` INTEGER NOT NULL, `downloadLimit` INTEGER NOT NULL, `downloadExpiry` INTEGER NOT NULL, `downloads` TEXT NOT NULL, `backorders` TEXT NOT NULL, `backordersAllowed` INTEGER NOT NULL, `backordered` INTEGER NOT NULL, `shippingClass` TEXT NOT NULL, `shippingClassId` INTEGER NOT NULL, `manageStock` INTEGER NOT NULL, `stockQuantity` REAL NOT NULL, `stockStatus` TEXT NOT NULL, `image` TEXT NOT NULL, `editContextImage` TEXT, `weight` TEXT NOT NULL, `length` TEXT NOT NULL, `width` TEXT NOT NULL, `height` TEXT NOT NULL, `minAllowedQuantity` INTEGER NOT NULL, `maxAllowedQuantity` INTEGER NOT NULL, `groupOfQuantity` INTEGER NOT NULL, `overrideProductQuantities` INTEGER NOT NULL, `menuOrder` INTEGER NOT NULL, `attributes` TEXT NOT NULL, `metadata` TEXT, PRIMARY KEY(`localSiteId`, `remoteProductId`, `remoteVariationId`))", + "fields": [ + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "remoteProductId", + "columnName": "remoteProductId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "remoteVariationId", + "columnName": "remoteVariationId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "dateCreated", + "columnName": "dateCreated", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "dateModified", + "columnName": "dateModified", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "permalink", + "columnName": "permalink", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "sku", + "columnName": "sku", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "globalUniqueId", + "columnName": "globalUniqueId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "status", + "columnName": "status", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "price", + "columnName": "price", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "regularPrice", + "columnName": "regularPrice", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "salePrice", + "columnName": "salePrice", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "dateOnSaleFrom", + "columnName": "dateOnSaleFrom", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "dateOnSaleTo", + "columnName": "dateOnSaleTo", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "dateOnSaleFromGmt", + "columnName": "dateOnSaleFromGmt", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "dateOnSaleToGmt", + "columnName": "dateOnSaleToGmt", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "taxStatus", + "columnName": "taxStatus", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "taxClass", + "columnName": "taxClass", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "onSale", + "columnName": "onSale", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "purchasable", + "columnName": "purchasable", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "virtual", + "columnName": "virtual", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "downloadable", + "columnName": "downloadable", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "downloadLimit", + "columnName": "downloadLimit", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "downloadExpiry", + "columnName": "downloadExpiry", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "downloads", + "columnName": "downloads", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "backorders", + "columnName": "backorders", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "backordersAllowed", + "columnName": "backordersAllowed", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "backordered", + "columnName": "backordered", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "shippingClass", + "columnName": "shippingClass", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "shippingClassId", + "columnName": "shippingClassId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "manageStock", + "columnName": "manageStock", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "stockQuantity", + "columnName": "stockQuantity", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "stockStatus", + "columnName": "stockStatus", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "image", + "columnName": "image", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "editContextImage", + "columnName": "editContextImage", + "affinity": "TEXT" + }, + { + "fieldPath": "weight", + "columnName": "weight", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "length", + "columnName": "length", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "width", + "columnName": "width", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "height", + "columnName": "height", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "minAllowedQuantity", + "columnName": "minAllowedQuantity", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "maxAllowedQuantity", + "columnName": "maxAllowedQuantity", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "groupOfQuantity", + "columnName": "groupOfQuantity", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "overrideProductQuantities", + "columnName": "overrideProductQuantities", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "menuOrder", + "columnName": "menuOrder", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "attributes", + "columnName": "attributes", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "metadata", + "columnName": "metadata", + "affinity": "TEXT" + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "localSiteId", + "remoteProductId", + "remoteVariationId" + ] + } + }, + { + "tableName": "ProductTagEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`localSiteId` INTEGER NOT NULL, `remoteTagId` INTEGER NOT NULL, `name` TEXT NOT NULL, `slug` TEXT NOT NULL, `description` TEXT NOT NULL, `count` INTEGER NOT NULL, PRIMARY KEY(`localSiteId`, `remoteTagId`))", + "fields": [ + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "remoteTagId", + "columnName": "remoteTagId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "slug", + "columnName": "slug", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "count", + "columnName": "count", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "localSiteId", + "remoteTagId" + ] + } + }, + { + "tableName": "ProductShippingClassEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`localSiteId` INTEGER NOT NULL, `remoteShippingClassId` INTEGER NOT NULL, `name` TEXT NOT NULL, `slug` TEXT NOT NULL, `description` TEXT NOT NULL, PRIMARY KEY(`localSiteId`, `remoteShippingClassId`))", + "fields": [ + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "remoteShippingClassId", + "columnName": "remoteShippingClassId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "slug", + "columnName": "slug", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "localSiteId", + "remoteShippingClassId" + ] + } + }, + { + "tableName": "ProductReviewEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`localSiteId` INTEGER NOT NULL, `remoteProductReviewId` INTEGER NOT NULL, `remoteProductId` INTEGER NOT NULL, `dateCreated` TEXT NOT NULL, `status` TEXT NOT NULL, `reviewerName` TEXT NOT NULL, `reviewerEmail` TEXT NOT NULL, `review` TEXT NOT NULL, `rating` INTEGER NOT NULL, `verified` INTEGER NOT NULL, `reviewerAvatarsJson` TEXT NOT NULL, PRIMARY KEY(`localSiteId`, `remoteProductReviewId`, `remoteProductId`))", + "fields": [ + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "remoteProductReviewId", + "columnName": "remoteProductReviewId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "remoteProductId", + "columnName": "remoteProductId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "dateCreated", + "columnName": "dateCreated", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "status", + "columnName": "status", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "reviewerName", + "columnName": "reviewerName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "reviewerEmail", + "columnName": "reviewerEmail", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "review", + "columnName": "review", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "rating", + "columnName": "rating", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "verified", + "columnName": "verified", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "reviewerAvatarsJson", + "columnName": "reviewerAvatarsJson", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "localSiteId", + "remoteProductReviewId", + "remoteProductId" + ] + } + }, + { + "tableName": "ProductSettingsEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`localSiteId` INTEGER NOT NULL, `weightUnit` TEXT NOT NULL, `dimensionUnit` TEXT NOT NULL, `defaultLowStockThreshold` INTEGER, PRIMARY KEY(`localSiteId`))", + "fields": [ + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "weightUnit", + "columnName": "weightUnit", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "dimensionUnit", + "columnName": "dimensionUnit", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "defaultLowStockThreshold", + "columnName": "defaultLowStockThreshold", + "affinity": "INTEGER" + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "localSiteId" + ] + } + }, + { + "tableName": "CustomerEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`stableId` TEXT NOT NULL, `localSiteId` INTEGER NOT NULL, `remoteCustomerId` INTEGER NOT NULL, `avatarUrl` TEXT NOT NULL, `dateCreated` TEXT NOT NULL, `dateCreatedGmt` TEXT NOT NULL, `dateModified` TEXT NOT NULL, `dateModifiedGmt` TEXT NOT NULL, `email` TEXT NOT NULL, `firstName` TEXT NOT NULL, `isPayingCustomer` INTEGER NOT NULL, `lastName` TEXT NOT NULL, `role` TEXT NOT NULL, `username` TEXT NOT NULL, `billingAddress1` TEXT NOT NULL, `billingAddress2` TEXT NOT NULL, `billingCity` TEXT NOT NULL, `billingCompany` TEXT NOT NULL, `billingCountry` TEXT NOT NULL, `billingEmail` TEXT NOT NULL, `billingFirstName` TEXT NOT NULL, `billingLastName` TEXT NOT NULL, `billingPhone` TEXT NOT NULL, `billingPostcode` TEXT NOT NULL, `billingState` TEXT NOT NULL, `shippingAddress1` TEXT NOT NULL, `shippingAddress2` TEXT NOT NULL, `shippingCity` TEXT NOT NULL, `shippingCompany` TEXT NOT NULL, `shippingCountry` TEXT NOT NULL, `shippingFirstName` TEXT NOT NULL, `shippingLastName` TEXT NOT NULL, `shippingPostcode` TEXT NOT NULL, `shippingState` TEXT NOT NULL, `analyticsCustomerId` INTEGER, PRIMARY KEY(`localSiteId`, `stableId`))", + "fields": [ + { + "fieldPath": "stableId", + "columnName": "stableId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "remoteCustomerId", + "columnName": "remoteCustomerId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "avatarUrl", + "columnName": "avatarUrl", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "dateCreated", + "columnName": "dateCreated", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "dateCreatedGmt", + "columnName": "dateCreatedGmt", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "dateModified", + "columnName": "dateModified", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "dateModifiedGmt", + "columnName": "dateModifiedGmt", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "email", + "columnName": "email", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "firstName", + "columnName": "firstName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "isPayingCustomer", + "columnName": "isPayingCustomer", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lastName", + "columnName": "lastName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "role", + "columnName": "role", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "username", + "columnName": "username", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "billingAddress1", + "columnName": "billingAddress1", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "billingAddress2", + "columnName": "billingAddress2", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "billingCity", + "columnName": "billingCity", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "billingCompany", + "columnName": "billingCompany", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "billingCountry", + "columnName": "billingCountry", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "billingEmail", + "columnName": "billingEmail", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "billingFirstName", + "columnName": "billingFirstName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "billingLastName", + "columnName": "billingLastName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "billingPhone", + "columnName": "billingPhone", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "billingPostcode", + "columnName": "billingPostcode", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "billingState", + "columnName": "billingState", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "shippingAddress1", + "columnName": "shippingAddress1", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "shippingAddress2", + "columnName": "shippingAddress2", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "shippingCity", + "columnName": "shippingCity", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "shippingCompany", + "columnName": "shippingCompany", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "shippingCountry", + "columnName": "shippingCountry", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "shippingFirstName", + "columnName": "shippingFirstName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "shippingLastName", + "columnName": "shippingLastName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "shippingPostcode", + "columnName": "shippingPostcode", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "shippingState", + "columnName": "shippingState", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "analyticsCustomerId", + "columnName": "analyticsCustomerId", + "affinity": "INTEGER" + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "localSiteId", + "stableId" + ] + } + }, + { + "tableName": "LocationEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`parentCode` TEXT NOT NULL, `code` TEXT NOT NULL, `name` TEXT NOT NULL, PRIMARY KEY(`parentCode`, `code`))", + "fields": [ + { + "fieldPath": "parentCode", + "columnName": "parentCode", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "code", + "columnName": "code", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "parentCode", + "code" + ] + } + }, + { + "tableName": "OrderShipmentProviderEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`localSiteId` INTEGER NOT NULL, `country` TEXT NOT NULL, `carrierName` TEXT NOT NULL, `carrierLink` TEXT NOT NULL, PRIMARY KEY(`localSiteId`, `carrierName`, `country`))", + "fields": [ + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "country", + "columnName": "country", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "carrierName", + "columnName": "carrierName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "carrierLink", + "columnName": "carrierLink", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "localSiteId", + "carrierName", + "country" + ] + } + }, + { + "tableName": "OrderShipmentTrackingEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`localSiteId` INTEGER NOT NULL, `orderId` INTEGER NOT NULL, `remoteTrackingId` TEXT NOT NULL, `trackingNumber` TEXT NOT NULL, `trackingProvider` TEXT NOT NULL, `trackingLink` TEXT NOT NULL, `dateShipped` TEXT NOT NULL, PRIMARY KEY(`localSiteId`, `orderId`, `remoteTrackingId`))", + "fields": [ + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "orderId", + "columnName": "orderId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "remoteTrackingId", + "columnName": "remoteTrackingId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "trackingNumber", + "columnName": "trackingNumber", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "trackingProvider", + "columnName": "trackingProvider", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "trackingLink", + "columnName": "trackingLink", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "dateShipped", + "columnName": "dateShipped", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "localSiteId", + "orderId", + "remoteTrackingId" + ] + } + }, + { + "tableName": "UserEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`localSiteId` INTEGER NOT NULL, `remoteUserId` INTEGER NOT NULL, `firstName` TEXT NOT NULL, `lastName` TEXT NOT NULL, `username` TEXT NOT NULL, `email` TEXT NOT NULL, `roles` TEXT NOT NULL, PRIMARY KEY(`localSiteId`, `remoteUserId`))", + "fields": [ + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "remoteUserId", + "columnName": "remoteUserId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "firstName", + "columnName": "firstName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "lastName", + "columnName": "lastName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "username", + "columnName": "username", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "email", + "columnName": "email", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "roles", + "columnName": "roles", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "localSiteId", + "remoteUserId" + ] + } + }, + { + "tableName": "TaxClassEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`localSiteId` INTEGER NOT NULL, `name` TEXT NOT NULL, `slug` TEXT NOT NULL, PRIMARY KEY(`localSiteId`, `slug`))", + "fields": [ + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "slug", + "columnName": "slug", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "localSiteId", + "slug" + ] + } + }, + { + "tableName": "SettingsEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`localSiteId` INTEGER NOT NULL, `currencyCode` TEXT NOT NULL, `currencyPosition` TEXT NOT NULL, `currencyThousandSeparator` TEXT NOT NULL, `currencyDecimalSeparator` TEXT NOT NULL, `currencyDecimalNumber` INTEGER NOT NULL, `countryCode` TEXT NOT NULL, `stateCode` TEXT NOT NULL, `address` TEXT NOT NULL, `address2` TEXT NOT NULL, `city` TEXT NOT NULL, `postalCode` TEXT NOT NULL, `couponsEnabled` INTEGER NOT NULL, PRIMARY KEY(`localSiteId`))", + "fields": [ + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "currencyCode", + "columnName": "currencyCode", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "currencyPosition", + "columnName": "currencyPosition", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "currencyThousandSeparator", + "columnName": "currencyThousandSeparator", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "currencyDecimalSeparator", + "columnName": "currencyDecimalSeparator", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "currencyDecimalNumber", + "columnName": "currencyDecimalNumber", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "countryCode", + "columnName": "countryCode", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "stateCode", + "columnName": "stateCode", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "address", + "columnName": "address", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "address2", + "columnName": "address2", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "city", + "columnName": "city", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "postalCode", + "columnName": "postalCode", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "couponsEnabled", + "columnName": "couponsEnabled", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "localSiteId" + ] + } + }, + { + "tableName": "OrderSummaryEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`siteId` INTEGER NOT NULL, `orderId` INTEGER NOT NULL, `dateCreated` TEXT NOT NULL, PRIMARY KEY(`siteId`, `orderId`))", + "fields": [ + { + "fieldPath": "siteId", + "columnName": "siteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "orderId", + "columnName": "orderId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "dateCreated", + "columnName": "dateCreated", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "siteId", + "orderId" + ] + } + }, + { + "tableName": "OrderStatusEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`siteId` INTEGER NOT NULL, `statusKey` TEXT NOT NULL, `label` TEXT NOT NULL, `statusCount` INTEGER NOT NULL, `position` INTEGER NOT NULL, PRIMARY KEY(`siteId`, `statusKey`))", + "fields": [ + { + "fieldPath": "siteId", + "columnName": "siteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "statusKey", + "columnName": "statusKey", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "label", + "columnName": "label", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "statusCount", + "columnName": "statusCount", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "position", + "columnName": "position", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "siteId", + "statusKey" + ] + } + }, + { + "tableName": "WooShippingLabelEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`localSiteId` INTEGER NOT NULL, `orderId` INTEGER NOT NULL, `labelId` INTEGER NOT NULL, `tracking` TEXT NOT NULL, `refundableAmount` TEXT NOT NULL, `status` TEXT NOT NULL, `created` TEXT, `carrierId` TEXT NOT NULL, `serviceName` TEXT NOT NULL, `commercialInvoiceUrl` TEXT, `isCommercialInvoiceSubmittedElectronically` INTEGER NOT NULL, `packageName` TEXT NOT NULL, `isLetter` INTEGER NOT NULL, `productNames` TEXT NOT NULL, `productIds` TEXT, `shipmentId` TEXT, `receiptItemId` INTEGER NOT NULL, `createdDate` TEXT, `mainReceiptId` INTEGER NOT NULL, `rate` TEXT NOT NULL, `currency` TEXT NOT NULL, `expiryDate` INTEGER NOT NULL, `usedDate` INTEGER, `refund` TEXT, `hazmatCategory` TEXT, `originAddress` TEXT, `destinationAddress` TEXT, PRIMARY KEY(`localSiteId`, `orderId`, `labelId`))", + "fields": [ + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "orderId", + "columnName": "orderId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "labelId", + "columnName": "labelId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "tracking", + "columnName": "tracking", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "refundableAmount", + "columnName": "refundableAmount", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "status", + "columnName": "status", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "created", + "columnName": "created", + "affinity": "TEXT" + }, + { + "fieldPath": "carrierId", + "columnName": "carrierId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "serviceName", + "columnName": "serviceName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "commercialInvoiceUrl", + "columnName": "commercialInvoiceUrl", + "affinity": "TEXT" + }, + { + "fieldPath": "isCommercialInvoiceSubmittedElectronically", + "columnName": "isCommercialInvoiceSubmittedElectronically", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "packageName", + "columnName": "packageName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "isLetter", + "columnName": "isLetter", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "productNames", + "columnName": "productNames", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "productIds", + "columnName": "productIds", + "affinity": "TEXT" + }, + { + "fieldPath": "shipmentId", + "columnName": "shipmentId", + "affinity": "TEXT" + }, + { + "fieldPath": "receiptItemId", + "columnName": "receiptItemId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "createdDate", + "columnName": "createdDate", + "affinity": "TEXT" + }, + { + "fieldPath": "mainReceiptId", + "columnName": "mainReceiptId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "rate", + "columnName": "rate", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "currency", + "columnName": "currency", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "expiryDate", + "columnName": "expiryDate", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "usedDate", + "columnName": "usedDate", + "affinity": "INTEGER" + }, + { + "fieldPath": "refund", + "columnName": "refund", + "affinity": "TEXT" + }, + { + "fieldPath": "hazmatCategory", + "columnName": "hazmatCategory", + "affinity": "TEXT" + }, + { + "fieldPath": "originAddress", + "columnName": "originAddress", + "affinity": "TEXT" + }, + { + "fieldPath": "destinationAddress", + "columnName": "destinationAddress", + "affinity": "TEXT" + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "localSiteId", + "orderId", + "labelId" + ] + } + }, + { + "tableName": "WooShippingShipmentEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`localSiteId` INTEGER NOT NULL, `orderId` INTEGER NOT NULL, `shipmentId` TEXT NOT NULL, `items` TEXT NOT NULL, PRIMARY KEY(`localSiteId`, `orderId`, `shipmentId`))", + "fields": [ + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "orderId", + "columnName": "orderId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "shipmentId", + "columnName": "shipmentId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "items", + "columnName": "items", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "localSiteId", + "orderId", + "shipmentId" + ] + } + }, + { + "tableName": "WooShippingPackagesEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`localSiteId` INTEGER NOT NULL, `storeOptions` TEXT NOT NULL, `savedPackages` TEXT NOT NULL, `carrierPackageGroups` TEXT NOT NULL, PRIMARY KEY(`localSiteId`))", + "fields": [ + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "storeOptions", + "columnName": "storeOptions", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "savedPackages", + "columnName": "savedPackages", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "carrierPackageGroups", + "columnName": "carrierPackageGroups", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "localSiteId" + ] + } + }, + { + "tableName": "GlobalAttributeEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`siteId` INTEGER NOT NULL, `remoteId` INTEGER NOT NULL, `name` TEXT NOT NULL, `slug` TEXT NOT NULL, `type` TEXT NOT NULL, `orderBy` TEXT NOT NULL, `hasArchives` INTEGER NOT NULL, PRIMARY KEY(`siteId`, `remoteId`))", + "fields": [ + { + "fieldPath": "siteId", + "columnName": "siteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "remoteId", + "columnName": "remoteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "slug", + "columnName": "slug", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "orderBy", + "columnName": "orderBy", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "hasArchives", + "columnName": "hasArchives", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "siteId", + "remoteId" + ] + } + }, + { + "tableName": "GatewayEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`siteId` INTEGER NOT NULL, `gatewayId` TEXT NOT NULL, `data` TEXT NOT NULL, PRIMARY KEY(`siteId`, `gatewayId`))", + "fields": [ + { + "fieldPath": "siteId", + "columnName": "siteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "gatewayId", + "columnName": "gatewayId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "data", + "columnName": "data", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "siteId", + "gatewayId" + ] + } + }, + { + "tableName": "NewVisitorStatsEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`localSiteId` INTEGER NOT NULL, `granularity` TEXT NOT NULL, `date` TEXT NOT NULL, `startDate` TEXT NOT NULL, `endDate` TEXT NOT NULL, `quantity` TEXT NOT NULL, `fields` TEXT NOT NULL, `data` TEXT NOT NULL, PRIMARY KEY(`localSiteId`, `granularity`, `date`, `quantity`))", + "fields": [ + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "granularity", + "columnName": "granularity", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "date", + "columnName": "date", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "startDate", + "columnName": "startDate", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "endDate", + "columnName": "endDate", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "quantity", + "columnName": "quantity", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "fields", + "columnName": "fields", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "data", + "columnName": "data", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "localSiteId", + "granularity", + "date", + "quantity" + ] + } + }, + { + "tableName": "RevenueStatsEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`localSiteId` INTEGER NOT NULL, `interval` TEXT NOT NULL, `startDate` TEXT NOT NULL, `endDate` TEXT NOT NULL, `data` TEXT NOT NULL, `total` TEXT NOT NULL, `rangeId` TEXT NOT NULL, PRIMARY KEY(`localSiteId`, `rangeId`))", + "fields": [ + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "interval", + "columnName": "interval", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "startDate", + "columnName": "startDate", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "endDate", + "columnName": "endDate", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "data", + "columnName": "data", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "total", + "columnName": "total", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "rangeId", + "columnName": "rangeId", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "localSiteId", + "rangeId" + ] + } + }, + { + "tableName": "ShippingLabelEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`localSiteId` INTEGER NOT NULL, `remoteOrderId` INTEGER NOT NULL, `remoteShippingLabelId` INTEGER NOT NULL, `trackingNumber` TEXT NOT NULL, `carrierId` TEXT NOT NULL, `dateCreated` INTEGER, `expiryDate` INTEGER, `serviceName` TEXT NOT NULL, `status` TEXT NOT NULL, `packageName` TEXT NOT NULL, `rate` REAL NOT NULL, `refundableAmount` REAL NOT NULL, `currency` TEXT NOT NULL, `productNames` TEXT NOT NULL, `productIds` TEXT NOT NULL, `formData` TEXT NOT NULL, `refund` TEXT NOT NULL, `commercialInvoiceUrl` TEXT, PRIMARY KEY(`localSiteId`, `remoteOrderId`, `remoteShippingLabelId`))", + "fields": [ + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "remoteOrderId", + "columnName": "remoteOrderId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "remoteShippingLabelId", + "columnName": "remoteShippingLabelId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "trackingNumber", + "columnName": "trackingNumber", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "carrierId", + "columnName": "carrierId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "dateCreated", + "columnName": "dateCreated", + "affinity": "INTEGER" + }, + { + "fieldPath": "expiryDate", + "columnName": "expiryDate", + "affinity": "INTEGER" + }, + { + "fieldPath": "serviceName", + "columnName": "serviceName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "status", + "columnName": "status", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "packageName", + "columnName": "packageName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "rate", + "columnName": "rate", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "refundableAmount", + "columnName": "refundableAmount", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "currency", + "columnName": "currency", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "productNames", + "columnName": "productNames", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "productIds", + "columnName": "productIds", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "formData", + "columnName": "formData", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "refund", + "columnName": "refund", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "commercialInvoiceUrl", + "columnName": "commercialInvoiceUrl", + "affinity": "TEXT" + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "localSiteId", + "remoteOrderId", + "remoteShippingLabelId" + ] + } + }, + { + "tableName": "ShippingLabelCreationEligibilityEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`siteId` INTEGER NOT NULL, `orderId` INTEGER NOT NULL, `canCreatePackage` INTEGER NOT NULL, `canCreatePaymentMethod` INTEGER NOT NULL, `canCreateCustomsForm` INTEGER NOT NULL, `isEligible` INTEGER NOT NULL, `reason` TEXT, PRIMARY KEY(`siteId`, `orderId`))", + "fields": [ + { + "fieldPath": "siteId", + "columnName": "siteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "orderId", + "columnName": "orderId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "canCreatePackage", + "columnName": "canCreatePackage", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "canCreatePaymentMethod", + "columnName": "canCreatePaymentMethod", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "canCreateCustomsForm", + "columnName": "canCreateCustomsForm", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isEligible", + "columnName": "isEligible", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "reason", + "columnName": "reason", + "affinity": "TEXT" + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "siteId", + "orderId" + ] + } + }, + { + "tableName": "WooPushNotificationPreferences", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`localSiteId` INTEGER NOT NULL, `storeOrderEnabled` INTEGER, `storeOrderMinAmount` TEXT, `storeReviewEnabled` INTEGER, `storeReviewMaxRating` INTEGER, `storeStockEnabled` INTEGER, `storeStockLowStock` INTEGER, `storeStockOutOfStock` INTEGER, `storeStockOnBackorder` INTEGER, PRIMARY KEY(`localSiteId`))", + "fields": [ + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "storeOrderEnabled", + "columnName": "storeOrderEnabled", + "affinity": "INTEGER" + }, + { + "fieldPath": "storeOrderMinAmount", + "columnName": "storeOrderMinAmount", + "affinity": "TEXT" + }, + { + "fieldPath": "storeReviewEnabled", + "columnName": "storeReviewEnabled", + "affinity": "INTEGER" + }, + { + "fieldPath": "storeReviewMaxRating", + "columnName": "storeReviewMaxRating", + "affinity": "INTEGER" + }, + { + "fieldPath": "storeStockEnabled", + "columnName": "storeStockEnabled", + "affinity": "INTEGER" + }, + { + "fieldPath": "storeStockLowStock", + "columnName": "storeStockLowStock", + "affinity": "INTEGER" + }, + { + "fieldPath": "storeStockOutOfStock", + "columnName": "storeStockOutOfStock", + "affinity": "INTEGER" + }, + { + "fieldPath": "storeStockOnBackorder", + "columnName": "storeStockOnBackorder", + "affinity": "INTEGER" + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "localSiteId" + ] + } + }, + { + "tableName": "SupportChatBookmarkEntity", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`chatId` INTEGER NOT NULL, `localSiteId` INTEGER NOT NULL, `remoteSiteId` INTEGER NOT NULL, `botSlug` TEXT NOT NULL, `sessionId` TEXT, `hasCreatedTicket` INTEGER NOT NULL DEFAULT 0, `isResolved` INTEGER NOT NULL DEFAULT 0, `extraTags` TEXT NOT NULL DEFAULT '', `title` TEXT, `createdAt` INTEGER NOT NULL, `updatedAt` INTEGER NOT NULL, PRIMARY KEY(`chatId`))", + "fields": [ + { + "fieldPath": "chatId", + "columnName": "chatId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "remoteSiteId", + "columnName": "remoteSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "botSlug", + "columnName": "botSlug", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "sessionId", + "columnName": "sessionId", + "affinity": "TEXT" + }, + { + "fieldPath": "hasCreatedTicket", + "columnName": "hasCreatedTicket", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "isResolved", + "columnName": "isResolved", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "extraTags", + "columnName": "extraTags", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT" + }, + { + "fieldPath": "createdAt", + "columnName": "createdAt", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "updatedAt", + "columnName": "updatedAt", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "chatId" + ] + } + }, + { + "tableName": "AnalyticsScheduledImportSetting", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`localSiteId` INTEGER NOT NULL, `isEnabled` INTEGER NOT NULL, PRIMARY KEY(`localSiteId`))", + "fields": [ + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isEnabled", + "columnName": "isEnabled", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "localSiteId" + ] + } + }, + { + "tableName": "FilterHistory", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`localSiteId` INTEGER NOT NULL, `filterType` TEXT NOT NULL, `payload` TEXT NOT NULL, `readableString` TEXT NOT NULL, `dateModified` INTEGER NOT NULL, PRIMARY KEY(`localSiteId`, `filterType`, `payload`))", + "fields": [ + { + "fieldPath": "localSiteId", + "columnName": "localSiteId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "filterType", + "columnName": "filterType", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "payload", + "columnName": "payload", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "readableString", + "columnName": "readableString", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "dateModified", + "columnName": "dateModified", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "localSiteId", + "filterType", + "payload" + ] + } + } + ], + "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, '5a184bbefdc60bba2154a2d2a4f7bda1')" + ] + } +} \ No newline at end of file diff --git a/libs/fluxc-plugin/src/main/kotlin/org/wordpress/android/fluxc/di/WCDatabaseModule.kt b/libs/fluxc-plugin/src/main/kotlin/org/wordpress/android/fluxc/di/WCDatabaseModule.kt index 93a127fa11c1..2365cbf86e42 100644 --- a/libs/fluxc-plugin/src/main/kotlin/org/wordpress/android/fluxc/di/WCDatabaseModule.kt +++ b/libs/fluxc-plugin/src/main/kotlin/org/wordpress/android/fluxc/di/WCDatabaseModule.kt @@ -14,6 +14,7 @@ import org.wordpress.android.fluxc.persistence.converters.StatsGranularityConver import org.wordpress.android.fluxc.persistence.dao.AddonsDao import org.wordpress.android.fluxc.persistence.dao.CouponsDao import org.wordpress.android.fluxc.persistence.dao.CustomerFromAnalyticsDao +import org.wordpress.android.fluxc.persistence.dao.FilterHistoryDao import org.wordpress.android.fluxc.persistence.dao.OrdersDao import org.wordpress.android.fluxc.persistence.dao.ShippingMethodDao import org.wordpress.android.fluxc.persistence.dao.SupportChatBookmarkDao @@ -178,6 +179,10 @@ interface WCDatabaseModule { return database.supportChatBookmarkDao } + @Provides fun provideFilterHistoryDao(database: WCAndroidDatabase): FilterHistoryDao { + return database.filterHistoryDao + } + @Provides fun provideAnalyticsScheduledImportDao(database: WCAndroidDatabase) = database.analyticsScheduledImportDao } diff --git a/libs/fluxc-plugin/src/main/kotlin/org/wordpress/android/fluxc/persistence/WCAndroidDatabase.kt b/libs/fluxc-plugin/src/main/kotlin/org/wordpress/android/fluxc/persistence/WCAndroidDatabase.kt index b4773d5525a1..67c29b1b4610 100644 --- a/libs/fluxc-plugin/src/main/kotlin/org/wordpress/android/fluxc/persistence/WCAndroidDatabase.kt +++ b/libs/fluxc-plugin/src/main/kotlin/org/wordpress/android/fluxc/persistence/WCAndroidDatabase.kt @@ -42,6 +42,7 @@ import org.wordpress.android.fluxc.persistence.dao.AnalyticsScheduledImportDao import org.wordpress.android.fluxc.persistence.dao.CouponsDao import org.wordpress.android.fluxc.persistence.dao.CustomerDao import org.wordpress.android.fluxc.persistence.dao.CustomerFromAnalyticsDao +import org.wordpress.android.fluxc.persistence.dao.FilterHistoryDao import org.wordpress.android.fluxc.persistence.dao.GatewaysDao import org.wordpress.android.fluxc.persistence.dao.GlobalAttributesDao import org.wordpress.android.fluxc.persistence.dao.InboxNotesDao @@ -85,6 +86,7 @@ import org.wordpress.android.fluxc.persistence.entity.AddonOptionEntity import org.wordpress.android.fluxc.persistence.entity.CouponEmailEntity import org.wordpress.android.fluxc.persistence.entity.CouponEntity import org.wordpress.android.fluxc.persistence.entity.CustomerFromAnalyticsEntity +import org.wordpress.android.fluxc.persistence.entity.FilterHistoryEntity import org.wordpress.android.fluxc.persistence.entity.GatewayEntity import org.wordpress.android.fluxc.persistence.entity.GlobalAddonGroupEntity import org.wordpress.android.fluxc.persistence.entity.InboxNoteActionEntity @@ -141,7 +143,7 @@ import org.wordpress.android.fluxc.persistence.migrations.MIGRATION_7_8 import org.wordpress.android.fluxc.persistence.migrations.MIGRATION_8_9 import org.wordpress.android.fluxc.persistence.migrations.MIGRATION_9_10 -const val WC_DATABASE_VERSION = 91 +const val WC_DATABASE_VERSION = 92 // Matches the CursorWindow size used by WooWellSqlConfig; raises SQLite's ~2 MB default on API 28+. @Suppress("MagicNumber") @@ -202,6 +204,7 @@ private val CURSOR_WINDOW_SIZE_BYTES = 1024L * 1024L * 10L WooPushNotificationPreferencesEntity::class, SupportChatBookmarkEntity::class, AnalyticsScheduledImportSettingEntity::class, + FilterHistoryEntity::class, ], autoMigrations = [ AutoMigration(from = 12, to = 13), @@ -272,6 +275,7 @@ private val CURSOR_WINDOW_SIZE_BYTES = 1024L * 1024L * 10L AutoMigration(from = 88, to = 89), AutoMigration(from = 89, to = 90, spec = AutoMigration89to90::class), AutoMigration(from = 90, to = 91), + AutoMigration(from = 91, to = 92), ] ) @TypeConverters( @@ -329,6 +333,7 @@ abstract class WCAndroidDatabase : RoomDatabase(), TransactionExecutor { internal abstract val wooPushNotificationPreferencesDao: WooPushNotificationPreferencesDao abstract val supportChatBookmarkDao: SupportChatBookmarkDao abstract val analyticsScheduledImportDao: AnalyticsScheduledImportDao + abstract val filterHistoryDao: FilterHistoryDao companion object { fun buildDb( diff --git a/libs/fluxc-plugin/src/main/kotlin/org/wordpress/android/fluxc/persistence/dao/FilterHistoryDao.kt b/libs/fluxc-plugin/src/main/kotlin/org/wordpress/android/fluxc/persistence/dao/FilterHistoryDao.kt new file mode 100644 index 000000000000..5dc3782aa0d1 --- /dev/null +++ b/libs/fluxc-plugin/src/main/kotlin/org/wordpress/android/fluxc/persistence/dao/FilterHistoryDao.kt @@ -0,0 +1,34 @@ +package org.wordpress.android.fluxc.persistence.dao + +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.OnConflictStrategy +import androidx.room.Query +import kotlinx.coroutines.flow.Flow +import org.wordpress.android.fluxc.model.LocalOrRemoteId.LocalId +import org.wordpress.android.fluxc.persistence.entity.FilterHistoryEntity + +@Dao +interface FilterHistoryDao { + /** + * Inserts a filter history entry, or replaces an existing one with the same + * (localSiteId, filterType, payload) so re-saving an identical selection bumps it to the top. + */ + @Insert(onConflict = OnConflictStrategy.REPLACE) + suspend fun insertOrReplace(entity: FilterHistoryEntity) + + @Query( + "SELECT * FROM FilterHistory WHERE localSiteId = :localSiteId AND filterType = :filterType " + + "ORDER BY dateModified DESC" + ) + fun observeForSite(localSiteId: LocalId, filterType: String): Flow> + + @Query( + "DELETE FROM FilterHistory WHERE localSiteId = :localSiteId AND filterType = :filterType " + + "AND payload = :payload" + ) + suspend fun delete(localSiteId: LocalId, filterType: String, payload: String): Int + + @Query("DELETE FROM FilterHistory WHERE localSiteId = :localSiteId AND filterType = :filterType") + suspend fun clear(localSiteId: LocalId, filterType: String): Int +} diff --git a/libs/fluxc-plugin/src/main/kotlin/org/wordpress/android/fluxc/persistence/entity/FilterHistoryEntity.kt b/libs/fluxc-plugin/src/main/kotlin/org/wordpress/android/fluxc/persistence/entity/FilterHistoryEntity.kt new file mode 100644 index 000000000000..b167dbb5ac41 --- /dev/null +++ b/libs/fluxc-plugin/src/main/kotlin/org/wordpress/android/fluxc/persistence/entity/FilterHistoryEntity.kt @@ -0,0 +1,24 @@ +package org.wordpress.android.fluxc.persistence.entity + +import androidx.room.Entity +import org.wordpress.android.fluxc.model.LocalOrRemoteId.LocalId + +/** + * A single persisted filter selection ("filter history" entry) for the order or product list. + * + * [payload] is a canonical, normalized serialization of the selected filters and doubles as the + * dedup key: the composite primary key ([localSiteId], [filterType], [payload]) combined with + * `OnConflictStrategy.REPLACE` means re-saving an identical selection replaces the existing row and + * bumps [dateModified], moving it to the top of the newest-first ordering. + */ +@Entity( + tableName = "FilterHistory", + primaryKeys = ["localSiteId", "filterType", "payload"] +) +data class FilterHistoryEntity( + val localSiteId: LocalId, + val filterType: String, + val payload: String, + val readableString: String, + val dateModified: Long +) diff --git a/libs/fluxc-plugin/src/test/java/org/wordpress/android/fluxc/persistence/dao/FilterHistoryDaoTest.kt b/libs/fluxc-plugin/src/test/java/org/wordpress/android/fluxc/persistence/dao/FilterHistoryDaoTest.kt new file mode 100644 index 000000000000..1fb675f09ac7 --- /dev/null +++ b/libs/fluxc-plugin/src/test/java/org/wordpress/android/fluxc/persistence/dao/FilterHistoryDaoTest.kt @@ -0,0 +1,135 @@ +package org.wordpress.android.fluxc.persistence.dao + +import android.app.Application +import androidx.test.core.app.ApplicationProvider +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.test.runTest +import org.assertj.core.api.Assertions.assertThat +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.wordpress.android.fluxc.model.LocalOrRemoteId.LocalId +import org.wordpress.android.fluxc.persistence.DatabaseTestRule +import org.wordpress.android.fluxc.persistence.entity.FilterHistoryEntity + +@ExperimentalCoroutinesApi +@RunWith(RobolectricTestRunner::class) +class FilterHistoryDaoTest { + private lateinit var sut: FilterHistoryDao + + private val siteId = LocalId(1) + private val orders = "ORDERS" + private val products = "PRODUCTS" + + @Rule + @JvmField + val databaseRule = DatabaseTestRule(ApplicationProvider.getApplicationContext()) + + @Before + fun setup() { + sut = databaseRule.db.filterHistoryDao + } + + @Test + fun `given no history, when observed, then empty list is emitted`() = runTest { + val result = sut.observeForSite(siteId, orders).first() + + assertThat(result).isEmpty() + } + + @Test + fun `given a saved filter, when observed, then it is emitted`() = runTest { + sut.insertOrReplace(entity(payload = "status=processing", readableString = "Processing", dateModified = 1)) + + val result = sut.observeForSite(siteId, orders).first() + + assertThat(result).hasSize(1) + assertThat(result.first().payload).isEqualTo("status=processing") + assertThat(result.first().readableString).isEqualTo("Processing") + } + + @Test + fun `given multiple filters, when observed, then newest modified is first`() = runTest { + sut.insertOrReplace(entity(payload = "a", readableString = "A", dateModified = 1)) + sut.insertOrReplace(entity(payload = "b", readableString = "B", dateModified = 2)) + sut.insertOrReplace(entity(payload = "c", readableString = "C", dateModified = 3)) + + val result = sut.observeForSite(siteId, orders).first() + + assertThat(result.map { it.payload }).containsExactly("c", "b", "a") + } + + @Test + fun `given an identical payload, when saved again, then it is deduped and bumped to the top`() = runTest { + sut.insertOrReplace(entity(payload = "a", readableString = "A", dateModified = 1)) + sut.insertOrReplace(entity(payload = "b", readableString = "B", dateModified = 2)) + + // Re-save "a" with a newer timestamp and updated readable string. + sut.insertOrReplace(entity(payload = "a", readableString = "A updated", dateModified = 3)) + + val result = sut.observeForSite(siteId, orders).first() + + assertThat(result.map { it.payload }).containsExactly("a", "b") + assertThat(result.first().readableString).isEqualTo("A updated") + } + + @Test + fun `given a saved filter, when deleted by its key, then it is removed`() = runTest { + sut.insertOrReplace(entity(payload = "a", readableString = "A", dateModified = 1)) + + sut.delete(siteId, orders, payload = "a") + + assertThat(sut.observeForSite(siteId, orders).first()).isEmpty() + } + + @Test + fun `given the same payload for two types, when one is deleted, then the other type is untouched`() = runTest { + sut.insertOrReplace(entity(payload = "a", readableString = "A", dateModified = 1)) + sut.insertOrReplace(entity(filterType = products, payload = "a", readableString = "A", dateModified = 1)) + + sut.delete(siteId, orders, payload = "a") + + assertThat(sut.observeForSite(siteId, orders).first()).isEmpty() + assertThat(sut.observeForSite(siteId, products).first()).hasSize(1) + } + + @Test + fun `given filters for a site and type, when cleared, then only that site and type is emptied`() = runTest { + sut.insertOrReplace(entity(payload = "a", readableString = "A", dateModified = 1)) + sut.insertOrReplace(entity(payload = "b", readableString = "B", dateModified = 2)) + sut.insertOrReplace(entity(filterType = products, payload = "p", readableString = "P", dateModified = 1)) + sut.insertOrReplace(entity(localSiteId = LocalId(2), payload = "o", readableString = "O", dateModified = 1)) + + sut.clear(siteId, orders) + + assertThat(sut.observeForSite(siteId, orders).first()).isEmpty() + assertThat(sut.observeForSite(siteId, products).first()).hasSize(1) + assertThat(sut.observeForSite(LocalId(2), orders).first()).hasSize(1) + } + + @Test + fun `given filters for multiple sites, when observed, then each site is isolated`() = runTest { + sut.insertOrReplace(entity(payload = "a", readableString = "A", dateModified = 1)) + sut.insertOrReplace(entity(localSiteId = LocalId(2), payload = "b", readableString = "B", dateModified = 1)) + + assertThat(sut.observeForSite(siteId, orders).first().first().payload).isEqualTo("a") + assertThat(sut.observeForSite(LocalId(2), orders).first().first().payload).isEqualTo("b") + } + + private fun entity( + localSiteId: LocalId = siteId, + filterType: String = orders, + payload: String, + readableString: String, + dateModified: Long + ) = FilterHistoryEntity( + localSiteId = localSiteId, + filterType = filterType, + payload = payload, + readableString = readableString, + dateModified = dateModified + ) +}