Skip to content

Commit 53f5998

Browse files
authored
v1.0.0 (#21)
2 parents 5e45180 + b22e2ca commit 53f5998

File tree

155 files changed

+48644
-802
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

155 files changed

+48644
-802
lines changed

.gitignore

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,4 +100,10 @@ dblibj/.idea/httpRequests
100100
# Android studio 3.1+ serialized cache file
101101
dblibj/.idea/caches/build_file_checksums.ser
102102

103-
103+
#####################
104+
.tags
105+
*.jar
106+
dblibj/lib/~BROMIUM/
107+
dblibj/project/target/active.json
108+
*.class
109+
*.cache

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Under construction

ChangeLog

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Under Construction

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Under Construction

README

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
See README.md

README.md

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ Open COBOL ESQL 4j (OCESQL 4j) consits of open-source Embedded SQL pre-compiler
2020
Run the following commands.
2121

2222
```sh
23-
./configure
23+
autoreconf --force --install
24+
./configure --prefix=/usr/
2425
make
2526
make install
2627
```
@@ -50,10 +51,6 @@ See test cases or sample programs.
5051

5152
# TODO
5253

53-
- [ ] Implement Prepared Statement.
54-
- [ ] Support other COBOL data types (COMP5, Japanese, ... etc).
55-
- [ ] Add test cases.
56-
- [ ] tests for SQL CA(communication area).
57-
- [ ] tests for SQL data types.
54+
- [ ] Support other COBOL data types (COMP3, SIGN LEADING, ... etc).
5855
- [ ] Set up test environments using Github Actions.
5956
- [ ] Create docker images.

dblibj/.idea/modules/OCESQL4j.iml

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dblibj/build.sbt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ val catsCore = "org.typelevel" %% "cats-core" % "2.6.1"
88
val catsFree = "org.typelevel" %% "cats-free" % "2.6.1"
99
val scalaTest = "org.scalatest" %% "scalatest" % "3.0.8" % Test
1010

11+
unmanagedJars in Compile += file("lib/postgresql-42.2.24.jre6.jar")
12+
1113
libraryDependencies ++= Seq(
1214
catsCore,
1315
catsFree,

dblibj/src/main/scala/Common.scala

Lines changed: 114 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import java.sql._
66
import ConnectionInfo.ConnectionMap
77
import jp.osscons.opensourcecobol.libcobj.data.CobolDataStorage
88

9+
import java.nio.ByteBuffer
910
import scala.collection.immutable.Queue
1011

1112
object Common {
@@ -204,43 +205,27 @@ object Common {
204205
def setLibErrorStatus(errorCode: SqlCode): Operation[Int] =
205206
OCDB_PGSetLibErrorStatus(errorCode)
206207

207-
def setResultStatus(id: Int): Operation[Boolean] = (for {
208-
keyAndValue <- operationCPure(lookUpConnList(id))
209-
210-
_ <- whenExecuteAndExit(keyAndValue.isEmpty, operationPure(false))
211-
212-
kv <- operationCPure(operationPure(keyAndValue.getOrElse(("", ConnectionInfo.defaultValue))))
213-
key <- operationCPure(operationPure(kv._1))
214-
pConn <- operationCPure(operationPure(kv._2))
215-
216-
//[remark] temporary implementation
217-
//_ <- whenExecuteAndExit(pConn.result == OCDB_RES_DEFAULT_ADDRESS && pConn.result <= RESULT_FLAGBASE,
218-
_ <- whenExecuteAndExit(pConn.result.isLeft,
219-
operationPure(false))
220-
221-
//[remark] temporary implementation
222-
/*returnValue <- if(pConn.result == RESULT_FLAG1_PGSQL_DUMMYOPEN) {
223-
operationCPure[Int, Int](operationPure(RESULT_SUCCESS))
224-
} else {
225-
operationCPure[Int, Int](OCDB_PGSetResultStatus(pConn.result))
226-
}*/
227-
returnValue <- operationCPure(OCDB_PGSetResultStatus(pConn.result))
228-
} yield returnValue).eval
208+
def setResultStatus(id: Int): Operation[Boolean] =
209+
lookUpConnList(id).flatMap(_ match {
210+
case None => operationPure(false)
211+
case Some((_, pConn)) => OCDB_PGSetResultStatus(pConn.result)
212+
})
229213

230214
/**
231-
* [remark] temporary implementation
232-
* Equivalent to OCDB_PGSetResultStatus in dblib/ocpgsql.c
215+
* Implementation of OCDB_PGSetResultStatus in dblib/ocpgsql.c (Open-COBOL-ESQL)
216+
* Regardless of the pretious SQL execution, sqlErrorCode is zero.
217+
* If the pretious SQL execution fails, sqlState equals to PSQLState.
218+
* (https://github.com/pgjdbc/pgjdbc/blob/8be516d47ece60b7aeba5a9474b5cac1d538a04a/pgjdbc/src/main/java/org/postgresql/util/PSQLState.java)
233219
* @param connAddr
234-
* @return
220+
* @return true if and only if the previous SQL execution is successful.
235221
*/
236222
def OCDB_PGSetResultStatus(result: ExecResult): Operation[Boolean] = {
237223
val (sqlCode, sqlState) = result match {
238224
case Right(_) => (OCPG_NO_ERROR, "00000")
239-
case Left(e) => (e.getErrorCode, e.getSQLState)
225+
case Left(e) => (e.getErrorCode, Option(e.getSQLState).getOrElse("00000"))
240226
}
241227
for {
242-
state <- getState
243-
_ <- setState({
228+
_ <- updateState(state => {
244229
val sqlCA = state.sqlCA
245230
val newSqlCA = sqlCA.setCode(sqlCode).setState(sqlState.getBytes)
246231
state.setSqlCA(newSqlCA)
@@ -365,22 +350,42 @@ object Common {
365350
case OCDB_TYPE_JAPANESE_VARYING => createCobolDataJapaneseVarying(sv, addr, index, resultData)
366351
}
367352
}
368-
369-
private def createCobolDataUnsignedNumber(sv: SQLVar, addr: CobolDataStorage, index: Int, data: scala.Array[Byte]): Unit = {
353+
354+
//[TODO] improve the algorithm
355+
private def createCobolDataUnsignedNumber(sv: SQLVar, addr: CobolDataStorage, index: Int, str: scala.Array[Byte]): Unit = {
370356
val finalBuf: scala.Array[Byte] = new scala.Array(sv.length)
371-
val isNegative = data(0) == '-'.toByte
357+
val isNegative = str(0) == '-'.toByte
372358
val valueFirstIndex = if(isNegative) {1} else {0}
373-
374359
val indexOfDecimalPoint = {
375-
val index = data.indexOf('.')
376-
if(index < 0) { data.length } else { index }
360+
val index = str.indexOf('.')
361+
if(index < 0) { str.length } else { index }
377362
}
363+
378364
for(i <- 0 until finalBuf.length) {
379365
finalBuf(i) = '0'.toByte
380366
}
381-
for(i <- valueFirstIndex until indexOfDecimalPoint) {
382-
finalBuf(i + finalBuf.length - (indexOfDecimalPoint + sv.power)) = data(i)
367+
368+
if(sv.power >= 0) {
369+
for(i <- valueFirstIndex until indexOfDecimalPoint) {
370+
finalBuf(i + finalBuf.length - (indexOfDecimalPoint + sv.power)) = str(i)
371+
}
372+
} else {
373+
var i = sv.length + sv.power - 1
374+
var j = indexOfDecimalPoint - 1
375+
while(i >= 0 && j >= valueFirstIndex) {
376+
finalBuf(i) = str(j)
377+
i -= 1
378+
j -= 1
379+
}
380+
i = sv.length + sv.power
381+
j = indexOfDecimalPoint + 1
382+
while(i < sv.length && j < str.length) {
383+
finalBuf(i) = str(j)
384+
i += 1
385+
j += 1
386+
}
383387
}
388+
384389
for(i <- 0 until finalBuf.length) {
385390
addr.setByte(i, finalBuf(i))
386391
}
@@ -390,17 +395,36 @@ object Common {
390395
val finalBuf: scala.Array[Byte] = new scala.Array(sv.length)
391396
val isNegative = str(0) == '-'.toByte
392397
val valueFirstIndex = if(isNegative) {1} else {0}
393-
394398
val indexOfDecimalPoint = {
395399
val index = str.indexOf('.')
396400
if(index < 0) { str.length } else { index }
397401
}
402+
398403
for(i <- 0 until finalBuf.length) {
399404
finalBuf(i) = '0'.toByte
400405
}
401-
for(i <- valueFirstIndex until indexOfDecimalPoint) {
402-
finalBuf(i + finalBuf.length - (indexOfDecimalPoint + sv.power)) = str(i)
406+
407+
if(sv.power >= 0) {
408+
for(i <- valueFirstIndex until indexOfDecimalPoint) {
409+
finalBuf(i + finalBuf.length - (indexOfDecimalPoint + sv.power)) = str(i)
410+
}
411+
} else {
412+
var i = sv.length + sv.power - 1
413+
var j = indexOfDecimalPoint - 1
414+
while(i >= 0 && j >= valueFirstIndex) {
415+
finalBuf(i) = str(j)
416+
i -= 1
417+
j -= 1
418+
}
419+
i = sv.length + sv.power
420+
j = indexOfDecimalPoint + 1
421+
while(i < sv.length && j < str.length) {
422+
finalBuf(i) = str(j)
423+
i += 1
424+
j += 1
425+
}
403426
}
427+
404428
if(isNegative) {
405429
val finalByte = finalBuf(finalBuf.length - 1)
406430
finalBuf(finalBuf.length - 1) = (finalByte + 0x40).toByte
@@ -411,15 +435,58 @@ object Common {
411435
}
412436

413437
private def createCobolDataSignedNumberLs(sv: SQLVar, addr: CobolDataStorage, i: Int, str: scala.Array[Byte]): Unit = {
414-
//TODO Implement
438+
val finalBuf: scala.Array[Byte] = new scala.Array(sv.length)
439+
val isNegative = str(0) == '-'.toByte
440+
val valueFirstIndex = if(isNegative) {1} else {0}
441+
val indexOfDecimalPoint = {
442+
val index = str.indexOf('.')
443+
if(index < 0) { str.length } else { index }
444+
}
445+
446+
for(i <- 0 until finalBuf.length) {
447+
finalBuf(i) = '0'.toByte
448+
}
449+
450+
if(sv.power >= 0) {
451+
for(i <- valueFirstIndex until indexOfDecimalPoint) {
452+
finalBuf(i + finalBuf.length - (indexOfDecimalPoint + sv.power)) = str(i)
453+
}
454+
} else {
455+
var i = sv.length + sv.power
456+
var j = indexOfDecimalPoint - 1
457+
while(i >= 1 && j >= valueFirstIndex) {
458+
finalBuf(i) = str(j)
459+
i -= 1
460+
j -= 1
461+
}
462+
i = sv.length + sv.power + 1
463+
j = indexOfDecimalPoint + 1
464+
while(i < sv.length && j < str.length) {
465+
finalBuf(i) = str(j)
466+
i += 1
467+
j += 1
468+
}
469+
}
470+
471+
finalBuf(0) = (if(isNegative) {'-'} else {'+'}).toByte
472+
for(i <- 0 until finalBuf.length) {
473+
addr.setByte(i, finalBuf(i))
474+
}
415475
}
416476

417477
private def createCobolDataUnsignedNumberPd(sv: SQLVar, addr: CobolDataStorage, i: Int, str: scala.Array[Byte]): Unit = {
418478
//TODO Implement
419479
}
420480

421481
private def createCobolDataSignedNumberPd(sv: SQLVar, addr: CobolDataStorage, i: Int, str: scala.Array[Byte]): Unit = {
422-
//TODO Implement
482+
println("createCobolDataSignedNumberPd 1")
483+
val n = Integer.parseInt(new String(str))
484+
println(s"n: ${n}")
485+
val bytes = new scala.Array[Byte](4)
486+
ByteBuffer.wrap(bytes).putInt(n)
487+
for(i <- 0 until 4) {
488+
addr.setByte(i, bytes(i))
489+
}
423490
}
424491

425492
private def createCobolDataAlphanumeric(sv: SQLVar, addr: CobolDataStorage, i: Int, str: scala.Array[Byte]): Unit = {
@@ -432,7 +499,12 @@ object Common {
432499
}
433500

434501
private def createCobolDataJapanese(sv: SQLVar, addr: CobolDataStorage, i: Int, str: scala.Array[Byte]): Unit = {
435-
//TODO Implement
502+
if(str.length >= sv.length * 2) {
503+
addr.memcpy(str, sv.length * 2)
504+
} else {
505+
addr.memset(' '.toByte, sv.length * 2)
506+
addr.memcpy(str, str.length)
507+
}
436508
}
437509

438510
private def createCobolDataAlphanumericVarying(sv: SQLVar, addr: CobolDataStorage, i: Int, str: scala.Array[Byte]): Unit = {

dblibj/src/main/scala/Connect.scala

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import ConstValues._
22
import Operation._
33
import Common._
4-
import cats.syntax.flatMap
54

65
import java.sql._
76

@@ -67,12 +66,12 @@ object OCESQLConnectCore {
6766
_ <- logLnC(s"publish connect Id: ${connectId}")
6867

6968
_ <- whenExecuteAndExit(connectId == OCDB_CONN_FAIL_CONNECT, for {
70-
_ <- setLibErrorStatus(OCDB_NO_ERROR())
69+
_ <- setLibErrorStatus(OCDB_CONNECT())
7170
_ <- errorLogLn(s"connection failed. connect param is :${connStr}")
7271
} yield 1)
7372

7473
_ <- whenExecuteAndExit(connectId == INVALID_CONN_ID, for {
75-
_ <- setLibErrorStatus(OCDB_NO_ERROR())
74+
_ <- setLibErrorStatus(OCDB_CONNECT())
7675
_ <- errorLogLn(s"connection failed. connect param is :${connStr}")
7776
} yield 1)
7877

dblibj/src/main/scala/ConstValues.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,4 +142,6 @@ object ConstValues {
142142
case class OCDB_READ_NEXT() extends ReadDirection
143143
case class OCDB_READ_PREVIOUS() extends ReadDirection
144144
case class OCDB_READ_CURRENT() extends ReadDirection
145+
146+
val DATA_SIZE_OF_SQL_COMMAND_LEN = 9
145147
}

0 commit comments

Comments
 (0)