WIP: Compiled SQL function #33

Draft
flecomte wants to merge 37 commits from compiled_sql_function into master
2 changed files with 32 additions and 32 deletions
Showing only changes of commit 6f6e9f6560 - Show all commits

View File

@@ -59,7 +59,7 @@ class Function(
ScriptPart(script) ScriptPart(script)
.getFunctionOrProcedure().trimSpace().nextScriptPart .getFunctionOrProcedure().trimSpace().nextScriptPart
.getFunctionName().apply { name = value }.nextScriptPart .getFunctionName().apply { name = value }.nextScriptPart
.getArguments().apply { parameters = value }.nextScriptPart .getParameters().apply { parameters = value }.nextScriptPart
// .getReturns().hook { returns = value } // .getReturns().hook { returns = value }
} }
@@ -189,17 +189,17 @@ class Function(
return NextScript(digits.toIntOrNull(), restOfScript).trimSpace() return NextScript(digits.toIntOrNull(), restOfScript).trimSpace()
} }
private fun ScriptPart.getArguments(): NextScript<List<Parameter>> { private fun ScriptPart.getParameters(): NextScript<List<Parameter>> {
val allArgumentsScript = this.getNextScript { val allParametersScript = this.getNextScript {
currentChar == ')' && status.isNotEscaped() currentChar == ')' && status.isNotEscaped()
} }
val arguments: List<Parameter> = allArgumentsScript val parameterList: List<Parameter> = allParametersScript
.valueAsScriptPart() .valueAsScriptPart()
.removeParentheses() .removeParentheses()
.split(",") .split(",")
.map { it.toArgument() } .map { it.toParameter() }
return NextScript(arguments.toList(), allArgumentsScript.restOfScript) return NextScript(parameterList, allParametersScript.restOfScript)
} }
private fun ScriptPart.trimSpace(): ScriptPart { private fun ScriptPart.trimSpace(): ScriptPart {
@@ -242,17 +242,17 @@ class Function(
} }
} }
private fun ScriptPart.toArgument(): Parameter { private fun ScriptPart.toParameter(): Parameter {
var script: ScriptPart = this.trimSpace() var script: ScriptPart = this.trimSpace()
return Parameter( return Parameter(
direction = script.getArgMode().apply { script = nextScriptPart }.value, direction = script.getParameterMode().apply { script = nextScriptPart }.value,
name = script.getArgName().trimSpace().apply { script = nextScriptPart }.value.trim(), name = script.getParameterName().trimSpace().apply { script = nextScriptPart }.value.trim(),
type = script.getArgType().trimSpace().apply { script = nextScriptPart }.value, type = script.getParameterType().trimSpace().apply { script = nextScriptPart }.value,
default = script.getArgDefault().trimSpace().apply { script = nextScriptPart }.value, default = script.getParameterDefault().trimSpace().apply { script = nextScriptPart }.value,
) )
} }
private fun ScriptPart.getArgMode(): NextScript<Direction> { private fun ScriptPart.getParameterMode(): NextScript<Direction> {
return when { return when {
restOfScript.startsWith("inout ", true) -> NextScript(Direction.INOUT, restOfScript.drop("inout ".length)) restOfScript.startsWith("inout ", true) -> NextScript(Direction.INOUT, restOfScript.drop("inout ".length))
restOfScript.startsWith("in ", true) -> NextScript(Direction.IN, restOfScript.drop("in ".length)) restOfScript.startsWith("in ", true) -> NextScript(Direction.IN, restOfScript.drop("in ".length))
@@ -261,20 +261,20 @@ class Function(
} }
} }
private fun ScriptPart.getArgName(): NextScript<String> { private fun ScriptPart.getParameterName(): NextScript<String> {
try { try {
return getNextScript { afterBeginBy(" ", "\n") } return getNextScript { afterBeginBy(" ", "\n") }
} catch (e: NameMalformed) { } catch (e: NameMalformed) {
throw ArgNameMalformed(null, e) throw ParameterNameMalformed(null, e)
} }
} }
private fun ScriptPart.getArgType(): NextScript<ArgumentType> { private fun ScriptPart.getParameterType(): NextScript<ParameterType> {
val fullType = try { val fullType = try {
val endTextList = arrayOf(" default ", "=", ")") val endTextList = arrayOf(" default ", "=", ")")
getNextScript { afterBeginBy(texts = endTextList) } getNextScript { afterBeginBy(texts = endTextList) }
} catch (e: ParseError) { } catch (e: ParseError) {
throw ArgTypeMalformed(null, e) throw ParameterTypeMalformed(null, e)
} }
var rest: ScriptPart = fullType.valueAsScriptPart() var rest: ScriptPart = fullType.valueAsScriptPart()
@@ -290,7 +290,7 @@ class Function(
.apply { rest = nextScriptPart } .apply { rest = nextScriptPart }
return NextScript( return NextScript(
ArgumentType( ParameterType(
name = name.value.trim(), name = name.value.trim(),
precision = precision.value, precision = precision.value,
scale = scale.value scale = scale.value
@@ -298,14 +298,14 @@ class Function(
) )
} }
private fun ScriptPart.getArgDefault(): NextScript<String?> { private fun ScriptPart.getParameterDefault(): NextScript<String?> {
return if (this.isEmpty() || this.restOfScript == ")") { return if (this.isEmpty() || this.restOfScript == ")") {
NextScript(null, "") NextScript(null, "")
} else { } else {
"""^(\s*=\s*|\s+default\s+)(.+)\s*$""" """^(\s*=\s*|\s+default\s+)(.+)\s*$"""
.toRegex(IGNORE_CASE) .toRegex(IGNORE_CASE)
.find(restOfScript) .find(restOfScript)
.let { it ?: throw ArgDefaultMalformed() } .let { it ?: throw ParameterDefaultMalformed() }
.let { it.groups[2]!!.value } .let { it.groups[2]!!.value }
.let { NextScript(it, "") } .let { NextScript(it, "") }
} }
@@ -319,21 +319,21 @@ class Function(
} }
class FunctionNotFound(cause: Throwable? = null): Resource.ParseException("Function not found in script", cause) class FunctionNotFound(cause: Throwable? = null): Resource.ParseException("Function not found in script", cause)
class ArgumentNotFound(cause: Throwable? = null): Resource.ParseException("Argument not found in script", cause) class ParameterNotFound(cause: Throwable? = null): Resource.ParseException("Parameter not found in script", cause)
class FunctionNameMalformed(message: String? = null, cause: Throwable? = null): class FunctionNameMalformed(message: String? = null, cause: Throwable? = null):
Resource.ParseException(message ?: "Function name is malformed", cause) Resource.ParseException(message ?: "Function name is malformed", cause)
class ArgNameMalformed(message: String? = null, cause: Throwable? = null): class ParameterNameMalformed(message: String? = null, cause: Throwable? = null):
Resource.ParseException(message ?: "Arg name is malformed", cause) Resource.ParseException(message ?: "Parameter name is malformed", cause)
class ArgTypeMalformed(message: String? = null, cause: Throwable? = null): class ParameterTypeMalformed(message: String? = null, cause: Throwable? = null):
Resource.ParseException(message ?: "Arg type is malformed", cause) Resource.ParseException(message ?: "Parameter type is malformed", cause)
class ArgDefaultMalformed(message: String? = null, cause: Throwable? = null): class ParameterDefaultMalformed(message: String? = null, cause: Throwable? = null):
Resource.ParseException(message ?: "Arg default is malformed", cause) Resource.ParseException(message ?: "Parameter default is malformed", cause)
class NameMalformed(message: String? = null, cause: Throwable? = null): class NameMalformed(message: String? = null, cause: Throwable? = null):
Resource.ParseException(message ?: "name is malformed", cause) Resource.ParseException(message ?: "Name is malformed", cause)
class ParseError(message: String? = null, cause: Throwable? = null): class ParseError(message: String? = null, cause: Throwable? = null):
Resource.ParseException(message ?: "Parsing fail", cause) Resource.ParseException(message ?: "Parsing fail", cause)
@@ -385,7 +385,7 @@ class Function(
): Returns(definition, isSetOf) { ): Returns(definition, isSetOf) {
class ParameterTable( class ParameterTable(
override val name: String, override val name: String,
override val type: ArgumentType, override val type: ParameterType,
): ParameterSimpleI ): ParameterSimpleI
} }

View File

@@ -2,7 +2,7 @@ package fr.postgresjson.definition
import java.util.Locale import java.util.Locale
class ArgumentType( class ParameterType(
val name: String, val name: String,
val precision: Int? = null, val precision: Int? = null,
val scale: Int? = null, val scale: Int? = null,
@@ -21,16 +21,16 @@ class ArgumentType(
interface ParameterSimpleI { interface ParameterSimpleI {
val name: String? val name: String?
val type: ArgumentType val type: ParameterType
} }
class Parameter( class Parameter(
override val name: String?, override val name: String?,
override val type: ArgumentType, override val type: ParameterType,
val direction: Direction = Direction.IN, val direction: Direction = Direction.IN,
val default: String? = null, val default: String? = null,
): ParameterSimpleI { ): ParameterSimpleI {
constructor(name: String?, type: ArgumentType, direction: String = "IN", default: String? = null): this( constructor(name: String?, type: ParameterType, direction: String = "IN", default: String? = null): this(
name = name, name = name,
type = type, type = type,
direction = direction.let { Direction.valueOf(direction.uppercase(Locale.getDefault())) }, direction = direction.let { Direction.valueOf(direction.uppercase(Locale.getDefault())) },