Skip to content

WCOrderSummary to Room #14315

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 11 commits into
base: trunk
Choose a base branch
from
Open

WCOrderSummary to Room #14315

wants to merge 11 commits into from

Conversation

wzieba
Copy link
Contributor

@wzieba wzieba commented Jul 11, 2025

Closes: AINFRA-558

Description

This PR migrates WCOrderSummary from WellSql to Room

Steps to reproduce

Testing information

  1. Create a new Jurassic test site - check "Smooth Generator" option for WooCommerce
  2. Open the site on web, go to Tools > Smooth generator
  3. Generate some products and a great number of orders, e.g. 1000 (it takes a few minutes)
  4. Open the mobile app and smoke test browsing the list of orders

Images/gif

  • I have considered if this change warrants release notes and have added them to RELEASE-NOTES.txt if necessary. Use the "[Internal]" label for non-user-facing changes.

wzieba added 4 commits July 10, 2025 13:48
…ansaction for a possible small performance gain

The need for "chunk" is an implementation constraint from SQL - it shouldn't leak to consumer of dao. Therefore this change name from "how" to simple "what".
@dangermattic
Copy link
Collaborator

dangermattic commented Jul 11, 2025

1 Warning
⚠️ This PR is larger than 300 lines of changes. Please consider splitting it into smaller PRs for easier and faster reviews.

Generated by 🚫 Danger

@wpmobilebot
Copy link
Collaborator

wpmobilebot commented Jul 11, 2025

📲 You can test the changes from this Pull Request in WooCommerce-Wear Android by scanning the QR code below to install the corresponding build.
App Name WooCommerce-Wear Android
Platform⌚️ Wear OS
FlavorJalapeno
Build TypeDebug
Commit806e440
Direct Downloadwoocommerce-wear-prototype-build-pr14315-806e440.apk

It doesn't need it. Make `dateModified` nullable, as this is more correct interpretation of "no value" state than an empty string.
@wpmobilebot
Copy link
Collaborator

wpmobilebot commented Jul 11, 2025

📲 You can test the changes from this Pull Request in WooCommerce Android by scanning the QR code below to install the corresponding build.

App Name WooCommerce Android
Platform📱 Mobile
FlavorJalapeno
Build TypeDebug
Commit806e440
Direct Downloadwoocommerce-prototype-build-pr14315-806e440.apk

@codecov-commenter
Copy link

codecov-commenter commented Jul 11, 2025

Codecov Report

Attention: Patch coverage is 3.84615% with 50 lines in your changes missing coverage. Please review.

Project coverage is 37.69%. Comparing base (ba6df7d) to head (806e440).
Report is 311 commits behind head on trunk.

Files with missing lines Patch % Lines
.../org/wordpress/android/fluxc/store/WCOrderStore.kt 0.00% 21 Missing ⚠️
.../android/ui/orders/list/OrderListItemDataSource.kt 0.00% 10 Missing ⚠️
...uxc/network/rest/wpcom/wc/order/OrderRestClient.kt 0.00% 6 Missing ⚠️
...rdpress/android/fluxc/model/WCOrderSummaryModel.kt 0.00% 5 Missing ⚠️
...s/android/fluxc/persistence/dao/OrderSummaryDao.kt 0.00% 4 Missing ⚠️
...rdpress/android/fluxc/persistence/WellSqlConfig.kt 0.00% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff            @@
##              trunk   #14315   +/-   ##
=========================================
  Coverage     37.69%   37.69%           
+ Complexity     9054     9053    -1     
=========================================
  Files          1979     1980    +1     
  Lines        110994   110984   -10     
  Branches      14602    14602           
=========================================
- Hits          41837    41836    -1     
+ Misses        65336    65326   -10     
- Partials       3821     3822    +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Base automatically changed from migrate_refund to trunk July 11, 2025 15:47
@wzieba wzieba added the type: technical debt Represents or solves tech debt of the project. label Jul 11, 2025
@wzieba wzieba added this to the 22.9 milestone Jul 11, 2025
@wzieba wzieba requested a review from Copilot July 11, 2025 15:47
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR migrates the WCOrderSummary data flow from WellSql into Room.

  • Introduces a new OrderSummaryDao, Room entity (WCOrderSummaryModel), and database migration (version bump to 54).
  • Refactors stores and clients (WCOrderStore, OrderUpdateStore, OrderRestClient, etc.) to use the new DAO instead of OrderSqlUtils.
  • Removes WellSql-based OrderSqlUtils methods and updates tests to target the new DAO.

Reviewed Changes

Copilot reviewed 15 out of 16 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
libs/fluxc/src/main/java/org/wordpress/android/fluxc/persistence/WellSqlConfig.kt Bumped WellSql DB version and dropped old table.
libs/fluxc-plugin/src/main/kotlin/.../persistence/dao/OrderSummaryDao.kt New DAO with chunked queries and upsert methods.
libs/fluxc-plugin/src/main/kotlin/.../model/WCOrderSummaryModel.kt Converted model from WellSql annotations to Room.
libs/fluxc-plugin/src/main/kotlin/.../WCAndroidDatabase.kt Added WCOrderSummaryModel and DAO to Room DB.
libs/fluxc-plugin/src/main/kotlin/.../store/WCOrderStore.kt Updated store to call DAO instead of WellSql.
libs/fluxc-plugin/src/main/kotlin/.../store/OrderUpdateStore.kt Swapped OrderSqlUtils for DAO calls.
libs/fluxc-plugin/src/test/java/.../persistence/dao/OrderSummaryDaoTest.kt New tests covering basic DAO operations.
WooCommerce/src/main/kotlin/.../OrderListItemDataSource.kt Adapted UI data source to fetch via DAO.
Comments suppressed due to low confidence (1)

libs/fluxc-plugin/src/main/kotlin/org/wordpress/android/fluxc/persistence/dao/OrderSummaryDao.kt:24

  • The chunking logic splits IDs into subsets of CHUNK_SIZE—it would be prudent to add a test case that verifies getOrderSummaries handles lists larger than CHUNK_SIZE correctly.
        return remoteOrderIds.chunked(CHUNK_SIZE)

Comment on lines +26 to 28
) {
@Ignore var dateModified: String? = null
}
Copy link
Preview

Copilot AI Jul 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dateModified field is marked with @Ignore and won't be persisted, so its value is always null when fetching. You likely need to include it in the entity (remove @Ignore and add it to the primary constructor) so that Room stores and retrieves the modified date correctly.

Suggested change
) {
@Ignore var dateModified: String? = null
}
val dateModified: String? = null // ISO 8601-formatted date in UTC, e.g. 1955-11-05T14:15:00Z
)

Copilot uses AI. Check for mistakes.

Copy link
Contributor Author

@wzieba wzieba Jul 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really - the previous WellSql implementation didn't had this field in db table as well:

db.execSQL(
"CREATE TABLE WCOrderSummaryModel (LOCAL_SITE_ID INTEGER,REMOTE_ORDER_ID INTEGER," +
"DATE_CREATED TEXT NOT NULL,_id INTEGER PRIMARY KEY AUTOINCREMENT," +
"FOREIGN KEY(LOCAL_SITE_ID) REFERENCES SiteModel(_id) ON DELETE CASCADE," +
"UNIQUE (REMOTE_ORDER_ID, LOCAL_SITE_ID) ON CONFLICT REPLACE)"
)

so I guess it's intentional

summaries.filter { cachedOrders.containsKey(it.orderId) }
} else {
summaries
val orderSummaries = runBlocking {
Copy link
Preview

Copilot AI Jul 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using runBlocking in a UI data source can block the main thread and cause jank. Consider making this method suspendable or launching a coroutine in an appropriate scope instead of using runBlocking.

Copilot uses AI. Check for mistakes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well known comment. As always - it's intentional, as these migrations are not meant to resolve threading issues (sometimes they do when I'm sure there are no side effects)

@wzieba wzieba requested a review from ParaskP7 July 14, 2025 08:04
@wzieba wzieba marked this pull request as ready for review July 14, 2025 08:04
Copy link
Contributor

@ParaskP7 ParaskP7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👋 @wzieba !

I have reviewed and tested this PR as per the instructions (almost), everything works as expected, good job! 🌟 x 🌟 ^ 🌟


I have left one question (❓), one suggestions (💡) and one minor (🔍) comment for you to consider. I am going to approve this PR anyway, since none is blocking. I am NOT going to merge this PR yet to give you some time to apply any of my suggestions. However, feel free to ignore them and merge the PR yourself.


EXTRAS

  1. Copilot wrote this and it made me 🤔 a bit: The chunking logic splits IDs into subsets of CHUNK_SIZE—it would be prudent to add a test case that verifies getOrderSummaries handles lists larger than CHUNK_SIZE correctly.
  2. On this second step of testing information 2. Open the site on web, go to Tools > Smooth generator, I could proceed as I was getting this critical error below:
image

Any ideas, did that happen to you too? 🤔

FYI: I tried that 3 times already, 3 different sites... 🤷

"UNIQUE (REMOTE_ORDER_ID, LOCAL_SITE_ID) ON CONFLICT REPLACE"
@Entity(
tableName = "OrderSummaryEntity",
primaryKeys = ["siteId", "orderId"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Info (ℹ️): Just an FYI that after I migrated I noticed that, when navigating to the Orders screen, the list of orders was empty and wouldn't auto-refresh. I then had to manually trigger pull-to-refresh to get the orders to show up.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please confirm that it doesn't happen on trunk?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👋 @wzieba , how do you suggest I confirm that this doesn't happen on trunk? 🤔

FYI: To my understanding, I should uninstall/install the app to get a similar behavior, an empty WCOrderSummaryModel table, correct? And, as far as I remember, whenever I uninstall/install the app from scratch, when navigating to the Orders screen, the list of orders gets auto-populated for me, no need for a manual pull-to-refresh from my side.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah sorry, I understand now. I wonder, we can either:

  • leave it as it is (one time pull-to-refresh shouldn't be bothering)
  • move the data from WellSql to Room database before removing the table (maybe worth experimenting with a solution for this as we'll have to do it anyway for SiteModel)
  • request summaries fetch if database has orders, but not summaries (it'll be one-time case, only after initial run after this migration)

I'll check how time-consuming would be the second point .

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the reply @wzieba ! 🙏

leave it as it is (one time pull-to-refresh shouldn't be bothering)

  1. Can't disagree too much, it shouldn't be too bothering indeed.
  2. Then again, in trying to think as a non-tech user, I wonder if they'll get scared not having any orders shown after an app update... And how quickly would they find pull-to-refresh to get their soul back into their body... 😅 🤷

FYI: I think personally this was they first time I used pull-to-refresh on this screen, but can't be too sure, thinking that the order screen got auto-refreshed for me every time I visit this screen, again, not sure... 🤔

move the data from WellSql to Room database before removing the table (maybe worth experimenting with a solution for this as we'll have to do it anyway for SiteModel)

Maybe this is indeed worth experimenting and get some initial feedback on the process... 🤔

request summaries fetch if database has orders, but not summaries (it'll be one-time case, only after initial run after this migration)

Interesting idea, maybe that would work... 🤔


I'll check how time-consuming would be the second point .

👍 and btw, maybe it's a good time to ask someone from the product team for some extra feedback on that, wdyt? 💭

@ParaskP7
Copy link
Contributor

ParaskP7 commented Jul 14, 2025

Any ideas, did that happen to you too? 🤔

Btw @wzieba , maybe this here and me being just unlucky: p1752505897072599-slack-C02TDTD1GCX 🤷

PS: Will try again tomorrow... 🤞

@wzieba
Copy link
Contributor Author

wzieba commented Jul 15, 2025

Copilot wrote this and it made me 🤔 a bit: The chunking logic splits IDs into subsets of CHUNK_SIZE—it would be prudent to add a test case that verifies getOrderSummaries handles lists larger than CHUNK_SIZE correctly.

I was thinking about test for this method, but rather to verify if it really runs in a transaction - I wasn't sure that @Transaction annotation was enough to make it happen. So I experimented with a test, but eventually decided to not add it as I thought it's too complex. But this comment made me think that this could be actually useful, so here it is: fe950c8

@ParaskP7
Copy link
Contributor

👋 @wzieba !

I was thinking about test for this method, but rather to verify if it really runs in a transaction - I wasn't sure that @transaction annotation was enough to make it happen. So I experimented with a test, but eventually decided to not add it as I thought it's too complex. But this comment made me think that this could be actually useful, so here it is: fe950c8

I just reviewed this OrderSummaryDaoChunksTest, thanks for doing that, an awesome way you found there! 🥇

  1. Question (❓): Is this assertThat(normalizedLogs).contains(buildString { ... } really needed? I am just trying to understand why you added it. Isn't this testing implementation details of how Room does it? Wouldn't just testing that adding 250 order summaries and then retrieving them be enough? Understand that you also want to test the chunked functionality, and if want to keep that please do, I was just not expecting that when writing/pointing to that comment. 🤔
  2. Suggestion (💡): Just to keep this test simpler, I would extract the whole chucked test login into its own assert method, maybe that will further help:
    @Test
    fun `given more than 200 order IDs when getOrderSummaries is called then it chunks input and returns all results in a single transaction`() =
        runTest {
            val orderSummaries = (1..250).asOrderSummaries(siteId)
            dao.upsertOrderSummaries(orderSummaries)

            val remoteIds = orderSummaries.map(WCOrderSummaryModel::orderId)

            // Call your method that chunks with a for loop and is annotated with @Transaction
            val result = dao.getOrderSummaries(siteId, remoteIds)

            assertChunked()
            assertThat(result).containsExactlyInAnyOrderElementsOf(orderSummaries)
        }

    private fun assertChunked() {
        val expectedFirstChunk = createExpectedQuery(200)
        val expectedSecondChunk = createExpectedQuery(50)

        val normalizedLogs = logs.lines()
            .map { it.trim() }
            .filter { it.isNotEmpty() }
            .joinToString("\n")
        assertThat(normalizedLogs).contains(
            buildString {
                appendLine(expectedFirstChunk)
                appendLine(expectedSecondChunk)
                appendLine("TRANSACTION SUCCESSFUL")
                appendLine("END TRANSACTION")
            }
        )
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: technical debt Represents or solves tech debt of the project.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants