BLOCK-LEVEL ON ERROR UNDO, THROW.

USING OpenEdge.Core.Assert FROM PROPATH.

CLASS tests.TestBatch:
    @Setup.
    METHOD PUBLIC VOID Setup():
        DEFINE VARIABLE i AS INTEGER NO-UNDO.
        FOR EACH table1:
            DELETE table1.
        END.
        FOR EACH table2:
            DELETE table2.
        END.
        DO i = 1 TO 100:
            CREATE table1.
            ASSIGN
                table1.f1 = "f1 " + STRING(i)
                table1.f2 = "f2 " + STRING(i)
                table1.f3 = "f3 " + STRING(i)
                table1.f4 = "f4 " + STRING(i)
                table1.f5 = "f5 " + STRING(i)
                table1.f6 = "f6 " + STRING(i)
                table1.f7 = "f7 " + STRING(i)
                table1.f8 = "f8 " + STRING(i)
                table1.f9 = "f9 " + STRING(i)
                table1.f10 = "f10 " + STRING(i).
        END.
    END.
    
    METHOD PUBLIC VOID DoStuff(idx AS INTEGER):
        DEFINE BUFFER buf1 FOR table1.
        DO TRANSACTION:
            FIND FIRST buf1 WHERE RECID(buf1) = RECID(table1) NO-ERROR.
            IF NOT AVAILABLE(buf1) THEN
                RETURN.
            CREATE table2.
            table2.f1 = buf1.f1.
            IF idx = 51 THEN DO:
                DELETE buf1.
            END.
        END.
    END.
    
    @TearDown.
    METHOD PUBLIC VOID Cleanup():
        FOR EACH table1:
            DELETE table1.
        END.
        FOR EACH table2:
            DELETE table2.
        END.
    END.
    
    @Test.
    METHOD PUBLIC VOID TestShareLock():
        DEFINE VARIABLE i AS INTEGER NO-UNDO.
        DEFINE VARIABLE deletedIdx AS INTEGER NO-UNDO.
        DEFINE VARIABLE ids AS CHARACTER NO-UNDO EXTENT 100.

        i = 1.
        FOR EACH table1 NO-LOCK:
            ids[i] = table1.f1.
            i = i + 1.
        END.
        
        i = 1.
        FOR EACH table1:
            Assert:Equals(ids[i], table1.f1).
            DO TRANSACTION:
                CREATE table2.
                ASSIGN
                    table2.f1 = table1.f1
                    i = i + 1.
                IF i = 51 THEN DO:
                    ASSIGN
                        deletedIdx = 50.
                    DELETE table1.
                END.
            END.
        END.
        
        i = 1.
        FOR EACH table1 NO-LOCK:
            IF i = deletedIdx THEN
                i = i + 1.
            Assert:Equals(ids[i], table1.f1).
            i = i + 1.
        END.
        
        i = 1.
        FOR EACH table2 NO-LOCK:
            Assert:Equals(ids[i], table2.f1).
            i = i + 1.
        END.
    END.
    
    @Test.
    METHOD PUBLIC VOID TestNoLock():
        DEFINE VARIABLE i AS INTEGER NO-UNDO.
        DEFINE VARIABLE deletedIdx AS INTEGER NO-UNDO.
        DEFINE VARIABLE ids AS CHARACTER NO-UNDO EXTENT 100.
        DEFINE BUFFER buf1 FOR table1.

        i = 1.
        FOR EACH table1 NO-LOCK:
            ids[i] = table1.f1.
            i = i + 1.
        END.
        
        i = 1.
        FOR EACH table1 NO-LOCK:
            Assert:Equals(ids[i], table1.f1).
            DO TRANSACTION:
                FIND FIRST buf1 WHERE RECID(buf1) = RECID(table1).
                CREATE table2.
                ASSIGN
                    table2.f1 = buf1.f1
                    i = i + 1.
                IF i = 51 THEN DO:
                    ASSIGN
                        deletedIdx = 50.
                    DELETE buf1.
                END.
            END.
        END.
        
        i = 1.
        FOR EACH table1 NO-LOCK:
            IF i = deletedIdx THEN
                i = i + 1.
            Assert:Equals(ids[i], table1.f1).
            i = i + 1.
        END.
        
        i = 1.
        FOR EACH table2 NO-LOCK:
            Assert:Equals(ids[i], table2.f1).
            i = i + 1.
        END.
    END.
    
    @Test.
    METHOD PUBLIC VOID TestNoLockMethod():
        DEFINE VARIABLE i AS INTEGER NO-UNDO.
        DEFINE VARIABLE deletedIdx AS INTEGER NO-UNDO.
        DEFINE VARIABLE ids AS CHARACTER NO-UNDO EXTENT 100.
        DEFINE BUFFER buf1 FOR table1.

        i = 1.
        FOR EACH table1 NO-LOCK:
            ids[i] = table1.f1.
            i = i + 1.
        END.
        
        i = 1.
        FOR EACH table1 NO-LOCK:
            Assert:Equals(ids[i], table1.f1).
            DO TRANSACTION:
                i = i + 1.
                DoStuff(i).
                IF i = 51 THEN
                    deletedIdx = 50.
            END.
        END.
        
        i = 1.
        FOR EACH table1 NO-LOCK:
            IF i = deletedIdx THEN
                i = i + 1.
            Assert:Equals(ids[i], table1.f1).
            i = i + 1.
        END.
        
        i = 1.
        FOR EACH table2 NO-LOCK:
            Assert:Equals(ids[i], table2.f1).
            i = i + 1.
        END.
    END.
    
    @Test.
    METHOD PUBLIC VOID TestPreselectQuery():
        DEFINE BUFFER buf2 FOR table1.
        DEFINE QUERY q1 FOR buf2.
        DEFINE VARIABLE i AS INTEGER NO-UNDO INITIAL 1.
        DEFINE VARIABLE deletedIdx AS INTEGER NO-UNDO.
        DEFINE VARIABLE ids AS CHARACTER NO-UNDO EXTENT 100.
        
        FOR EACH table1 NO-LOCK:
            ids[i] = table1.f1.
            i = i + 1.
        END.
        
        OPEN QUERY q1 PRESELECT EACH buf2 NO-LOCK.
        Assert:Equals(100, NUM-RESULTS("q1")).
        
        i = 1.
        FOR EACH table1 NO-LOCK:
            Assert:Equals(ids[i], table1.f1).
            DO TRANSACTION:
                i = i + 1.
                DoStuff(i).
                IF i = 51 THEN
                    deletedIdx = 50.
            END.
        END.
        
        i = 1.
        GET FIRST q1.
        DO WHILE AVAILABLE (buf2):
            Assert:Equals(ids[i], buf2.f1).
            DO TRANSACTION:
                i = i + 1.
                DoStuff(i).
                IF i = 50 THEN DO:
                    deletedIdx = 50.
                    i = i + 1.
                END.
            END.
            GET NEXT q1.
        END.
        
        i = 1.
        FOR EACH table1 NO-LOCK:
            IF i = deletedIdx THEN
                i = i + 1.
            Assert:Equals(ids[i], table1.f1).
            i = i + 1.
        END.
        
        i = 1.
        FOR EACH table2 NO-LOCK:
            Assert:Equals(ids[i], table2.f1).
            i = i + 1.
        END.
    END.
END.