Skip to content

Commit dbcfae7

Browse files
Set file status to 92 when opening old indexed file (#694)
* feat: set file status 92 when opening old files * fix: set file status 92 correctly * tests: add tests for opening old indexed files * Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 70bb24c commit dbcfae7

File tree

7 files changed

+114
-0
lines changed

7 files changed

+114
-0
lines changed

libcobj/app/src/main/java/jp/osscons/opensourcecobol/libcobj/file/CobolFile.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,12 @@ public class CobolFile {
285285
/** TODO: 準備中 */
286286
protected static final int COB_STATUS_91_NOT_AVAILABLE = 91;
287287

288+
/**
289+
* File status 92: Version incompatibility.
290+
* Indicates that the file operation failed due to a version mismatch between the file and the program.
291+
*/
292+
protected static final int COB_STATUS_92_VERSION_INCOMPATIBLE = 92;
293+
288294
// ==============================================
289295
// The following constants must not be equal
290296
// to any of the above constants `COB_STATUS_*`
@@ -1103,6 +1109,9 @@ public void open(int mode, int sharing, AbstractCobolField fnstatus) {
11031109
case COB_STATUS_91_NOT_AVAILABLE:
11041110
saveStatus(COB_STATUS_91_NOT_AVAILABLE, fnstatus);
11051111
return;
1112+
case COB_STATUS_92_VERSION_INCOMPATIBLE:
1113+
saveStatus(COB_STATUS_92_VERSION_INCOMPATIBLE, fnstatus);
1114+
return;
11061115
case COB_LINAGE_INVALID:
11071116
saveStatus(COB_STATUS_57_I_O_LINAGE, fnstatus);
11081117
return;
@@ -2066,6 +2075,9 @@ public void cob_delete_file(AbstractCobolField fnstatus) {
20662075
case COB_STATUS_91_NOT_AVAILABLE:
20672076
saveStatus(COB_STATUS_91_NOT_AVAILABLE, fnstatus);
20682077
return;
2078+
case COB_STATUS_92_VERSION_INCOMPATIBLE:
2079+
saveStatus(COB_STATUS_92_VERSION_INCOMPATIBLE, fnstatus);
2080+
return;
20692081
case COB_LINAGE_INVALID:
20702082
saveStatus(COB_STATUS_57_I_O_LINAGE, fnstatus);
20712083
return;

libcobj/app/src/main/java/jp/osscons/opensourcecobol/libcobj/file/CobolIndexedFile.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,13 @@ public int open_(String filename, int mode, int sharing) {
227227
return getConnectionStatus;
228228
}
229229

230+
if(fileExists) {
231+
int code = this.checkVersionOld();
232+
if(code != COB_STATUS_00_SUCCESS) {
233+
return code;
234+
}
235+
}
236+
230237
try {
231238
// Acquire a file lock
232239
boolean succeedToFileLock = this.acquireFileLock(filename, mode, fileExists);
@@ -292,6 +299,45 @@ private int getConnection(String filename) {
292299
return COB_STATUS_00_SUCCESS;
293300
}
294301

302+
private int checkVersionOld() {
303+
IndexedFile p = this.filei;
304+
try (Statement st = p.connection.createStatement()) {
305+
String fileLockTableExistsSql =
306+
"select exists(select 1 from sqlite_master where type = 'table' and name = 'file_lock')";
307+
ResultSet fileLockTableExistsResultSet = st.executeQuery(fileLockTableExistsSql);
308+
if (fileLockTableExistsResultSet.next()) {
309+
boolean fileLockTableExists = fileLockTableExistsResultSet.getInt(1) == 1;
310+
if(!fileLockTableExists) {
311+
return COB_STATUS_92_VERSION_INCOMPATIBLE;
312+
}
313+
} else {
314+
return COB_STATUS_92_VERSION_INCOMPATIBLE; // file_lock table does not exist
315+
}
316+
317+
boolean lockedByColumnExists = false;
318+
boolean processIdColumnExists = false;
319+
boolean lockedAtColumnExists = false;
320+
try (ResultSet rs = st.executeQuery("PRAGMA table_info('table0')")) {
321+
while (rs.next()) {
322+
String columnName = rs.getString("name");
323+
if ("locked_by".equals(columnName)) {
324+
lockedByColumnExists = true;
325+
} else if ("process_id".equals(columnName)) {
326+
processIdColumnExists = true;
327+
} else if ("locked_at".equals(columnName)) {
328+
lockedAtColumnExists = true;
329+
}
330+
if (lockedByColumnExists && processIdColumnExists && lockedAtColumnExists) {
331+
return COB_STATUS_00_SUCCESS; // All required columns exist
332+
}
333+
}
334+
}
335+
} catch (SQLException e) {
336+
return COB_STATUS_30_PERMANENT_ERROR;
337+
}
338+
return COB_STATUS_92_VERSION_INCOMPATIBLE;
339+
}
340+
295341
private String getOpenModeString(int mode) {
296342
switch (mode) {
297343
case COB_OPEN_INPUT:

tests/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ indexed_lock_DEPENDENCIES = \
217217
indexed-lock.src/release-lock.at \
218218
indexed-lock.src/open-input.at \
219219
indexed-lock.src/lock-mode-clause.at \
220+
indexed-lock.src/old-file.at \
220221
indexed-lock.src/lock-mode-automatic.at
221222

222223
misc_DEPENDENCIES = \

tests/Makefile.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,7 @@ indexed_lock_DEPENDENCIES = \
756756
indexed-lock.src/release-lock.at \
757757
indexed-lock.src/open-input.at \
758758
indexed-lock.src/lock-mode-clause.at \
759+
indexed-lock.src/old-file.at \
759760
indexed-lock.src/lock-mode-automatic.at
760761

761762
misc_DEPENDENCIES = \

tests/indexed-lock.at

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ m4_include([release-lock.at])
1010
m4_include([open-input.at])
1111
m4_include([lock-mode-clause.at])
1212
m4_include([lock-mode-automatic.at])
13+
m4_include([old-file.at])
40 KB
Binary file not shown.

tests/indexed-lock.src/old-file.at

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
AT_SETUP([old file])
2+
AT_DATA([open_file_status.at], [
3+
IDENTIFICATION DIVISION.
4+
PROGRAM-ID. open_file_status.
5+
6+
ENVIRONMENT DIVISION.
7+
INPUT-OUTPUT SECTION.
8+
FILE-CONTROL.
9+
SELECT F ASSIGN TO "indexed_file.dat"
10+
ORGANIZATION IS INDEXED
11+
ACCESS MODE IS DYNAMIC
12+
RECORD KEY IS REC-KEY
13+
ALTERNATE RECORD KEY IS REC-KEY2 WITH DUPLICATES
14+
FILE STATUS IS FILE-STATUS.
15+
16+
DATA DIVISION.
17+
FILE SECTION.
18+
FD f.
19+
01 REC.
20+
05 REC-KEY PIC X(5).
21+
05 REC-KEY2 PIC X(5).
22+
05 REC-DATA PIC X(5).
23+
24+
WORKING-STORAGE SECTION.
25+
01 FILE-STATUS PIC XX.
26+
PROCEDURE DIVISION.
27+
MAIN-PROCEDURE.
28+
OPEN INPUT f.
29+
DISPLAY FILE-STATUS.
30+
CLOSE f.
31+
32+
OPEN I-O f.
33+
DISPLAY FILE-STATUS.
34+
CLOSE f.
35+
36+
OPEN EXTEND f.
37+
DISPLAY FILE-STATUS.
38+
CLOSE f.
39+
40+
OPEN OUTPUT f.
41+
DISPLAY FILE-STATUS.
42+
CLOSE f.
43+
])
44+
45+
AT_CHECK([${COBJ} open_file_status.at])
46+
AT_CHECK([cp ../../indexed-lock.src/indexed-file/old_indexed_file.dat indexed_file.dat])
47+
AT_CHECK([java open_file_status], [0],
48+
[92
49+
92
50+
92
51+
92
52+
])
53+
AT_CLEANUP

0 commit comments

Comments
 (0)