У меня есть несколько сложный набор таблиц с @Relations. Вот моя первая таблица:
@Entity(tableName = "commodity")
class Commodity(@NotNull @PrimaryKey val id : String,
val __typename : String,
val name : String,
val isometricDrawingUrl : String,
val startDate : OffsetDateTime?,
val endDate : OffsetDateTime?,
val numberOfBlocks : Int,
val numberOfRejects : Int)
Вторая таблица:
@Entity(tableName = "milestone")
class Milestone(@NotNull @PrimaryKey val id : String,
val commodityId : String,
val __typename: String,
val name: String,
val earnableHours: Double,
val currentStatusI18n: MilestoneStatus,
val approved: OffsetDateTime?,
val claimed: OffsetDateTime?
)
Вот моя первая запись @Ebedded:
class CommoditiesAndAllMilestones {
@Embedded
var commodity: Commodity? = null
@Relation(
parentColumn = "id",
entityColumn = "commodityId",
entity = Milestone::class
)
var milestones: List<MileStonesAndAllBlocks> = ArrayList()
override fun equals(other: Any?): Boolean {
return this === other
}
}
Второе встраиваемое отношение:
class MileStonesAndAllBlocks {
@Embedded
var milestone: Milestone? = null
@Relation(
entity = Block::class,
parentColumn = "id",
entityColumn = "milestoneId"
)
var blocks: List<Block> = ArrayList()
@Relation(
parentColumn = "id",
entity = ApprovedBy::class,
entityColumn = "milestoneId"
)
var approvedBy : List<ApprovedBy> = ArrayList()
@Relation(
parentColumn = "id",
entity = ClaimedBy::class,
entityColumn = "milestoneId"
)
var claimedBy : List<ClaimedBy> = ArrayList()
}
Проблема в том, что я не могу выполнить простой запрос:
@Transaction
@Query("Select * from commodity WHERE name LIKE '%' || :typeName || '%' AND numberOfBlocks > 0")
fun getCommodities(typeName: String) : DataSource.Factory<Int,CommoditiesAndAllMilestones>
Выполнение этого запроса возвращает все значения в таблице. Кажется, он игнорирует предложение where, хотя встроенные отношения работают - структура List такая, как я ожидал. Можете ли вы выполнить условия в пунктах where, если вы используете Room Relations?
РЕДАКТИРОВАТЬ
Я создал этот тестовый файл, и, очевидно, вы можете выполнять запросы с предложениями Where.
@Query("Select * from commodity WHERE name LIKE '%' || :typeName || '%' AND numberOfBlocks > 0")
fun getCommoditiesBasic(typeName: String) : List<CommoditiesAndAllMilestones>
@RunWith(AndroidJUnit4::class)
class ListCategoryDaoTest {
@get:Rule
val rule: TestRule = InstantTaskExecutorRule()
private lateinit var database: CommoditiesDatabase
private lateinit var commodityDao: CommodityDao
private lateinit var approvedBy : ApprovedByDao
private lateinit var claimedByDao : ClaimedByDao
private lateinit var blockDao : BlockDao
private lateinit var milestoneDao : MilestoneDao
private val workPackageId : String = UUID.randomUUID().toString()
private var workPackage : WorkPackageByIdQuery.WorkPackage? = null
private lateinit var commodityRepository : CommodityRepository
private val mainThreadSurrogate = newSingleThreadContext("UI thread")
@Before
fun setup() {
database = CommoditiesDatabase.newTestInstance(InstrumentationRegistry.getInstrumentation().context)
commodityDao = database.commodityDao()
approvedBy = database.approvedByDao()
claimedByDao = database.claimedByDao()
blockDao = database.blockDao()
milestoneDao = database.milestoneDao()
commodityRepository = CommodityRepository(approvedBy,blockDao,claimedByDao,commodityDao,milestoneDao)
Dispatchers.setMain(mainThreadSurrogate)
}
@Test
fun addAndRetrieveVideoDataAndBookmarks() {
runBlocking {
launch(Dispatchers.Unconfined) {
workPackage = workPackage(workPackageId).response
workPackage.let {
if (it != null) {
for (commodity in it.commodities()) {
commodityRepository.insertCommodity(commodity)
}
}
}
val commodityData = commodityDao.getCommoditiesBasic(CommodityType.SPOOL.rawValue())
for (i in commodityData.indices) {
val commodity = commodityData[i].commodity
if (commodity != null) {
Assert.assertTrue(commodity.numberOfBlocks > 0)
Assert.assertTrue(commodity.name == CommodityType.SPOOL.rawValue())
}
}
}
}
}
@After
fun tearDown() {
database.close()
Dispatchers.resetMain() // reset main dispatcher to the original Main dispatcher
mainThreadSurrogate.close()
}
fun workPackage(
workPackageId: String
): BpsResponse<WorkPackageByIdQuery.WorkPackage, PipefighterError>
{
var totalBlocks = 0
val workPackage: WorkPackageByIdQuery.WorkPackage
val commodities = mutableListOf<WorkPackageByIdQuery.Commodity>()
val crew = mutableListOf<WorkPackageByIdQuery.Crew>()
val commodityNames = listOf(CommodityType.SPOOL, CommodityType.WELD, CommodityType.BULKPIPE)
val milestoneTypes = listOf("Staged", "ELT", "Weldout", "Supports", "Punchlist")
for (name in commodityNames) {
val preIndex = commodityNames.indexOf(name) + 1
// Create Commodities
for (id in 1..8) {
val milestones = mutableListOf<WorkPackageByIdQuery.Milestone>()
for (index in 0 until 5) {
val status: MilestoneStatus
val blocks = if (id % 2 == 0 && milestoneTypes[index] == "Staged") {
totalBlocks++
status = MilestoneStatus.`$UNKNOWN`
listOf(WorkPackageByIdQuery.Block("Block", UUID.randomUUID().toString()))
} else {
status = MilestoneStatus.values()[Random.nextInt(4)]
listOf()
}
WorkPackageByIdQuery.Milestone(
"Milestone",
milestoneTypes[index],
Random.nextInt(101).toDouble(),
status,
if (status == MilestoneStatus.APPROVED) OffsetDateTime.now() else null,
if (status == MilestoneStatus.APPROVED) WorkPackageByIdQuery.ApprovedBy("ApprovedBy", UUID.randomUUID().toString(), "Mock Approver") else null,
if (status != MilestoneStatus.UNCLAIMED) OffsetDateTime.now() else null,
if (status != MilestoneStatus.UNCLAIMED) WorkPackageByIdQuery.ClaimedBy("ClaimedBy", UUID.randomUUID().toString(), "Mock Claimer") else null,
blocks
).also {
milestones.add(it)
}
}
WorkPackageByIdQuery.Commodity(
"Commodity",
"1FX20000X-5D-130045-${String.format("%02d", preIndex)}-${String.format("%02d", id)}",
name.rawValue(),
"https://file-examples.com/wp-content/uploads/2017/10/file-sample_150kB.pdf",
OffsetDateTime.now().plusDays(id - 1L),
OffsetDateTime.now().plusDays(id + 1L),
milestones
).also {
commodities.add(it)
}
}
}
// Create Crew
for (id in 1..3) {
WorkPackageByIdQuery.Crew(
PipefighterClient.TYPE_CREW,
UUID.randomUUID().toString(),
"# $id Mock Tester"
).also {
crew.add(it)
}
}
WorkPackageByIdQuery.WorkPackage(
PipefighterClient.TYPE_WORKPACKAGE,
workPackageId,
OffsetDateTime.now(),
"https://file-examples.com/wp-content/uploads/2017/10/file-sample_150kB.pdf",
OffsetDateTime.now(),
OffsetDateTime.now().plusMonths(1),
totalBlocks,
0,
commodityNames,
commodities,
crew
).also {
workPackage = it
}
return BpsResponse(workPackage, null)
}
}