Skip to content

Instantly share code, notes, and snippets.

@MarkGoldberg
Last active June 12, 2020 13:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MarkGoldberg/809ab9ced9fd61e57a058ea5729409cc to your computer and use it in GitHub Desktop.
Save MarkGoldberg/809ab9ced9fd61e57a058ea5729409cc to your computer and use it in GitHub Desktop.
Refactor FileManager.PrimeAutoIncServer to show use of routines in a method
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 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 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 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