From 8c16a72cceef14baa2e0fe48b5791e82c3f7e70a Mon Sep 17 00:00:00 2001 From: Manfred Zingl Date: Fri, 17 May 2024 16:34:54 +0200 Subject: [PATCH] adapt get size query for foreignRows --- .../database/model/TableauxModel.scala | 2 +- .../database/model/tableaux/RowModel.scala | 54 ++++++++++--------- .../api/content/LinkConstraintTest.scala | 8 ++- 3 files changed, 36 insertions(+), 28 deletions(-) diff --git a/src/main/scala/com/campudus/tableaux/database/model/TableauxModel.scala b/src/main/scala/com/campudus/tableaux/database/model/TableauxModel.scala index 1cac50ba..c1107e88 100644 --- a/src/main/scala/com/campudus/tableaux/database/model/TableauxModel.scala +++ b/src/main/scala/com/campudus/tableaux/database/model/TableauxModel.scala @@ -1235,7 +1235,7 @@ class TableauxModel( }) (_, linkDirection, _) <- structureModel.columnStruc.retrieveLinkInformation(table, linkColumn.id) - totalSize <- retrieveRowModel.sizeForeign(linkColumn, rowId, linkDirection) + totalSize <- retrieveRowModel.sizeForeign(linkColumn, rowId, linkDirection, finalFlagOpt, archivedFlagOpt) rawRows <- retrieveRowModel.retrieveForeign( linkColumn, rowId, diff --git a/src/main/scala/com/campudus/tableaux/database/model/tableaux/RowModel.scala b/src/main/scala/com/campudus/tableaux/database/model/tableaux/RowModel.scala index a96e05db..38d87e87 100644 --- a/src/main/scala/com/campudus/tableaux/database/model/tableaux/RowModel.scala +++ b/src/main/scala/com/campudus/tableaux/database/model/tableaux/RowModel.scala @@ -1192,12 +1192,11 @@ class RetrieveRowModel(val connection: DatabaseConnection)( val projection = generateProjection(foreignTableId, foreignColumns) val fromClause = generateFromClause(foreignTableId) - val whereClause = generateRowAnnotationWhereClause(finalFlagOpt, archivedFlagOpt) - val cardinalityFilter = generateCardinalityFilter(linkColumn) + val rowAnnotationFilter = generateRowAnnotationFilter(finalFlagOpt, archivedFlagOpt) val shouldCheckCardinality = !linkDirection.isManyToMany - val maybeCardinalityFilter = shouldCheckCardinality match { + val cardinalityFilter = shouldCheckCardinality match { case false => "" - case true => s"AND $cardinalityFilter" + case true => generateCardinalityFilter(linkColumn) } val binds = shouldCheckCardinality match { case false => Json.arr() @@ -1208,7 +1207,7 @@ class RetrieveRowModel(val connection: DatabaseConnection)( result <- connection.query( s"""|SELECT $projection |FROM $fromClause - |WHERE TRUE $maybeCardinalityFilter $whereClause + |WHERE TRUE $cardinalityFilter $rowAnnotationFilter |GROUP BY ut.id ORDER BY ut.id $pagination""".stripMargin, binds ) @@ -1226,14 +1225,14 @@ class RetrieveRowModel(val connection: DatabaseConnection)( ): Future[Seq[RawRow]] = { val projection = generateProjection(tableId, columns) val fromClause = generateFromClause(tableId) - val whereClause = generateRowAnnotationWhereClause(finalFlagOpt, archivedFlagOpt) + val rowAnnotationFilter = generateRowAnnotationFilter(finalFlagOpt, archivedFlagOpt) for { result <- connection.query( s"""|SELECT $projection |FROM $fromClause - |WHERE TRUE $whereClause + |WHERE TRUE $rowAnnotationFilter |GROUP BY ut.id ORDER BY ut.id $pagination""".stripMargin ) } yield { @@ -1280,31 +1279,35 @@ class RetrieveRowModel(val connection: DatabaseConnection)( } def size(tableId: TableId, finalFlagOpt: Option[Boolean], archivedFlagOpt: Option[Boolean]): Future[Long] = { - val whereClause = generateRowAnnotationWhereClause(finalFlagOpt, archivedFlagOpt) - val query = s"SELECT COUNT(*) FROM user_table_$tableId WHERE TRUE $whereClause" + val rowAnnotationFilter = generateRowAnnotationFilter(finalFlagOpt, archivedFlagOpt) + val query = s"SELECT COUNT(*) FROM user_table_$tableId WHERE TRUE $rowAnnotationFilter" connection.selectSingleValue(query) } - def sizeForeign(linkColumn: LinkColumn, rowId: RowId, linkDirection: LinkDirection): Future[Long] = { + def sizeForeign( + linkColumn: LinkColumn, + rowId: RowId, + linkDirection: LinkDirection, + finalFlagOpt: Option[Boolean], + archivedFlagOpt: Option[Boolean] + ): Future[Long] = { val foreignTableId = linkColumn.to.table.id - val cardinalityFilter = generateCardinalityFilter(linkColumn) - val shouldNotCheckCardinality = linkDirection.isManyToMany + val shouldCheckCardinality = !linkDirection.isManyToMany + val rowAnnotationFilter = generateRowAnnotationFilter(finalFlagOpt, archivedFlagOpt) + val cardinalityFilter = shouldCheckCardinality match { + case false => "" + case true => generateCardinalityFilter(linkColumn) + } + val binds = shouldCheckCardinality match { + case false => Json.arr() + case true => Json.arr(rowId, linkColumn.linkId, rowId, linkColumn.linkId) + } for { - maybeCardinalityFilter <- - if (shouldNotCheckCardinality) { - Future.successful("") - } else { - Future.successful(s"WHERE $cardinalityFilter") - } result <- connection.selectSingleValue[Long]( - s"SELECT COUNT(*) FROM user_table_$foreignTableId ut $maybeCardinalityFilter", - if (shouldNotCheckCardinality) { - Json.arr() - } else { - Json.arr(rowId, linkColumn.linkId, rowId, linkColumn.linkId) - } + s"SELECT COUNT(*) FROM user_table_$foreignTableId ut WHERE TRUE $cardinalityFilter $rowAnnotationFilter", + binds ) } yield { result } } @@ -1485,13 +1488,14 @@ class RetrieveRowModel(val connection: DatabaseConnection)( // linkColumn is from origin tables point of view // ... so we need to swap toSql and fromSql s""" + | AND |(SELECT COUNT(*) = 0 FROM $linkTable WHERE ${linkDirection.toSql} = ut.id AND ${linkDirection.fromSql} = ?) AND |(SELECT COUNT(*) FROM $linkTable WHERE ${linkDirection.toSql} = ut.id) < (SELECT ${linkDirection.fromCardinality} FROM system_link_table WHERE link_id = ?) AND |(SELECT COUNT(*) FROM $linkTable WHERE ${linkDirection.fromSql} = ?) < (SELECT ${linkDirection.toCardinality} FROM system_link_table WHERE link_id = ?) """.stripMargin } - private def generateRowAnnotationWhereClause( + private def generateRowAnnotationFilter( finalFlagOpt: Option[Boolean], archivedFlagOpt: Option[Boolean] ): String = { diff --git a/src/test/scala/com/campudus/tableaux/api/content/LinkConstraintTest.scala b/src/test/scala/com/campudus/tableaux/api/content/LinkConstraintTest.scala index 5c387b0e..75a58a71 100644 --- a/src/test/scala/com/campudus/tableaux/api/content/LinkConstraintTest.scala +++ b/src/test/scala/com/campudus/tableaux/api/content/LinkConstraintTest.scala @@ -1704,6 +1704,7 @@ class RetrieveFinalAndArchivedRows extends LinkTestBase with Helper { resultCell <- sendRequest("GET", s"/tables/$tableId1/columns/$linkColumnId/rows/$rowId1") + resultAllForeignRows <- sendRequest("GET", s"/tables/$tableId1/columns/$linkColumnId/rows/$rowId1/foreignRows") resultForeignRowsFinal <- sendRequest("GET", s"/tables/$tableId1/columns/$linkColumnId/rows/$rowId1/foreignRows?final=true") resultForeignRowsArchived <- @@ -1711,8 +1712,11 @@ class RetrieveFinalAndArchivedRows extends LinkTestBase with Helper { } yield { assertEquals(0, resultCell.getJsonArray("value").size()) - assertEquals(2, resultForeignRowsFinal.getJsonObject("page").getLong("totalSize").longValue()) - assertEquals(2, resultForeignRowsArchived.getJsonObject("page").getLong("totalSize").longValue()) + assertEquals(2, resultAllForeignRows.getJsonObject("page").getLong("totalSize").longValue()) + assertJSONEquals(Json.arr(Json.obj("id" -> 1), Json.obj("id" -> 2)), resultAllForeignRows.getJsonArray("rows")) + + assertEquals(1, resultForeignRowsFinal.getJsonObject("page").getLong("totalSize").longValue()) + assertEquals(1, resultForeignRowsArchived.getJsonObject("page").getLong("totalSize").longValue()) assertJSONEquals(Json.arr(Json.obj("id" -> 1)), resultForeignRowsFinal.getJsonArray("rows")) assertJSONEquals(Json.arr(Json.obj("id" -> 2)), resultForeignRowsArchived.getJsonArray("rows")) }