Skip to content
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

AC#1034/change-check #276

Merged
merged 9 commits into from
Nov 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ dependencies {

implementation 'com.github.cb372:scalacache-guava_2.12:0.28.0'

implementation 'org.webjars:swagger-ui:4.11.1'
implementation 'org.webjars:swagger-ui:5.9.0' // Also update version in DocumentationRouter
zingmane marked this conversation as resolved.
Show resolved Hide resolved

compileOnly "io.vertx:vertx-codegen:${vertxVersion}"

Expand Down
48 changes: 35 additions & 13 deletions src/main/resources/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -1065,6 +1065,9 @@
"parameters": [
{
"$ref": "#/parameters/value"
},
{
"$ref": "#/parameters/forceHistoryOpt"
}
],
"responses": {
Expand All @@ -1086,6 +1089,9 @@
"parameters": [
{
"$ref": "#/parameters/value"
},
{
"$ref": "#/parameters/forceHistoryOpt"
}
],
"responses": {
Expand All @@ -1107,6 +1113,9 @@
"parameters": [
{
"$ref": "#/parameters/value"
},
{
"$ref": "#/parameters/forceHistoryOpt"
}
],
"responses": {
Expand Down Expand Up @@ -2318,19 +2327,10 @@
]
},
"historyType": {
"description": "The type of the history entry",
"type": "string",
"enum": [
"row",
"cell",
"comment",
"cell_flag",
"row_flag",
"row_permissions"
]
"$ref": "#/definitions/Enum: HistoryType"
},
"languageType": {
"description": "Name of the user who has triggered a change",
"description": "The language type of the column",
"type": "string",
"enum": [
"neutral",
Expand Down Expand Up @@ -3582,6 +3582,18 @@
"listener"
]
},
"Enum: HistoryType": {
"type": "string",
"description": "The type of the history entry",
"enum": [
"row",
"cell",
"comment",
"cell_flag",
"row_flag",
"row_permissions"
]
},
"Response: Subfolder": {
"type": "object",
"required": [
Expand Down Expand Up @@ -3822,6 +3834,14 @@
}
}
},
"forceHistoryOpt": {
"name": "forceHistory",
"description": "If set to true, a history entry will be created even if the value did not change.",
"in": "query",
"required": false,
"type": "boolean",
"default": false
},
"fileuuid": {
"name": "fileuuid",
"in": "path",
Expand All @@ -3847,8 +3867,10 @@
"description": "The type of the history to filter for.",
"in": "query",
"type": "string",
"format": "string",
"required": false
"required": false,
"items": {
"$ref": "#/definitions/Enum: HistoryType"
}
},
"groupId": {
"name": "groupId",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -458,26 +458,26 @@ class TableauxController(
} yield filled
}

def replaceCellValue[A](tableId: TableId, columnId: ColumnId, rowId: RowId, value: A)(
def replaceCellValue[A](tableId: TableId, columnId: ColumnId, rowId: RowId, value: A, forceHistory: Boolean = false)(
implicit user: TableauxUser
): Future[Cell[_]] = {
checkArguments(greaterZero(tableId), greaterZero(columnId), greaterZero(rowId))
logger.info(s"replaceCellValue $tableId $columnId $rowId $value")
for {
table <- repository.retrieveTable(tableId)
filled <- repository.replaceCellValue(table, columnId, rowId, value)
filled <- repository.replaceCellValue(table, columnId, rowId, value, forceHistory)
} yield filled
}

def updateCellValue[A](tableId: TableId, columnId: ColumnId, rowId: RowId, value: A)(
def updateCellValue[A](tableId: TableId, columnId: ColumnId, rowId: RowId, value: A, forceHistory: Boolean = false)(
implicit user: TableauxUser
): Future[Cell[_]] = {
checkArguments(greaterZero(tableId), greaterZero(columnId), greaterZero(rowId))
logger.info(s"updateCellValue $tableId $columnId $rowId $value")

for {
table <- repository.retrieveTable(tableId)
updated <- repository.updateCellValue(table, columnId, rowId, value)
updated <- repository.updateCellValue(table, columnId, rowId, value, forceHistory)
} yield updated
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -906,19 +906,18 @@ case class CreateHistoryModel(tableauxModel: TableauxModel, connection: Database
def createCells(table: Table, rowId: RowId, values: Seq[(ColumnType[_], _)])(
implicit user: TableauxUser
): Future[Unit] = {
val columns = values.map({ case (col: ColumnType[_], _) => col })
val (_, _, _, attachments) = ColumnType.splitIntoTypes(columns)

ColumnType.splitIntoTypesWithValues(values) match {
case Failure(ex) =>
Future.failed(ex)

case Success((simples, multis, links, _)) =>
case Success((simples, multis, links, attachments)) =>
for {
_ <- if (simples.isEmpty) Future.successful(()) else createSimple(table, rowId, simples)
_ <- if (multis.isEmpty) Future.successful(()) else createTranslation(table, rowId, multis)
_ <- if (links.isEmpty) Future.successful(()) else createLinks(table, rowId, links, allowRecursion = true)
_ <- if (attachments.isEmpty) Future.successful(()) else createAttachments(table, rowId, attachments)
_ <-
if (attachments.isEmpty) Future.successful(())
else createAttachments(table, rowId, attachments.map({ case (column, _) => column }))
} yield ()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ class TableauxModel(
{
case (future, (table, column, id)) => {
future.flatMap(_ => {
updateOrReplaceValue(table, column.id, id, replacingRowId, false, t)
updateOrReplaceValue(table, column.id, id, replacingRowId, false, maybeTransaction = t)
}).map(_ => ())
}
}
Expand Down Expand Up @@ -645,12 +645,15 @@ class TableauxModel(
}
}

private def hasCellChanged(oldCell: Cell[_], newCell: Cell[_]): Boolean = oldCell.value != newCell.value

private def updateOrReplaceValue[A](
table: Table,
columnId: ColumnId,
rowId: RowId,
value: A,
replace: Boolean = false,
forceHistory: Boolean = false,
maybeTransaction: Option[DbTransaction] = None
)(implicit user: TableauxUser): Future[Cell[_]] = {
for {
Expand All @@ -673,6 +676,7 @@ class TableauxModel(
roleModel.checkAuthorization(EditCellValue, ComparisonObjects(table, column, value))
}

oldCell <- retrieveCell(column, rowId, true)
_ <- createHistoryModel.createCellsInit(table, rowId, Seq((column, value)))

_ <-
Expand All @@ -687,21 +691,28 @@ class TableauxModel(

_ <- updateRowModel.updateRow(table, rowId, Seq((column, value)), maybeTransaction)
_ <- invalidateCellAndDependentColumns(column, rowId)
_ <- createHistoryModel.createCells(table, rowId, Seq((column, value)))
newCell <- retrieveCell(column, rowId, true)

shouldCreateHistory = forceHistory || hasCellChanged(oldCell, newCell)

changedCell <- retrieveCell(column, rowId, true)
} yield changedCell
_ <-
if (shouldCreateHistory) {
createHistoryModel.createCells(table, rowId, Seq((column, value)))
} else {
Future.successful(())
}
} yield newCell
}

def updateCellValue[A](table: Table, columnId: ColumnId, rowId: RowId, value: A)(
def updateCellValue[A](table: Table, columnId: ColumnId, rowId: RowId, value: A, forceHistory: Boolean = false)(
implicit user: TableauxUser
): Future[Cell[_]] =
updateOrReplaceValue(table, columnId, rowId, value)
updateOrReplaceValue(table, columnId, rowId, value, forceHistory = forceHistory)

def replaceCellValue[A](table: Table, columnId: ColumnId, rowId: RowId, value: A)(
def replaceCellValue[A](table: Table, columnId: ColumnId, rowId: RowId, value: A, forceHistory: Boolean = false)(
implicit user: TableauxUser
): Future[Cell[_]] =
updateOrReplaceValue(table, columnId, rowId, value, replace = true)
updateOrReplaceValue(table, columnId, rowId, value, replace = true, forceHistory = forceHistory)

def clearCellValue(table: Table, columnId: ColumnId, rowId: RowId)(
implicit user: TableauxUser
Expand Down
4 changes: 4 additions & 0 deletions src/main/scala/com/campudus/tableaux/router/BaseRouter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,10 @@ trait BaseRouter extends VertxAccess {
context.request().getParam(name).map(_.toBoolean)
}

def getBoolQuery(name: String, context: RoutingContext): Option[Boolean] = {
context.queryParams().get(name).map(_.toBoolean)
}

def getStringParam(name: String, context: RoutingContext): Option[String] = {
context.request().getParam(name)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ object DocumentationRouter {

class DocumentationRouter(override val config: TableauxConfig) extends BaseRouter {

private val swaggerUiVersion = "4.11.1"
private val swaggerUiVersion = "5.9.0"
private val directory = """(?<directory>[A-Za-z0-9-_\\.]{1,60}){1}"""
private val file = s"""(?<file>[A-Za-z0-9-_\\.]{1,60}){1}"""

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -665,6 +665,7 @@ class TableauxRouter(override val config: TableauxConfig, val controller: Tablea
*/
private def updateCell(context: RoutingContext): Unit = {
implicit val user = TableauxUser(context)
val forceHistory = getBoolQuery("forceHistory", context).getOrElse(false)
for {
tableId <- getTableId(context)
columnId <- getColumnId(context)
Expand All @@ -675,7 +676,7 @@ class TableauxRouter(override val config: TableauxConfig, val controller: Tablea
asyncGetReply {
val json = getJson(context)
for {
updated <- controller.updateCellValue(tableId, columnId, rowId, json.getValue("value"))
updated <- controller.updateCellValue(tableId, columnId, rowId, json.getValue("value"), forceHistory)
} yield updated
}
)
Expand All @@ -687,6 +688,7 @@ class TableauxRouter(override val config: TableauxConfig, val controller: Tablea
*/
private def replaceCell(context: RoutingContext): Unit = {
implicit val user = TableauxUser(context)
val forceHistory = getBoolQuery("forceHistory", context).getOrElse(false)
for {
tableId <- getTableId(context)
columnId <- getColumnId(context)
Expand All @@ -699,7 +701,7 @@ class TableauxRouter(override val config: TableauxConfig, val controller: Tablea
for {
updated <-
if (json.containsKey("value")) {
controller.replaceCellValue(tableId, columnId, rowId, json.getValue("value"))
controller.replaceCellValue(tableId, columnId, rowId, json.getValue("value"), forceHistory)
} else {
Future.failed(InvalidJsonException("request must contain a value", "value_is_missing"))
}
Expand Down
Loading
Loading