Skip to content

Commit d19bac4

Browse files
authored
Merge pull request #517 from smeup/bugfix/LS24002645/like-to-file-field-with-utilization-of-ds
Bugfix/LS24002645/LIKE to file field with utilization of DS
2 parents e469548 + 36f399e commit d19bac4

File tree

7 files changed

+148
-6
lines changed

7 files changed

+148
-6
lines changed

rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,12 @@ open class BaseCompileTimeInterpreter(
154154
private fun findSize(statements: List<RpgParser.StatementContext>, declName: String, conf: ToAstConfiguration, innerBlock: Boolean = true): Int? {
155155
statements.forEach {
156156
when {
157+
it.fspec_fixed() != null -> {
158+
val size = it.fspec_fixed().runParserRuleContext(conf) { context ->
159+
kotlin.runCatching { context.toAst(conf).let { fileDefinition -> fileDefinition.toDataDefinitions() } }.getOrNull()
160+
}?.find { dataDefinition -> dataDefinition.name.equals(declName, ignoreCase = true) }?.elementSize()
161+
if (size != null) return size
162+
}
157163
it.dspec() != null -> {
158164
val name = it.dspec().ds_name()?.text ?: it.dspec().dspecConstant().ds_name()?.text
159165
if (declName.equals(name, ignoreCase = true)) {
@@ -234,6 +240,12 @@ open class BaseCompileTimeInterpreter(
234240
statements
235241
.forEach { it ->
236242
when {
243+
it.fspec_fixed() != null -> {
244+
val type = it.fspec_fixed().runParserRuleContext(conf) { context ->
245+
kotlin.runCatching { context.toAst(conf).let { fileDefinition -> fileDefinition.toDataDefinitions() } }.getOrNull()
246+
}?.find { dataDefinition -> dataDefinition.name.equals(declName, ignoreCase = true) }?.type
247+
if (type != null) return type
248+
}
237249
it.dcl_ds() != null -> {
238250
val type = it.dcl_ds().parm_fixed().find { it.ds_name().text.equals(declName, ignoreCase = true) }?.findType(conf)
239251
if (type != null) return type

rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ private fun MutableMap<String, DataDefinition>.addIfNotPresent(dataDefinition: D
155155
dataDefinition.error("${dataDefinition.name} has been defined twice")
156156
}
157157

158-
private fun FileDefinition.toDataDefinitions(): List<DataDefinition> {
158+
internal fun FileDefinition.toDataDefinitions(): List<DataDefinition> {
159159
val dataDefinitions = mutableListOf<DataDefinition>()
160160
val reloadConfig = MainExecutionContext.getConfiguration()
161161
.reloadConfig ?: error("Not found metadata for $this because missing property reloadConfig in configuration")

rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstAndDSpecTest.kt

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,31 @@
11
package com.smeup.rpgparser.smeup
22

3+
import com.smeup.rpgparser.db.utilities.DBServer
4+
import com.smeup.rpgparser.smeup.dbmock.MULANGTLDbMock
35
import org.junit.Test
6+
import kotlin.test.AfterTest
7+
import kotlin.test.BeforeTest
48
import kotlin.test.assertEquals
59

610
open class MULANGT02ConstAndDSpecTest : MULANGTTest() {
11+
@BeforeTest
12+
override fun setUp() {
13+
if (!DBServer.isRunning()) {
14+
DBServer.startDB()
15+
}
16+
17+
super.setUp()
18+
}
19+
20+
@AfterTest()
21+
override fun tearDown() {
22+
/*
23+
* This causes `connection exception: connection failure: java.net.SocketException: Pipe interrotta (Write failed)`
24+
* during `./gradle check`
25+
*/
26+
// DBServer.stopDB()
27+
}
28+
729
/**
830
* /COPY recognized in CTDATA
931
* @see #268
@@ -158,4 +180,21 @@ open class MULANGT02ConstAndDSpecTest : MULANGTTest() {
158180
val expected = listOf("A50_A14(A) A50_B14(ABCDEFGHIJ)")
159181
assertEquals(expected, "smeup/MU025014".outputOf(configuration = smeupConfig))
160182
}
183+
184+
/**
185+
* Data definition not resolved for a specification that uses `LIKE` to a field from file. In addition,
186+
* there is a DS with an `%ELEM()` built-in function to that field.
187+
* @see #LS24002645
188+
*/
189+
@Test
190+
fun executeMUDRNRAPU00101() {
191+
MULANGTLDbMock().use {
192+
com.smeup.rpgparser.db.utilities.execute(listOf(it.createTable(), it.populateTable()))
193+
val expected = listOf("HELLO THERE")
194+
assertEquals(
195+
expected = expected,
196+
"smeup/MUDRNRAPU00101".outputOf(configuration = smeupConfig)
197+
)
198+
}
199+
}
161200
}

rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGTTest.kt

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ package com.smeup.rpgparser.smeup
33
import com.smeup.dbnative.DBNativeAccessConfig
44
import com.smeup.rpgparser.AbstractTest
55
import com.smeup.rpgparser.execution.Configuration
6+
import com.smeup.rpgparser.execution.ConnectionConfig
67
import com.smeup.rpgparser.execution.ReloadConfig
78
import com.smeup.rpgparser.execution.SimpleReloadConfig
9+
import kotlin.test.AfterTest
810
import kotlin.test.BeforeTest
911

1012
/**
@@ -14,21 +16,38 @@ import kotlin.test.BeforeTest
1416
* @see MULANGT60VideoTestCompiled see above
1517
*/
1618
abstract class MULANGTTest : AbstractTest() {
17-
1819
/**
1920
* The configuration used to execute some kind of tests, for example all test required files.
2021
* The required files are placed in the resources/smeup/metadata folder.
2122
*/
2223
lateinit var smeupConfig: Configuration
2324

2425
@BeforeTest
25-
fun setUp() {
26+
open fun setUp() {
2627
smeupConfig = Configuration()
2728
val path = javaClass.getResource("/smeup/metadata")!!.path
28-
val reloadConfig = SimpleReloadConfig(metadataPath = path, connectionConfigs = listOf())
29+
val connectionConfigs = listOf(ConnectionConfig(
30+
fileName = "*",
31+
url = "jdbc:hsqldb:hsql://127.0.0.1:9001/mainDb",
32+
user = "SA",
33+
password = "",
34+
driver = "org.hsqldb.jdbc.JDBCDriver"
35+
))
36+
val reloadConfig = SimpleReloadConfig(metadataPath = path, connectionConfigs = connectionConfigs)
2937
smeupConfig.reloadConfig = ReloadConfig(
30-
nativeAccessConfig = DBNativeAccessConfig(emptyList()),
38+
nativeAccessConfig = DBNativeAccessConfig(connectionConfigs.map {
39+
com.smeup.dbnative.ConnectionConfig(
40+
fileName = it.fileName,
41+
url = it.url,
42+
user = it.user,
43+
password = it.password,
44+
driver = it.driver,
45+
impl = it.impl
46+
)
47+
}),
3148
metadataProducer = { dbFile: String -> reloadConfig.getMetadata(dbFile = dbFile) })
32-
smeupConfig.options.debuggingInformation = true
3349
}
50+
51+
@AfterTest()
52+
open fun tearDown() {}
3453
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package com.smeup.rpgparser.smeup.dbmock
2+
3+
import com.smeup.rpgparser.interpreter.DbField
4+
import com.smeup.rpgparser.interpreter.NumberType
5+
import com.smeup.rpgparser.interpreter.StringType
6+
import kotlin.test.todo
7+
8+
interface DbMock : AutoCloseable {
9+
fun createTable(): String
10+
fun dropTable(): String
11+
fun populateTable(): String
12+
13+
override fun close() {
14+
dropTable()
15+
}
16+
17+
fun buildDbColumnsFromDbFields(fields: List<DbField>): String {
18+
return fields.mapIndexed { i, it ->
19+
when {
20+
it.type is StringType -> "${it.fieldName} VARCHAR(${it.type.size}) DEFAULT '' NOT NULL".plus(if (fields.lastIndex != i) ",\n" else "\n")
21+
it.type is NumberType -> {
22+
var columnDeclaration = it.fieldName
23+
if ((it.type as NumberType).decimal) {
24+
columnDeclaration += " DECIMAL(${(it.type as NumberType).entireDigits}, ${(it.type as NumberType).decimalDigits}) DEFAULT 0.0"
25+
} else {
26+
columnDeclaration += " BIGINT DEFAULT 0"
27+
}
28+
29+
columnDeclaration += " NOT NULL".plus(if (fields.lastIndex != i) ",\n" else "\n")
30+
31+
columnDeclaration
32+
}
33+
else -> todo { "Implements ${it.type} for 'buildDbColumnsFromDbFields'." }
34+
}
35+
}
36+
.joinToString("")
37+
}
38+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.smeup.rpgparser.smeup.dbmock
2+
3+
import com.smeup.rpgparser.interpreter.FileMetadata
4+
import java.io.File
5+
6+
class MULANGTLDbMock : DbMock {
7+
val metadata = FileMetadata.createInstance(File("src/test/resources/smeup/metadata/MULANGTL.json").inputStream())
8+
9+
override fun createTable(): String = """
10+
CREATE TABLE IF NOT EXISTS ${metadata.tableName} (
11+
${this.buildDbColumnsFromDbFields(metadata.fields)})
12+
"""
13+
.trimIndent()
14+
override fun dropTable(): String = "DROP TABLE IF EXISTS ${metadata.tableName}"
15+
override fun populateTable(): String {
16+
return """
17+
INSERT INTO ${metadata.tableName}(MLSYST, MLLIBR, MLFILE, MLTIPO, MLPROG, MLPSEZ, MLPPAS, MLPDES, MLSQIN, MLSQFI, MLAAAT, MLAAVA, MLNNAT, MLNNVA, MLINDI, MLTEES, MLUSES, MLDTES, MLORES, MLASLA, MLASNR, MLLIBE)
18+
VALUES ('FOO', 'FOO', 'FOO', 'FOO', 'FOO', 'FOO', 'FOO', 'FOO', 'FOO', 'FOO', 'FOO', 'FOO', 1.0, 1.0, 'FOO', 1, 'FOO', 1, 1, 'FOO', 1, 'FOO')
19+
"""
20+
.trimIndent()
21+
}
22+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
FMULANGTL IF E K DISK
2+
D PNCLAS S DIM(1000) LIKE(MLLIBR)
3+
D DSCLAS DS OCCURS(%ELEM(PNCLAS))
4+
D XC£GRA LIKE(MLSYST)
5+
*
6+
C EVAL MLSYST = 'HELLO THERE'
7+
C EXSR MEMREC
8+
*
9+
C MEMREC BEGSR
10+
C EVAL XC£GRA=MLSYST
11+
C XC£GRA DSPLY
12+
C ENDSR

0 commit comments

Comments
 (0)