Last active
June 12, 2020 13:30
-
-
Save MarkGoldberg/809ab9ced9fd61e57a058ea5729409cc to your computer and use it in GitHub Desktop.
Refactor FileManager.PrimeAutoIncServer to show use of routines in a method
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Apparently the files in a gist are sorted alphabetically | |
so I've renamed the files to control the sort order. | |
FurtherRefactored - change method to have one RETURN | |
and make some formatting changes too | |
OrigMethod - a copy of the method from ABFile | |
EarlyRefactored - splitting orig up using a local procedure and routines | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
! This routine primes the auto increment fields of a record | |
! A key part of the specification is that fields values | |
! (other than autoincrement ones) are -not- corrupted. | |
FileManager.PrimeAutoIncServer PROCEDURE(BYTE HandleError) | |
MAP | |
PrimeAutoIncServer:ProcessAutoIncKeys(),BOOL | |
END | |
RetVal BYTE | |
CODE | |
IF SELF.UseFile() <> Level:Benign THEN RetVal = Level:Fatal | |
ELSIF NOT SELF.HasAutoInc OR SELF.AutoIncDone THEN RetVal = Level:Benign | |
ELSE | |
DO PrimeAutoIncServer:AutoInc | |
END | |
RETURN RetVal | |
PrimeAutoIncServer:AutoInc ROUTINE | |
DATA | |
Attempts BYTE(0) | |
CODE | |
SELF.File{PROP:IPRequestCount} = 0 | |
LOOP | |
IF NOT PrimeAutoIncServer:ProcessAutoIncKeys() | |
SELF.SetError(Msg:AbortReading) | |
IF HandleError | |
RetVal = SELF.Throw() | |
ELSE RetVal = Level:Notify | |
END | |
BREAK | |
END | |
ADD(SELF.File) | |
IF ERRORCODE() | |
Attempts += 1 | |
IF Attempts = 3 | |
DO PrimeAutoIncServer:SetError_RetryAutoInc | |
IF HandleError AND ~Self.Throw() | |
Attempts = 0 | |
CYCLE | |
END | |
RetVal = Level:Notify | |
BREAK | |
END | |
ELSE | |
SELF.AutoIncDone = 1 | |
RetVal = Level:Benign | |
BREAK | |
END | |
END | |
PrimeAutoIncServer:SetError_RetryAutoInc ROUTINE | |
DATA | |
I SIGNED,AUTO | |
CODE | |
IF ERRORCODE()=DupKeyErr | |
SELF.SetError(Msg:RetryAutoInc) | |
LOOP I = 1 TO RECORDS(SELF.Keys) | |
GET(SELF.Keys,I) | |
IF DUPLICATE(SELF.Keys.Key) | |
SELF.Errors.SetKey(CHOOSE(CLIP(SELF.Keys.Description)<>'',CLIP(SELF.Keys.Description),SELF.Keys.Key{PROP:NAME})) | |
BREAK | |
END | |
END | |
!ELSE | |
! SELF.SetError(Msg:RetryAutoInc) | |
END | |
SELF.SetError(Msg:RetryAutoInc) | |
!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= | |
PrimeAutoIncServer:ProcessAutoIncKeys PROCEDURE() | |
I SHORT,AUTO | |
AutoVal ANY | |
AutoIncField ANY | |
RetSuccess BOOL(TRUE) | |
CODE | |
LOOP I = 1 TO RECORDS(SELF.Keys) | |
GET(SELF.Keys,I) | |
IF SELF.Keys.AutoInc | |
DO PrimeAutoIncServer:AutoIncKey | |
IF NOT RetSuccess THEN BREAK END | |
END | |
END | |
RETURN RetSuccess | |
PrimeAutoIncServer:AutoIncKey ROUTINE | |
DATA | |
SaveRec USHORT,AUTO | |
CODE | |
SELF.Errors.SetKey(CHOOSE(CLIP(SELF.Keys.Description)<>'',CLIP(SELF.Keys.Description),SELF.Keys.Key{PROP:NAME})) | |
! For each key with autoincrement try to find a valid new component value | |
SaveRec = SELF.SaveBuffer() | |
NOMEMO(SELF.File) | |
IF RECORDS(SELF.Keys.Fields) = 1 | |
DO PrimeAutoIncServer:OneFieldKey | |
ELSE DO PrimeAutoIncServer:MultipleFieldsKey | |
END | |
SELF.RestoreBuffer(SaveRec) | |
AutoIncField = AutoVal | |
PrimeAutoIncServer:OneFieldKey ROUTINE | |
GET(SELF.Keys.Fields,1) | |
AutoIncField &= SELF.Keys.Fields.Field | |
SET(SELF.Keys.Key) | |
DO PrimeAutoIncServer:NextOrPrev | |
CASE ERRORCODE() | |
OF NoError ; AutoVal = AutoIncField + 1 | |
OF BadRecErr ; AutoVal = 1 | |
ELSE ; RetSuccess = FALSE | |
END | |
PrimeAutoIncServer:MultipleFieldsKey ROUTINE | |
DATA | |
SaveKeys CSTRING(2000),AUTO | |
NewKeys CSTRING(2000),AUTO | |
CODE | |
ConcatGetComponents(SELF.Keys.Fields,SaveKeys,SELF.Keys.AutoInc-1) | |
GET(SELF.Keys.Fields,SELF.Keys.AutoInc) | |
AutoIncField &= SELF.Keys.Fields.Field | |
CLEAR(AutoIncField,1) | |
SET(SELF.Keys.Key,SELF.Keys.Key) | |
DO PrimeAutoIncServer:NextOrPrev | |
CASE ERRORCODE() | |
OF NoError ; ConcatGetComponents(SELF.Keys.Fields,NewKeys,SELF.Keys.AutoInc-1) | |
IF SaveKeys = NewKeys | |
AutoVal = AutoIncField + 1 | |
ELSE AutoVal = 1 | |
END | |
OF BadRecErr ; AutoVal = 1 | |
ELSE ; RetSuccess = FALSE | |
END | |
PrimeAutoIncServer:NextOrPrev ROUTINE | |
IF SELF.Keys.Fields.Ascend | |
PREVIOUS(SELF.File) | |
ELSE NEXT (SELF.File) | |
END | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
! This routine primes the auto increment fields of a record | |
! A key part of the specification is that fields values | |
! (other than autoincrement ones) are -not- corrupted. | |
FileManager.PrimeAutoIncServer PROCEDURE(BYTE HandleError) | |
I SHORT,AUTO | |
SaveKeys CSTRING(2000),AUTO | |
NewKeys CSTRING(2000),AUTO | |
SaveRec USHORT,AUTO | |
AutoVal ANY | |
AutoIncField ANY | |
Attempts BYTE(0) | |
CODE | |
IF SELF.UseFile()<>Level:Benign THEN RETURN Level:Fatal. | |
IF NOT SELF.HasAutoInc OR SELF.AutoIncDone | |
RETURN Level:Benign | |
END | |
SELF.File{PROP:IPRequestCount} = 0 | |
LOOP | |
LOOP I = 1 TO RECORDS(SELF.Keys) | |
GET(SELF.Keys,I) | |
IF SELF.Keys.AutoInc | |
SELF.Errors.SetKey(CHOOSE(CLIP(SELF.Keys.Description)<>'',CLIP(SELF.Keys.Description),SELF.Keys.Key{PROP:NAME})) | |
! For each key with autoincrement try to find a valid new component value | |
SaveRec = SELF.SaveBuffer() | |
NOMEMO(SELF.File) | |
IF RECORDS(SELF.Keys.Fields) = 1 | |
GET(SELF.Keys.Fields,1) | |
AutoIncField &= SELF.Keys.Fields.Field | |
SET(SELF.Keys.Key) | |
IF SELF.Keys.Fields.Ascend | |
PREVIOUS(SELF.File) | |
ELSE | |
NEXT(SELF.File) | |
END | |
CASE ERRORCODE() | |
OF NoError | |
AutoVal = AutoIncField + 1 | |
OF BadRecErr | |
AutoVal = 1 | |
ELSE | |
SELF.SetError(Msg:AbortReading) | |
IF HandleError | |
RETURN SELF.Throw() | |
ELSE | |
RETURN Level:Notify | |
END | |
END | |
ELSE | |
ConcatGetComponents(SELF.Keys.Fields,SaveKeys,SELF.Keys.AutoInc-1) | |
GET(SELF.Keys.Fields,SELF.Keys.AutoInc) | |
AutoIncField &= SELF.Keys.Fields.Field | |
CLEAR(AutoIncField,1) | |
SET(SELF.Keys.Key,SELF.Keys.Key) | |
IF SELF.Keys.Fields.Ascend | |
PREVIOUS(SELF.File) | |
ELSE | |
NEXT(SELF.File) | |
END | |
CASE ERRORCODE() | |
OF NoError | |
ConcatGetComponents(SELF.Keys.Fields,NewKeys,SELF.Keys.AutoInc-1) | |
IF SaveKeys = NewKeys | |
AutoVal = AutoIncField + 1 | |
ELSE | |
AutoVal = 1 | |
END | |
OF BadRecErr | |
AutoVal = 1 | |
ELSE | |
SELF.SetError(Msg:AbortReading) | |
IF HandleError | |
RETURN SELF.Throw() | |
ELSE | |
RETURN Level:Notify | |
END | |
END | |
END | |
SELF.RestoreBuffer(SaveRec) | |
AutoIncField = AutoVal | |
END | |
END | |
ADD(SELF.File) | |
IF ERRORCODE() | |
Attempts += 1 | |
! This probably means someone else got there first | |
! In a 'heavy' usage network a number > 3 might be useful | |
! although the machine will go 'dead' for longer | |
IF Attempts = 3 | |
IF ERRORCODE()=DupKeyErr | |
SELF.SetError(Msg:RetryAutoInc) | |
LOOP I = 1 TO RECORDS(SELF.Keys) | |
GET(SELF.Keys,I) | |
IF DUPLICATE(SELF.Keys.Key) | |
SELF.Errors.SetKey(CHOOSE(CLIP(SELF.Keys.Description)<>'',CLIP(SELF.Keys.Description),SELF.Keys.Key{PROP:NAME})) | |
BREAK | |
END | |
END | |
ELSE | |
SELF.SetError(Msg:RetryAutoInc) | |
END | |
SELF.SetError(Msg:RetryAutoInc) | |
IF HandleError | |
IF ~Self.Throw() | |
Attempts = 0 | |
CYCLE | |
END | |
END | |
RETURN Level:Notify | |
END | |
ELSE | |
SELF.AutoIncDone = 1 | |
RETURN Level:Benign | |
END | |
END | |
? ASSERT(0,'Coding error, this point should not be reachable') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
! This routine primes the auto increment fields of a record | |
! A key part of the specification is that fields values | |
! (other than autoincrement ones) are -not- corrupted. | |
FileManager.PrimeAutoIncServer PROCEDURE(BYTE HandleError) | |
Attempts BYTE(0) | |
MAP | |
PrimeAutoIncServer:ForEachKey(),BOOL | |
END | |
CODE | |
IF SELF.UseFile()<>Level:Benign THEN RETURN Level:Fatal. | |
IF NOT SELF.HasAutoInc OR SELF.AutoIncDone | |
RETURN Level:Benign | |
END | |
SELF.File{PROP:IPRequestCount} = 0 | |
LOOP | |
IF PrimeAutoIncServer:ForEachKey() | |
SELF.SetError(Msg:AbortReading) | |
IF HandleError | |
RETURN SELF.Throw() | |
ELSE | |
RETURN Level:Notify | |
END | |
END | |
ADD(SELF.File) | |
IF ERRORCODE() | |
Attempts += 1 | |
IF Attempts = 3 | |
DO PrimeAutoIncServer:SetError | |
RETURN Level:Notify | |
END | |
ELSE | |
SELF.AutoIncDone = 1 | |
RETURN Level:Benign | |
END | |
END | |
? ASSERT(0,'Coding error, this point should not be reachable') | |
PrimeAutoIncServer:SetError ROUTINE | |
DATA | |
I SIGNED,AUTO | |
CODE | |
IF ERRORCODE()=DupKeyErr | |
SELF.SetError(Msg:RetryAutoInc) | |
LOOP I = 1 TO RECORDS(SELF.Keys) | |
GET(SELF.Keys,I) | |
IF DUPLICATE(SELF.Keys.Key) | |
SELF.Errors.SetKey(CHOOSE(CLIP(SELF.Keys.Description)<>'',CLIP(SELF.Keys.Description),SELF.Keys.Key{PROP:NAME})) | |
BREAK | |
END | |
END | |
ELSE | |
SELF.SetError(Msg:RetryAutoInc) | |
END | |
SELF.SetError(Msg:RetryAutoInc) | |
IF HandleError | |
IF ~Self.Throw() | |
Attempts = 0 | |
CYCLE | |
END | |
END | |
PrimeAutoIncServer:ForEachKey PROCEDURE() | |
I SHORT,AUTO | |
SaveKeys CSTRING(2000),AUTO | |
NewKeys CSTRING(2000),AUTO | |
SaveRec USHORT,AUTO | |
AutoVal ANY | |
AutoIncField ANY | |
Attempts BYTE(0) | |
RetFailed BOOL(FALSE) | |
CODE | |
LOOP I = 1 TO RECORDS(SELF.Keys) | |
GET(SELF.Keys,I) | |
IF SELF.Keys.AutoInc | |
SELF.Errors.SetKey(CHOOSE(CLIP(SELF.Keys.Description)<>'',CLIP(SELF.Keys.Description),SELF.Keys.Key{PROP:NAME})) | |
! For each key with autoincrement try to find a valid new component value | |
SaveRec = SELF.SaveBuffer() | |
NOMEMO(SELF.File) | |
IF RECORDS(SELF.Keys.Fields) = 1 | |
DO PrimeAutoIncServer:OneFieldKey | |
ELSE | |
DO PrimeAutoIncServer:MultipleFieldsKey | |
END | |
SELF.RestoreBuffer(SaveRec) | |
AutoIncField = AutoVal | |
END | |
END | |
RETURN RetFailed | |
PrimeAutoIncServer:OneFieldKey ROUTINE | |
GET(SELF.Keys.Fields,1) | |
AutoIncField &= SELF.Keys.Fields.Field | |
SET(SELF.Keys.Key) | |
DO PrimeAutoIncServer:NextOrPrev | |
CASE ERRORCODE() | |
OF NoError | |
AutoVal = AutoIncField + 1 | |
OF BadRecErr | |
AutoVal = 1 | |
ELSE | |
RetFailed = TRUE | |
END | |
PrimeAutoIncServer:MultipleFieldsKey ROUTINE | |
ConcatGetComponents(SELF.Keys.Fields,SaveKeys,SELF.Keys.AutoInc-1) | |
GET(SELF.Keys.Fields,SELF.Keys.AutoInc) | |
AutoIncField &= SELF.Keys.Fields.Field | |
CLEAR(AutoIncField,1) | |
SET(SELF.Keys.Key,SELF.Keys.Key) | |
DO PrimeAutoIncServer:NextOrPrev | |
CASE ERRORCODE() | |
OF NoError | |
ConcatGetComponents(SELF.Keys.Fields,NewKeys,SELF.Keys.AutoInc-1) | |
IF SaveKeys = NewKeys | |
AutoVal = AutoIncField + 1 | |
ELSE | |
AutoVal = 1 | |
END | |
OF BadRecErr | |
AutoVal = 1 | |
ELSE | |
RetFailed = TRUE | |
END | |
PrimeAutoIncServer:NextOrPrev ROUTINE | |
IF SELF.Keys.Fields.Ascend | |
PREVIOUS(SELF.File) | |
ELSE | |
NEXT(SELF.File) | |
END | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment