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#1093/backend/add-decimal-digits-to-column-spec #289

Merged
merged 7 commits into from
Aug 2, 2024
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: 2 additions & 0 deletions src/main/resources/schema/schema_v37.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE system_columns
ADD COLUMN decimal_digits INT;
21 changes: 20 additions & 1 deletion src/main/resources/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -3887,6 +3887,24 @@
"type": "boolean",
"description": "Flag if the member columns should be displayed in the frontend table view (They are always displayed in entity view).",
"example": true
},
"minLength": {
"type": "integer",
"description": "Minimum length of the value, only for text columns",
"format": "int32",
"example": 1
},
"maxLength": {
"type": "integer",
"description": "Maximum length of the value, only for text columns",
"format": "int32",
"example": 255
},
"decimalDigits": {
"type": "integer",
"description": "Number of decimal digits, only for numeric columns. Values between 0 and 10 are allowed. If not set, the default value is 3.",
"format": "int32",
"example": 2
}
},
"description": "A column object, which is used to create a new column.",
Expand Down Expand Up @@ -3925,7 +3943,8 @@
2
],
"formatPattern": "city {{1}} has {{2}} inhabitants",
"showMemberColumns": true
"showMemberColumns": true,
"decimalDigits": 6
}
]
},
Expand Down
21 changes: 0 additions & 21 deletions src/main/scala/com/campudus/tableaux/arguments.scala
Original file line number Diff line number Diff line change
Expand Up @@ -109,27 +109,6 @@ object ArgumentChecker {
}
}

def isDefined(options: Seq[Option[_]], trys: Seq[Try[Option[_]]], name: String): ArgumentCheck[Unit] = {
val empty = !options.exists(_.isDefined)
val noneHaveBeenDefined = trys.forall(_.isFailure)

if (empty && noneHaveBeenDefined) {
FailArg(InvalidRequestException(s"None of these options has a (valid) value. ($name)"))
} else {
OkArg(())
}

}

def nullableValuesAreDefined(trys: Seq[Try[Option[_]]], name: String = ""): ArgumentCheck[Unit] = {
val allHaveBeenSupplied = trys.forall(_.isSuccess)
if (allHaveBeenSupplied) {
FailArg(InvalidRequestException(s"None of these options has a (valid) value. ($name)"))
} else {
OkArg(())
}
}

def oneOf[A](x: => A, list: List[A], name: String): ArgumentCheck[A] = {
if (list.contains(x)) {
OkArg(x)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -445,18 +445,19 @@ class StructureController(
tableId: TableId,
columnId: ColumnId,
columnName: Option[String],
ordering: Option[Ordering],
kind: Option[TableauxDbType],
identifier: Option[Boolean],
displayInfos: Option[Seq[DisplayInfo]],
countryCodes: Option[Seq[String]],
separator: Option[Boolean],
attributes: Option[JsonObject],
rules: Option[JsonArray],
hidden: Option[Boolean],
maxLengthTry: Try[Option[Int]],
minLengthTry: Try[Option[Int]],
showMemberColumns: Option[Boolean]
ordering: Option[Ordering] = None,
kind: Option[TableauxDbType] = None,
identifier: Option[Boolean] = None,
displayInfos: Option[Seq[DisplayInfo]] = None,
countryCodes: Option[Seq[String]] = None,
separator: Option[Boolean] = None,
attributes: Option[JsonObject] = None,
rules: Option[JsonArray] = None,
hidden: Option[Boolean] = None,
maxLength: Option[Int] = None,
minLength: Option[Int] = None,
showMemberColumns: Option[Boolean] = None,
decimalDigits: Option[Int] = None
)(implicit user: TableauxUser): Future[ColumnType[_]] = {
checkArguments(
greaterZero(tableId),
Expand All @@ -473,20 +474,16 @@ class StructureController(
attributes,
rules,
hidden,
showMemberColumns
maxLength,
minLength,
showMemberColumns,
decimalDigits
),
Seq(maxLengthTry, minLengthTry),
"name, ordering, kind, identifier, displayInfos, countryCodes, separator, attributes, rules, hidden, maxLength, minLength, showMemberColumns"
"name, ordering, kind, identifier, displayInfos, countryCodes, separator, attributes, " +
"rules, hidden, maxLength, minLength, showMemberColumns, decimalDigits"
)
)
val maxLength = maxLengthTry match {
case Failure(exception) => None
case Success(opt) => opt
}
val minLength = minLengthTry match {
case Failure(exception) => None
case Success(opt) => opt
}

val structureProperties: Seq[Option[Any]] = Seq(columnName, ordering, kind, identifier, countryCodes)
val isAtLeastOneStructureProperty: Boolean = structureProperties.exists(_.isDefined)

Expand All @@ -513,7 +510,8 @@ class StructureController(
hidden,
maxLength,
minLength,
showMemberColumns
showMemberColumns,
decimalDigits
)

for {
Expand Down
107 changes: 59 additions & 48 deletions src/main/scala/com/campudus/tableaux/database/domain/column.scala
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ sealed trait ColumnInformation {
val hidden: Boolean
val maxLength: Option[Int]
val minLength: Option[Int]
val decimalDigits: Option[Int]
}

object BasicColumnInformation {
Expand Down Expand Up @@ -64,7 +65,8 @@ object BasicColumnInformation {
attributes,
createColumn.hidden,
createColumn.maxLength,
createColumn.minLength
createColumn.minLength,
createColumn.decimalDigits
)
}
}
Expand Down Expand Up @@ -110,7 +112,8 @@ case class BasicColumnInformation(
override val attributes: JsonObject,
override val hidden: Boolean,
override val maxLength: Option[Int],
override val minLength: Option[Int]
override val minLength: Option[Int],
override val decimalDigits: Option[Int]
) extends ColumnInformation

case class StatusColumnInformation(
Expand All @@ -126,7 +129,8 @@ case class StatusColumnInformation(
val rules: JsonArray,
override val hidden: Boolean,
override val maxLength: Option[Int] = None,
override val minLength: Option[Int] = None
override val minLength: Option[Int] = None,
override val decimalDigits: Option[Int] = None
) extends ColumnInformation

case class ConcatColumnInformation(override val table: Table) extends ColumnInformation {
Expand All @@ -147,6 +151,7 @@ case class ConcatColumnInformation(override val table: Table) extends ColumnInfo
override val attributes: JsonObject = Json.obj()
override val maxLength: Option[Int] = None
override val minLength: Option[Int] = None
override val decimalDigits: Option[Int] = None
}

object ColumnType {
Expand Down Expand Up @@ -292,24 +297,27 @@ sealed trait ColumnType[+A] extends DomainObject {
columnInformation.displayInfos.foreach(displayInfo => {
displayInfo.optionalName.map(name => {
json
.mergeIn(
Json
.obj("displayName" -> json.getJsonObject("displayName").mergeIn(Json.obj(displayInfo.langtag -> name)))
)
.mergeIn(Json.obj("displayName" -> json.getJsonObject("displayName")
.mergeIn(Json.obj(displayInfo.langtag -> name))))
})

displayInfo.optionalDescription.map(desc => {
json
.mergeIn(
Json
.obj("description" -> json.getJsonObject("description").mergeIn(Json.obj(displayInfo.langtag -> desc)))
)
.mergeIn(Json.obj("description" -> json.getJsonObject("description")
.mergeIn(Json.obj(displayInfo.langtag -> desc))))
})
})
json
}

def checkValidValue[B](value: B): Try[Option[A]]

protected def getJsonPart(columnInformationFiled: Option[Any], name: String): JsonObject = {
columnInformationFiled match {
case Some(v) => Json.obj(name -> v)
case None => Json.emptyObj()
}
}
}

/**
Expand Down Expand Up @@ -410,15 +418,12 @@ case class TextColumn(override val languageType: LanguageType)(override val colu
override def checkValidSingleValue[B](value: B): Try[String] = Try(value.asInstanceOf[String])

override def getJson: JsonObject = {
val maxLength = columnInformation.maxLength match {
case None => null
case Some(num) => num
}
val minLength = columnInformation.minLength match {
case None => null
case Some(num) => num
}
super.getJson.mergeIn(Json.obj("maxLength" -> maxLength, "minLength" -> minLength))
val maxLengthJson = getJsonPart(columnInformation.maxLength, "maxLength")
val minLengthJson = getJsonPart(columnInformation.minLength, "minLength")

super.getJson
.mergeIn(maxLengthJson)
.mergeIn(minLengthJson)
}
}

Expand All @@ -430,15 +435,12 @@ case class ShortTextColumn(override val languageType: LanguageType)(override val
override def checkValidSingleValue[B](value: B): Try[String] = Try(value.asInstanceOf[String])

override def getJson: JsonObject = {
val maxLength = columnInformation.maxLength match {
case None => null
case Some(num) => num
}
val minLength = columnInformation.minLength match {
case None => null
case Some(num) => num
}
super.getJson.mergeIn(Json.obj("maxLength" -> maxLength, "minLength" -> minLength))
val maxLengthJson = getJsonPart(columnInformation.maxLength, "maxLength")
val minLengthJson = getJsonPart(columnInformation.minLength, "minLength")

super.getJson
.mergeIn(maxLengthJson)
.mergeIn(minLengthJson)
}
}

Expand All @@ -450,15 +452,12 @@ case class RichTextColumn(override val languageType: LanguageType)(override val
override def checkValidSingleValue[B](value: B): Try[String] = Try(value.asInstanceOf[String])

override def getJson: JsonObject = {
val maxLength = columnInformation.maxLength match {
case None => null
case Some(num) => num
}
val minLength = columnInformation.minLength match {
case None => null
case Some(num) => num
}
super.getJson.mergeIn(Json.obj("maxLength" -> maxLength, "minLength" -> minLength))
val maxLengthJson = getJsonPart(columnInformation.maxLength, "maxLength")
val minLengthJson = getJsonPart(columnInformation.minLength, "minLength")

super.getJson
.mergeIn(maxLengthJson)
.mergeIn(minLengthJson)
}
}

Expand All @@ -467,6 +466,12 @@ case class NumberColumn(override val languageType: LanguageType)(override val co
val user: TableauxUser
) extends SimpleValueColumn[Number](NumericType)(languageType) {

override def getJson: JsonObject = {
val decimalDigitsJson = getJsonPart(columnInformation.decimalDigits, "decimalDigits")

super.getJson
.mergeIn(decimalDigitsJson)
}
override def checkValidSingleValue[B](value: B): Try[Number] = Try(value.asInstanceOf[Number])
}

Expand Down Expand Up @@ -528,16 +533,19 @@ case class LinkColumn(
override val languageType: LanguageType = to.languageType

override def getJson: JsonObject = {
val constraintJson = linkDirection.constraint.getJson
val baseJson = Json.obj(
"toTable" -> to.table.id,
"toColumn" -> to.getJson
)

val constraintJson = linkDirection.constraint.getJson match {
case json if json.isEmpty => Json.emptyObj()
case json => Json.obj("constraint" -> json)
}

super.getJson
.mergeIn(
Json.obj(
"toTable" -> to.table.id,
"toColumn" -> to.getJson
)
)
.mergeIn(if (constraintJson.isEmpty) Json.emptyObj() else Json.obj("constraint" -> constraintJson))
.mergeIn(baseJson)
.mergeIn(constraintJson)
}

override def checkValidValue[B](value: B): Try[Option[Seq[RowId]]] = {
Expand Down Expand Up @@ -721,7 +729,7 @@ case class GroupColumn(
override val kind: GroupType.type = GroupType

override def getJson: JsonObject = {
val json = super.getJson.mergeIn(Json.obj("groups" -> columns.map(_.getJson)))
val groupsJson = Json.obj("groups" -> columns.map(_.getJson))

val formatPatternJson = formatPattern match {
case Some(pattern) => Json.obj("formatPattern" -> pattern)
Expand All @@ -733,7 +741,10 @@ case class GroupColumn(
case false => Json.emptyObj()
}

json.mergeIn(formatPatternJson).mergeIn(showMemberColumnsJson)
super.getJson
.mergeIn(groupsJson)
.mergeIn(formatPatternJson)
.mergeIn(showMemberColumnsJson)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ sealed trait CreateColumn {
val hidden: Boolean
val maxLength: Option[Int] = None
val minLength: Option[Int] = None
val decimalDigits: Option[Int] = None
}

case class CreateSimpleColumn(
Expand All @@ -30,7 +31,8 @@ case class CreateSimpleColumn(
override val attributes: Option[JsonObject],
override val hidden: Boolean = false,
override val maxLength: Option[Int] = None,
override val minLength: Option[Int] = None
override val minLength: Option[Int] = None,
override val decimalDigits: Option[Int] = None
) extends CreateColumn

case class CreateBackLinkColumn(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,8 @@ class SystemModel(override protected[this] val connection: DatabaseConnection) e
setupVersion(readSchemaFile("schema_v33"), 33),
setupVersion(readSchemaFile("schema_v34"), 34),
setupVersion(readSchemaFile("schema_v35"), 35),
setupVersion(readSchemaFile("schema_v36"), 36)
setupVersion(readSchemaFile("schema_v36"), 36),
setupVersion(readSchemaFile("schema_v37"), 37)
)

private val setupShortCutFunction: Seq[DbTransaction => Future[DbTransaction]] = Seq(
Expand Down
Loading
Loading