From 53370e7cbc8dd14b2b290ef88d5885ac148e5f32 Mon Sep 17 00:00:00 2001 From: Charles KWON OhJun Date: Fri, 3 Apr 2026 19:42:50 +0900 Subject: [PATCH] test: Harbour vs Five RDD compatibility test (91% match) 47 test items comparing Harbour and Five output: - T01-T28: 100% match (CRUD, navigation, SET DELETED) - T29-T39: 100% match (SEEK exact/partial/softseek) - T40-T41: Found matches, RecNo differs (duplicate key sort stability) - T42-T43: 100% match - T44-T47: Five crashes (PACK with open index) Known issues found: - FIELD->NAME syntax not supported in INDEX ON expression - Modulo % returns Double causing array index hang (Int() workaround) - PACK crashes when NTX index is open Co-Authored-By: Claude Opus 4.6 (1M context) --- examples/rdd_compat.prg | 212 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 examples/rdd_compat.prg diff --git a/examples/rdd_compat.prg b/examples/rdd_compat.prg new file mode 100644 index 0000000..617ccc7 --- /dev/null +++ b/examples/rdd_compat.prg @@ -0,0 +1,212 @@ +// RDD Compatibility Test — Harbour vs Five +PROCEDURE Main() + LOCAL i, aStruct, nCount, aCities, nIdx + + aStruct := { ; + {"ID", "N", 6, 0}, ; + {"NAME", "C", 20, 0}, ; + {"CITY", "C", 15, 0}, ; + {"SALARY", "N", 10, 2}, ; + {"ACTIVE", "L", 1, 0} ; + } + dbCreate("compat_test", aStruct) + USE "compat_test" NEW + + aCities := {"Seoul","Tokyo","Beijing","London","NYC"} + FOR i := 1 TO 20 + APPEND BLANK + REPLACE ID WITH i + REPLACE NAME WITH PadR("Name_" + LTrim(Str(i)), 20) + nIdx := Int(((i-1) % 5)) + 1 + REPLACE CITY WITH PadR(aCities[nIdx], 15) + REPLACE SALARY WITH 30000 + i * 1000.50 + REPLACE ACTIVE WITH (i % 3 != 0) + NEXT + + Out("T01", LTrim(Str(RecCount()))) + + GO TOP + Out("T02", LTrim(Str(FieldGet(1)))) + Out("T03", RTrim(FieldGet(2))) + Out("T04", RTrim(FieldGet(3))) + Out("T05", LTrim(Str(FieldGet(4)))) + Out("T06", IIF(FieldGet(5), ".T.", ".F.")) + + GO 10 + Out("T07", LTrim(Str(FieldGet(1)))) + Out("T08", RTrim(FieldGet(2))) + + GO 20 + Out("T09", LTrim(Str(FieldGet(1)))) + Out("T10", LTrim(Str(FieldGet(4)))) + + GO TOP + Out("T11", LTrim(Str(RecNo()))) + Out("T12", IIF(BOF(), ".T.", ".F.")) + Out("T13", IIF(EOF(), ".T.", ".F.")) + + GO BOTTOM + Out("T14", LTrim(Str(RecNo()))) + + SKIP -1 + Out("T15", LTrim(Str(RecNo()))) + + GO TOP + SKIP 5 + Out("T16", LTrim(Str(RecNo()))) + + GO TOP + nCount := 0 + DO WHILE !EOF() + nCount++ + SKIP + ENDDO + Out("T17", LTrim(Str(nCount))) + Out("T18", IIF(EOF(), ".T.", ".F.")) + + GO 5 + DELETE + Out("T19", IIF(Deleted(), ".T.", ".F.")) + RECALL + Out("T20", IIF(Deleted(), ".T.", ".F.")) + + FOR i := 1 TO 20 + GO i + IF i % 3 == 0 + DELETE + ENDIF + NEXT + + nCount := 0 + GO TOP + DO WHILE !EOF() + IF Deleted() + nCount++ + ENDIF + SKIP + ENDDO + Out("T21", LTrim(Str(nCount))) + + SET DELETED OFF + GO TOP + nCount := 0 + DO WHILE !EOF() + nCount++ + SKIP + ENDDO + Out("T22", LTrim(Str(nCount))) + + SET DELETED ON + GO TOP + nCount := 0 + DO WHILE !EOF() + nCount++ + SKIP + ENDDO + Out("T23", LTrim(Str(nCount))) + + GO 1 + DELETE + SET DELETED ON + GO TOP + Out("T24", LTrim(Str(RecNo()))) + + GO 20 + DELETE + GO BOTTOM + Out("T25", LTrim(Str(RecNo()))) + + GO 1 + RECALL + GO 20 + RECALL + SET DELETED OFF + + INDEX ON NAME TO compat_idx1 + Out("T26", "OK") + + GO TOP + Out("T27", RTrim(FieldGet(2))) + Out("T28", LTrim(Str(FieldGet(1)))) + + SEEK PadR("Name_1", 20) + Out("T29", IIF(Found(), ".T.", ".F.") + " " + LTrim(Str(RecNo()))) + + SEEK PadR("Name_10", 20) + Out("T30", IIF(Found(), ".T.", ".F.") + " " + LTrim(Str(RecNo()))) + + SEEK PadR("Name_20", 20) + Out("T31", IIF(Found(), ".T.", ".F.") + " " + LTrim(Str(RecNo()))) + + SEEK PadR("Name_99", 20) + Out("T32", IIF(Found(), ".T.", ".F.") + " " + LTrim(Str(RecNo()))) + Out("T33", IIF(EOF(), ".T.", ".F.")) + + SEEK "Name_1" + Out("T34", IIF(Found(), ".T.", ".F.") + " " + LTrim(Str(RecNo()))) + + SEEK "Name_2" + Out("T35", IIF(Found(), ".T.", ".F.") + " " + LTrim(Str(RecNo()))) + + SET SOFTSEEK ON + SEEK PadR("Name_15", 20) + Out("T36", IIF(Found(), ".T.", ".F.") + " " + LTrim(Str(RecNo()))) + + SEEK PadR("Name_99", 20) + Out("T37", IIF(Found(), ".T.", ".F.") + " " + IIF(EOF(), ".T.", ".F.")) + SET SOFTSEEK OFF + + SET ORDER TO 0 + GO TOP + Out("T38", LTrim(Str(FieldGet(1)))) + + SET ORDER TO 1 + GO TOP + Out("T39", RTrim(FieldGet(2))) + + INDEX ON CITY TO compat_idx2 + SEEK PadR("Seoul", 15) + Out("T40", IIF(Found(), ".T.", ".F.") + " " + LTrim(Str(FieldGet(1)))) + + SEEK PadR("Tokyo", 15) + Out("T41", IIF(Found(), ".T.", ".F.") + " " + LTrim(Str(FieldGet(1)))) + + SEEK PadR("Paris", 15) + Out("T42", IIF(Found(), ".T.", ".F.")) + + SET ORDER TO 0 + SET DELETED OFF + nCount := 0 + GO TOP + DO WHILE !EOF() + IF Deleted() + nCount++ + ENDIF + SKIP + ENDDO + Out("T43", LTrim(Str(nCount))) + + PACK + Out("T44", LTrim(Str(RecCount()))) + + nCount := 0 + GO TOP + DO WHILE !EOF() + IF Deleted() + nCount++ + ENDIF + SKIP + ENDDO + Out("T45", LTrim(Str(nCount))) + + ZAP + Out("T46", LTrim(Str(RecCount()))) + Out("T47", IIF(EOF(), ".T.", ".F.")) + + CLOSE ALL + +RETURN + +PROCEDURE Out(cID, cVal) + ? cID + "=" + cVal +RETURN