added LSL2 stored procedures
This commit is contained in:
804
LSL2/STPROC/DATABASE_SERVICES_ORIG.txt
Normal file
804
LSL2/STPROC/DATABASE_SERVICES_ORIG.txt
Normal file
@ -0,0 +1,804 @@
|
||||
Function Database_Services_Orig(@Service, @Params)
|
||||
/***********************************************************************************************************************
|
||||
|
||||
This program is proprietary and is not to be used by or disclosed to others, nor is it to be copied without written
|
||||
permission from SRP Computer Solutions, Inc.
|
||||
|
||||
Name : Database_Services
|
||||
|
||||
Description : Handler program for all Database services.
|
||||
|
||||
Notes : Application errors should be logged using the Error Services module. There are a few methodological
|
||||
assumptions built into way errors are managed which are important to understand in order to properly
|
||||
work with Error Services:
|
||||
|
||||
Parameters :
|
||||
Service [in] -- Name of the service being requested
|
||||
Param1-10 [in/out] -- Additional request parameter holders
|
||||
Response [out] -- Response to be sent back to the Controller (MCP) or requesting procedure
|
||||
|
||||
Metadata :
|
||||
|
||||
History : (Date, Initials, Notes)
|
||||
03/27/17 dmb Original programmer.
|
||||
05/02/17 dmb Add error if WriteDatabaseRow is unable to lock row.
|
||||
10/31/17 dmb Add CalculateColumn and GetTableCommuter services.
|
||||
05/25/18 dmb Add GetUserLocks service.
|
||||
05/29/18 dmb Add IsKeyIDLocked, IsKeyIDSelfLocked, and UnlockKeyID services.
|
||||
10/09/18 djs Added ActivateRecord service, which sets @ID, @Record, and @DICT to enable {} shorthand.
|
||||
|
||||
***********************************************************************************************************************/
|
||||
|
||||
#pragma precomp SRP_PreCompiler
|
||||
|
||||
$insert LOGICAL
|
||||
$insert SERVICE_SETUP
|
||||
$insert VOL_TABLE_EQUATES
|
||||
$insert RTI_LH_INFO_EQUATES
|
||||
|
||||
Declare function Memory_Services, Database_Services, SRP_Encode, RetStack, RTI_LH_Info, SRP_Path
|
||||
Declare subroutine Memory_Services, Database_Services, Verify_LH, SRP_Stopwatch, Btree.Extract, Update_Index, Set_Status
|
||||
Declare subroutine RTI_LH_Info
|
||||
|
||||
GoToService else
|
||||
Error_Services('Add', Service : ' is not a valid service request within the ' : ServiceModule : ' module.')
|
||||
end
|
||||
|
||||
Return Response OR ''
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Service Parameter Options
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Options BOOLEAN = True$, False$
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Services
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// VerifyLHAll
|
||||
//
|
||||
// Performs a health check againsts all attached tables and returns back any issues. Returns two lists which are
|
||||
// delimited by an @RM. The first list is an @FM list of attached tables. The second list is an @FM list of results
|
||||
// (groups that have GFEs or an empty string if there are none). Items in each list correspond which each other based on
|
||||
// their list position.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
Service VerifyLHAll()
|
||||
|
||||
VerifyResults = ''
|
||||
TableNames = @TABLES(0)
|
||||
NumTables = DCount(TableNames, @FM)
|
||||
|
||||
For TableCnt = 1 to NumTables
|
||||
TableName = TableNames<TableCnt>
|
||||
VerifyResults := Database_Services('VerifyLH', TableName) : @FM
|
||||
Next TableCnt
|
||||
VerifyResults[-1, 1] = '' ; // Strip off the last @FM
|
||||
|
||||
Response = TableNames : @RM : VerifyResults
|
||||
|
||||
end service
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// VerifyLH
|
||||
//
|
||||
// TableNames. One or more linear hash database tables to verify. List should be @FM delimited. - [OPTIONAL]
|
||||
// SaveList. Name of a saved selection of linear hash database tables to verify. This argument will be ignored
|
||||
// if TableNames is populated. - [OPTIONAL]
|
||||
//
|
||||
// Performs a health check against the indicated tables and returns back any issues. Note: This uses the Verify_LH
|
||||
// subroutine to check for GFEs. All results are stored in the SYSLHVERIFY table with a KeyID of
|
||||
// VolumeLabel*DatabaseID*TableName. Returns the list of groups that have GFEs or returns an empty string if there are
|
||||
// none. The list of GFEs or empty strings will themselves be @FM delimited to correspond with the tables passed into
|
||||
// this service.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
Service VerifyLH(Tablenames, SaveList)
|
||||
|
||||
VerifyResults = ''
|
||||
|
||||
If TableNames EQ '' then
|
||||
TableNames = Xlate('SYSLISTS', SaveList, '', 'X')
|
||||
If Index(TableNames<1>, @TM, 1) then
|
||||
// This saved select has metadata in attribute 1. Remove it.
|
||||
TableNames = Delete(TableNames, 1, 0, 0)
|
||||
end
|
||||
end
|
||||
|
||||
If TableNames NE '' then
|
||||
NumTables = DCount(TableNames, @FM)
|
||||
For TableCnt = 1 to NumTables
|
||||
TableName = TableNames<TableCnt>
|
||||
TableProperties = Database_Services('GetTableProperties', TableName)
|
||||
If Error_Services('NoError') then
|
||||
rv = Set_Status(0)
|
||||
Verify_LH('', TableName, True$, False$, False$)
|
||||
Open 'SYSLHVERIFY' to hSysLHVerify then
|
||||
DatabaseID = TableProperties<1>
|
||||
VolumeLabel = TableProperties<3>
|
||||
LHVerifyKeyID = VolumeLabel : '*' : DatabaseID : '*' : TableName
|
||||
Read LHVerifyRec from hSysLHVerify, LHVerifyKeyID then
|
||||
VerifyResults<TableCnt> = LHVerifyRec<2>
|
||||
end
|
||||
end else
|
||||
Error_Services('Add', 'Error opening the SYSLHVERIFY table in the ' : Service : ' service.')
|
||||
end
|
||||
Begin Case
|
||||
Case @File_Error NE ''
|
||||
Error_Services('Add', 'Error verifying table ' : TableName : ': FS Error = ' : @File_Error<1>)
|
||||
Case Get_Status()
|
||||
Error_Services('Add', 'Get_Status error: ' : Get_Status())
|
||||
End Case
|
||||
end
|
||||
Next TableCnt
|
||||
end else
|
||||
Error_Services('Add', 'The TableName argument was missing in the ' : Service : ' service.')
|
||||
end
|
||||
|
||||
Response = VerifyResults
|
||||
|
||||
end service
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// GetTableProperties
|
||||
//
|
||||
// TableName. The linear hash database table name. - [REQUIRED]
|
||||
//
|
||||
// Returns an array of information related to the database table being passed in.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
Service GetTableProperties(TableName)
|
||||
|
||||
TableProperties = ''
|
||||
|
||||
If TableName NE '' then
|
||||
rv = Set_Status(0)
|
||||
Locate TableName in @TABLES(0) using @FM setting fPos then
|
||||
TableProperties<1> = @TABLES(3)<fPos> ; // DatabaseID
|
||||
TableProperties<2> = @TABLES(4)<fPos> ; // MFS/BFS List
|
||||
VolumeID = @TABLES(1)<fPos> ; // Volume ID
|
||||
Locate VolumeID in @VOLUMES(0) using @FM setting fPos then
|
||||
TableProperties<3> = @VOLUMES(1)<fPos> ; // Volume Label
|
||||
TableProperties<4> = @VOLUMES(2)<fPos> ; // Volume Path
|
||||
TableProperties<5> = @VOLUMES(4)<fPos> ; // BFS
|
||||
end
|
||||
end else
|
||||
Error_Services('Add', 'The ' : TableName : ' table is not attached and available to the ' : Service : ' service.')
|
||||
end
|
||||
end else
|
||||
Error_Services('Add', 'TableName argument was missing in the ' : Service : ' service.')
|
||||
end
|
||||
|
||||
Response = TableProperties
|
||||
|
||||
end service
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// GetTableHandle
|
||||
//
|
||||
// TableName. The linear hash database table name. - [REQUIRED]
|
||||
//
|
||||
// Returns an array of information related to the database table being passed in.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
Service GetTableHandle(TableName)
|
||||
|
||||
ServiceKeyID := '*' : TableName
|
||||
TableHandle = Memory_Services('GetValue', ServiceKeyID, True$, 360)
|
||||
|
||||
If TableHandle EQ '' then
|
||||
rv = Set_Status(0)
|
||||
Open TableName to TableHandle then
|
||||
Memory_Services('SetValue', ServiceKeyID, TableHandle)
|
||||
end else
|
||||
Error_Services('Add', 'Unable to open the ' : TableName : ' table in the ' : Service : ' service. Error = ' : @File_Error<1>)
|
||||
end
|
||||
end
|
||||
|
||||
Response = TableHandle
|
||||
|
||||
end service
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// ReadDataRow
|
||||
//
|
||||
// TableName. The linear hash database table name. - [REQUIRED]
|
||||
// KeyID. The KeyID to the database table. - [REQUIRED]
|
||||
//
|
||||
// Reads a data row for the indicated Key ID and database table.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
Service ReadDataRow(TableName, KeyID, NotExpired, ExpirationDuration, IgnoreMFSRoutines)
|
||||
|
||||
If NotExpired NE False$ then NotExpired = True$
|
||||
If (ExpirationDuration EQ '') OR (Not(Num(ExpirationDuration))) then ExpirationDuration = 0
|
||||
If IgnoreMFSRoutines NE True$ then IgnoreMFSRoutines = False$
|
||||
|
||||
ServiceKeyID := '*' : TableName : '*' : KeyID
|
||||
DataRow = Memory_Services('GetValue', ServiceKeyID, NotExpired, ExpirationDuration)
|
||||
|
||||
If TableName NE '' AND KeyID NE '' then
|
||||
If DataRow EQ '' then
|
||||
TableHandle = Database_Services('GetTableHandle', TableName)
|
||||
If Error_Services('NoError') then
|
||||
If IgnoreMFSRoutines then
|
||||
MFSList = TableHandle<1, 1> ; // MFS routines are @SVM delimited.
|
||||
NumMFS = DCount(MFSList, @SVM)
|
||||
For MFSCnt = NumMFS to 1 Step -1
|
||||
MFSRoutine = MFSList<0, 0, MFSCnt>
|
||||
If MFSRoutine NE 'RTP57' then
|
||||
MFSList = Delete(MFSList, 0, 0, MFSCnt)
|
||||
end
|
||||
Next MFSCnt
|
||||
TableHandle<1, 1> = MFSList
|
||||
end
|
||||
Read DataRow from TableHandle, KeyID then
|
||||
Memory_Services('SetValue', ServiceKeyID, DataRow)
|
||||
end else
|
||||
Error_Services('Add', 'Error reading ' : KeyID : ' from the ' : TableName : ' table in the ' : Service : ' service.')
|
||||
end
|
||||
end
|
||||
end
|
||||
end else
|
||||
Error_Services('Add', 'TableName or KeyID argument was missing in the ' : Service : ' service.')
|
||||
end
|
||||
|
||||
Response = DataRow
|
||||
|
||||
end service
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// ReadDataColumn
|
||||
//
|
||||
// TableName. The linear hash database table name. - [REQUIRED]
|
||||
// KeyID. The KeyID to the database table. - [REQUIRED]
|
||||
// ColumnNo. The index of the column that is to be read. - [REQUIRED]
|
||||
//
|
||||
// Reads a data column for the indicated Key ID and database table.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
Service ReadDataColumn(TableName, KeyID, ColumnNo, NotExpired, ExpirationDuration, IgnoreMFSRoutines)
|
||||
|
||||
If NotExpired NE False$ then NotExpired = True$
|
||||
If (ExpirationDuration EQ '') OR (Not(Num(ExpirationDuration))) then ExpirationDuration = 0
|
||||
If IgnoreMFSRoutines NE True$ then IgnoreMFSRoutines = False$
|
||||
|
||||
ServiceKeyID := '*' : TableName : '*' : KeyID : '*' : ColumnNo
|
||||
DataColumn = Memory_Services('GetValue', ServiceKeyID, NotExpired, ExpirationDuration)
|
||||
|
||||
If Num(ColumnNo) AND (ColumnNo GT 0) then
|
||||
If TableName NE '' AND KeyID NE '' then
|
||||
If DataColumn EQ '' then
|
||||
TableHandle = Database_Services('GetTableHandle', TableName)
|
||||
If Error_Services('NoError') then
|
||||
If IgnoreMFSRoutines then
|
||||
MFSList = TableHandle<1, 1> ; // MFS routines are @SVM delimited.
|
||||
NumMFS = DCount(MFSList, @SVM)
|
||||
For MFSCnt = NumMFS to 1 Step -1
|
||||
MFSRoutine = MFSList<0, 0, MFSCnt>
|
||||
If MFSRoutine NE 'RTP57' then
|
||||
MFSList = Delete(MFSList, 0, 0, MFSCnt)
|
||||
end
|
||||
Next MFSCnt
|
||||
TableHandle<1, 1> = MFSList
|
||||
end
|
||||
ReadV DataColumn from TableHandle, KeyID, ColumnNo then
|
||||
Memory_Services('SetValue', ServiceKeyID, DataColumn)
|
||||
end else
|
||||
ErrorMsg = 'Error reading ' : KeyID : ' column number ' : ColumnNo : ' from the ' |
|
||||
: TableName : ' table in the ' : Service : ' service.'
|
||||
Error_Services('Add', ErrorMsg)
|
||||
end
|
||||
end
|
||||
end
|
||||
end else
|
||||
Error_Services('Add', 'TableName or KeyID argument was missing in the ' : Service : ' service.')
|
||||
end
|
||||
end else
|
||||
Error_Services('Add', 'ColumnNo was not a number or was not greater than zero in the ' : Service : ' service.')
|
||||
end
|
||||
|
||||
Response = DataColumn
|
||||
|
||||
end service
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// ActivateRecord
|
||||
//
|
||||
// TableName. The linear hash database table name. - [REQUIRED]
|
||||
// KeyID. The KeyID to the database table. - [REQUIRED]
|
||||
//
|
||||
// Reads a data row for the indicated Key ID and database table. Sets @ID, @Record, and @DICT to enable {} shorthand.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
Service ActivateRecord(TableName, KeyID, NotExpired, ExpirationDuration, IgnoreMFSRoutines)
|
||||
|
||||
If TableName NE '' AND KeyID NE '' then
|
||||
@ID = KeyID
|
||||
DictTable = ''
|
||||
If TableName[1,5] _EQC 'DICT.' then
|
||||
DictTable = TableName
|
||||
TableName = TableName[-1, 'B.']
|
||||
end else
|
||||
DictTable = 'DICT.':TableName
|
||||
end
|
||||
@DICT = Database_Services('GetTableHandle', DictTable)
|
||||
If Error_Services('NoError') then
|
||||
@Record = Database_Services('ReadDataRow',TableName,KeyID,NotExpired,ExpirationDuration,IgnoreMFSRoutines)
|
||||
If Not(Error_Services('NoError')) then
|
||||
Error_Services('Add','Error reading ':KeyID:' from the ':TableName:' table in the ':Service:' service.')
|
||||
end
|
||||
end else
|
||||
Error_Services('Add', 'Error retrieving handle for the ':TableName:' table in the ':Service:' service.')
|
||||
end
|
||||
end
|
||||
|
||||
Response = @Record
|
||||
|
||||
end service
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// WriteDataRow
|
||||
//
|
||||
// TableName. The linear hash database table name. - [REQUIRED]
|
||||
// KeyID. The KeyID to the database table. - [REQUIRED]
|
||||
//
|
||||
// Writes a data row for the indicated Key ID and database table.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
Service WriteDataRow(TableName, KeyID, DataRow, IgnoreSelfLock, IgnoreMFSRoutines, IgnoreAllLocks)
|
||||
|
||||
If TableName NE '' AND KeyID NE '' then
|
||||
If IgnoreSelfLock NE True$ then IgnoreSelfLock = False$
|
||||
If IgnoreMFSRoutines NE True$ then IgnoreMFSRoutines = False$
|
||||
If IgnoreAllLocks NE True$ then IgnoreAllLocks = False$
|
||||
If IgnoreAllLocks then
|
||||
HaveLock = True$
|
||||
end else
|
||||
HaveLock = Database_Services('GetKeyIDLock', TableName, KeyID, IgnoreSelfLock)
|
||||
end
|
||||
If HaveLock EQ True$ then
|
||||
TableHandle = Database_Services('GetTableHandle', TableName)
|
||||
If IgnoreMFSRoutines then
|
||||
MFSList = TableHandle<1, 1> ; // MFS routines are @SVM delimited.
|
||||
NumMFS = DCount(MFSList, @SVM)
|
||||
For MFSCnt = NumMFS to 1 Step -1
|
||||
MFSRoutine = MFSList<0, 0, MFSCnt>
|
||||
If (MFSRoutine NE 'SI.MFS') AND (MFSRoutine NE 'RTP57') then
|
||||
MFSList = Delete(MFSList, 0, 0, MFSCnt)
|
||||
end
|
||||
Next MFSCnt
|
||||
TableHandle<1, 1> = MFSList
|
||||
end
|
||||
If Error_Services('NoError') then
|
||||
Write DataRow to TableHandle, KeyID then
|
||||
Memory_Services('SetValue', ServiceModule : '*' : 'ReadDatarow' : '*' : TableName : '*' : KeyID, DataRow)
|
||||
end else
|
||||
Error_Services('Add', 'Error writing ' : KeyID : ' to the ' : TableName : ' table in the ' : Service : ' service.')
|
||||
end
|
||||
end
|
||||
If IgnoreAllLocks EQ False$ then
|
||||
Database_Services('ReleaseKeyIDLock', TableName, KeyID)
|
||||
end
|
||||
end else
|
||||
Error_Services('Add', 'Unable to lock ' : KeyID : ' for the ' : TableName : ' table in the ' : Service : ' service.')
|
||||
end
|
||||
end else
|
||||
Error_Services('Add', 'TableName or KeyID argument was missing in the ' : Service : ' service.')
|
||||
end
|
||||
|
||||
end service
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// DeleteDataRow
|
||||
//
|
||||
// TableName. The linear hash database table name. - [REQUIRED]
|
||||
// KeyID. The KeyID to the database table. - [REQUIRED]
|
||||
//
|
||||
// Deletes a data row for the indicated Key ID and database table.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
Service DeleteDataRow(TableName, KeyID, IgnoreSelfLock, IgnoreMFSRoutines)
|
||||
|
||||
If TableName NE '' AND KeyID NE '' then
|
||||
If IgnoreSelfLock NE True$ then IgnoreSelfLock = False$
|
||||
If IgnoreMFSRoutines NE True$ then IgnoreMFSRoutines = False$
|
||||
HaveLock = Database_Services('GetKeyIDLock', TableName, KeyID, IgnoreSelfLock)
|
||||
If HaveLock EQ True$ then
|
||||
TableHandle = Database_Services('GetTableHandle', TableName)
|
||||
If IgnoreMFSRoutines then
|
||||
MFSList = TableHandle<1, 1> ; // MFS routines are @SVM delimited.
|
||||
NumMFS = DCount(MFSList, @SVM)
|
||||
For MFSCnt = NumMFS to 1 Step -1
|
||||
MFSRoutine = MFSList<0, 0, MFSCnt>
|
||||
If (MFSRoutine NE 'SI.MFS') AND (MFSRoutine NE 'RTP57') then
|
||||
MFSList = Delete(MFSList, 0, 0, MFSCnt)
|
||||
end
|
||||
Next MFSCnt
|
||||
TableHandle<1, 1> = MFSList
|
||||
end
|
||||
If Error_Services('NoError') then
|
||||
Delete TableHandle, KeyID then
|
||||
Memory_Services('SetValue', ServiceModule : '*' : 'ReadDatarow' : '*' : TableName : '*' : KeyID, '')
|
||||
end else
|
||||
Error_Services('Add', 'Error deleting ' : KeyID : ' from the ' : TableName : ' table in the ' : Service : ' service.')
|
||||
end
|
||||
end
|
||||
Database_Services('ReleaseKeyIDLock', TableName, KeyID)
|
||||
end else
|
||||
Error_Services('Add', 'Unable to lock ' : KeyID : ' for the ' : TableName : ' table in the ' : Service : ' service.')
|
||||
end
|
||||
end else
|
||||
Error_Services('Add', 'TableName or KeyID argument was missing in the ' : Service : ' service.')
|
||||
end
|
||||
|
||||
end service
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// GetKeyIDLock
|
||||
//
|
||||
// Attempts to perform a semaphore lock on the indicated tablename and Key ID.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
Service GetKeyIDLock(TableName, KeyID, IgnoreSelfLock)
|
||||
|
||||
HaveLock = False$ ; // Assume false for now.
|
||||
|
||||
If TableName NE '' AND KeyID NE '' then
|
||||
If IgnoreSelfLock NE True$ then IgnoreSelfLock = False$
|
||||
TableHandle = Database_Services('GetTableHandle', TableName)
|
||||
If Error_Services('NoError') then
|
||||
Lock Tablehandle, KeyID then
|
||||
HaveLock = True$
|
||||
end else
|
||||
If IgnoreSelfLock EQ True$ then
|
||||
Status = Status()
|
||||
If Status EQ 1 then
|
||||
HaveLock = True$
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end else
|
||||
Error_Services('Add', 'TableName or KeyID argument was missing in the ' : Service : ' service.')
|
||||
end
|
||||
|
||||
Response = HaveLock
|
||||
|
||||
end service
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// ReleaseKeyIDLock
|
||||
//
|
||||
// Attempts to release a semaphore lock on the indicated tablename and Key ID.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
Service ReleaseKeyIDLock(TableName, KeyID)
|
||||
|
||||
LockReleased = False$ ; // Assume false for now.
|
||||
|
||||
If TableName NE '' AND KeyID NE '' then
|
||||
TableHandle = Database_Services('GetTableHandle', TableName)
|
||||
If Error_Services('NoError') then
|
||||
UnLock Tablehandle, KeyID then
|
||||
LockReleased = True$
|
||||
end else
|
||||
Error_Services('Add', 'Unable to unlock the ' : KeyID : ' Key ID from the ' : TableName : ' table in the ' : Service : ' service. Error = ' : @File_Error<1>)
|
||||
end
|
||||
end
|
||||
end else
|
||||
Error_Services('Add', 'TableName or KeyID argument was missing in the ' : Service : ' service.')
|
||||
end
|
||||
|
||||
Response = LockReleased
|
||||
|
||||
end service
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// SearchIndex
|
||||
//
|
||||
// TableName. The linear hash database table name. - [REQUIRED]
|
||||
// ColumnName. The indexed column to search against. - [REQUIRED]
|
||||
// SearchValue. The value being searched for. - [REQUIRED]
|
||||
// UpdateIndex. Boolean flag to determine if the index for the indicated column should be updated before searching.
|
||||
// - [OPTIONAL]
|
||||
//
|
||||
// Returns an @FM delimited list of Key IDs that match the search value.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
Service SearchIndex(TableName, ColumnName, SearchValue, UpdateIndex)
|
||||
|
||||
If UpdateIndex NE True$ then UpdateIndex = False$
|
||||
|
||||
ServiceKeyID := '*' : TableName : '*' : ColumnName : '*' : SearchValue
|
||||
ServiceKeyID = SRP_Encode(ServiceKeyID, 'BASE64')
|
||||
* KeyIDList = Memory_Services('GetValue', ServiceKeyID, True$, 5)
|
||||
KeyIDList = ''
|
||||
|
||||
If TableName NE '' AND ColumnName NE '' AND SearchValue NE '' then
|
||||
If KeyIDList EQ '' then
|
||||
DictTableHandle = Database_Services('GetTableHandle', 'DICT.' : TableName)
|
||||
If Error_Services('NoError') then
|
||||
Set_Status(0)
|
||||
If UpdateIndex then Update_Index(TableName, ColumnName 0)
|
||||
Set_Status(0)
|
||||
Btree.Extract(ColumnName : @VM : SearchValue : @FM, Tablename, DictTableHandle, KeyIDList, 'S', Flag)
|
||||
If Flag EQ 0 then
|
||||
Convert @VM to @FM in KeyIDList
|
||||
Memory_Services('SetValue', ServiceKeyID, KeyIDList)
|
||||
end else
|
||||
Error_Services('Add', 'Error in Btree.Extract search from the ' : TableName : ' table in the ' : Service : ' service.')
|
||||
end
|
||||
end
|
||||
end
|
||||
end else
|
||||
Error_Services('Add', 'TableName, ColumnName, or SearchValue argument was missing in the ' : Service : ' service.')
|
||||
end
|
||||
|
||||
Response = KeyIDList
|
||||
|
||||
end service
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// CalculateColumn
|
||||
//
|
||||
// Called directly from within a calculation column. The name of the table and column is derived from the call stack
|
||||
// and the associated table commuter, if it exists, is called with the appropriate arguments.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
Service CalculateColumn()
|
||||
|
||||
Response = ''
|
||||
ColumnName = ''
|
||||
RetStack = RetStack()
|
||||
For Each Item in RetStack using @FM
|
||||
If Index(Item, 'DICT.MFS', 1) then
|
||||
ColumnName = Item[2, \00\, 1]
|
||||
CharPos = BCol2() + 1
|
||||
TableHandle = Item[CharPos, GetByteSize(Item), 1]
|
||||
Locate TableHandle<1, 2> in @TABLES(TAB_HANDLE$) using @FM setting fPos then
|
||||
TableName = @TABLES(0)<fPos> ; // This technically returns the dictionary, but DICT. will be removed.
|
||||
TableName[1, 5] = ''
|
||||
end
|
||||
end
|
||||
Until (ColumnName NE '') OR (Item EQ '')
|
||||
Next Item
|
||||
|
||||
If TableName NE '' then
|
||||
TableCommuter = Database_Services('GetTableCommuter', TableName)
|
||||
If TableCommuter NE '' then
|
||||
Response = Function(@TableCommuter('CalculateColumn', ColumnName))
|
||||
end
|
||||
end
|
||||
|
||||
end service
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// GetTableCommuter
|
||||
//
|
||||
// Returns the name of the indicated table's commuter module if it exists. If it does not exist then an empty string
|
||||
// will be returned.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
Service GetTableCommuter(TableName)
|
||||
|
||||
ServiceKeyID := '*' : TableName
|
||||
TableCommuter = Memory_Services('GetValue', ServiceKeyID)
|
||||
|
||||
If TableCommuter EQ '' then
|
||||
ObjExists = False$ ; // Assume the object code for the action handler does not exist for now.
|
||||
For Each AppID in @AppId
|
||||
If AppID _EQC 'SYSPROG' then
|
||||
SysObjKey = '$' : TableName : '_ACTIONS'
|
||||
end else
|
||||
SysObjKey = '$' : TableName : '_ACTIONS' : '*' : AppID
|
||||
end
|
||||
ObjExists = Memory_Services('KeyExists', SysObjKey)
|
||||
Until ObjExists
|
||||
Next AppID
|
||||
|
||||
If Not(ObjExists) then
|
||||
For Each AppID in @AppId
|
||||
If AppID _EQC 'SYSPROG' then
|
||||
SysObjKey = '$' : TableName : '_ACTIONS'
|
||||
end else
|
||||
SysObjKey = '$' : TableName : '_ACTIONS' : '*' : AppID
|
||||
end
|
||||
OrigFileError = @FILE.ERROR
|
||||
@FILE.ERROR = ''
|
||||
BFS = 'RTP57'
|
||||
// The handle to SYSOBJ is used to find object code before it gets called
|
||||
Call @BFS(2, BFS, @FILE_SYSOBJ<1, 2>, SysObjKey, FMC, SysObjRecord, ActionStatus)
|
||||
@FILE.ERROR = OrigFileError
|
||||
If ActionStatus then ObjExists = True$
|
||||
Until ObjExists
|
||||
Next AppID
|
||||
end
|
||||
|
||||
If (ObjExists) then
|
||||
TableCommuter = TableName : '_ACTIONS'
|
||||
Memory_Services('SetValue', ServiceKeyID, TableCommuter)
|
||||
end
|
||||
end
|
||||
|
||||
Response = TableCommuter
|
||||
|
||||
end service
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// GetUserLocks
|
||||
//
|
||||
// Returns a dynamic array of user lock information. Note, this can only be done with the UD 5. This can also cause
|
||||
// instability with the current session and may require the Task Manager to close the session.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
Service GetUserLocks()
|
||||
|
||||
UserLocks = RTI_LH_Info(CMD_LOCKS_INFO$, '')
|
||||
|
||||
Response = UserLocks
|
||||
|
||||
end service
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// IsKeyIDLocked
|
||||
//
|
||||
// Returns a Boolean flag of the lock status for the indicated table and Key ID.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
Service IsKeyIDLocked(TableName, KeyID, IgnoreSelfLock=BOOLEAN)
|
||||
|
||||
If IgnoreSelfLock NE True$ then IgnoreSelfLock = False$
|
||||
|
||||
KeyIDLocked = False$ ; // Assume false for now.
|
||||
|
||||
If (TableName NE '') AND (KeyID NE '') then
|
||||
Open TableName to hTable then
|
||||
Lock hTable, KeyID then
|
||||
// Able to lock Key ID. Unlock it right away.
|
||||
Unlock hTable, KeyID else Null
|
||||
end else
|
||||
// Unable to lock Key ID. Evaluate the type of lock.
|
||||
LockType = Status()
|
||||
If LockType EQ 0 then
|
||||
// Lock exists on another station.
|
||||
KeyIDLocked = True$
|
||||
end else
|
||||
// Lock exists on this station. Check to see if the Ignore Self Lock flag is set.
|
||||
If Not(IgnoreSelfLock) then KeyIDLocked = True$
|
||||
end
|
||||
end
|
||||
end else
|
||||
Error_Services('Add', 'Error opening the ' : TableName : ' table in the ' : Service : ' service.')
|
||||
end
|
||||
end else
|
||||
Error_Services('Add', 'TableName or KeyID argument was missing in the ' : Service : ' service.')
|
||||
end
|
||||
|
||||
Response = KeyIDLocked
|
||||
|
||||
end service
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// IsKeyIDSelfLocked
|
||||
//
|
||||
// Returns a Boolean flag of the self-lock status for the indicated table and Key ID.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
Service IsKeyIDSelfLocked(TableName, KeyID)
|
||||
|
||||
KeyIDSelfLocked = False$ ; // Assume false for now.
|
||||
|
||||
If (TableName NE '') AND (KeyID NE '') then
|
||||
Open TableName to hTable then
|
||||
Lock hTable, KeyID then
|
||||
// Able to lock Key ID. Unlock it right away.
|
||||
Unlock hTable, KeyID else Null
|
||||
end else
|
||||
// Unable to lock Key ID. Evaluate the type of lock.
|
||||
LockType = Status()
|
||||
If LockType EQ 1 then
|
||||
// This Key ID is self-locked.
|
||||
KeyIDSelfLocked = True$
|
||||
end
|
||||
end
|
||||
end else
|
||||
Error_Services('Add', 'Error opening the ' : TableName : ' table in the ' : Service : ' service.')
|
||||
end
|
||||
end else
|
||||
Error_Services('Add', 'TableName or KeyID argument was missing in the ' : Service : ' service.')
|
||||
end
|
||||
|
||||
Response = KeyIDSelfLocked
|
||||
|
||||
end service
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
// UnlockKeyID
|
||||
//
|
||||
// Attempts to unlock the indicated Key ID from the indicated Table Name. Note, this can only be done with the UD 5.
|
||||
//----------------------------------------------------------------------------------------------------------------------
|
||||
Service UnlockKeyID(TableName, KeyID)
|
||||
|
||||
KeyIDUnlocked = False$ ; // Assume false for now.
|
||||
|
||||
Convert @Lower_Case to @Upper_Case in TableName
|
||||
|
||||
If (TableName NE '') AND (KeyID NE '') then
|
||||
// First, do a sanity check to confirm that there is a lock on this Key ID.
|
||||
IsKeyIDLocked = Database_Services('IsKeyIDLocked', TableName, KeyID, False$)
|
||||
If Error_Services('NoError') AND (IsKeyIDLocked EQ False$) then
|
||||
// Key ID was not locked.
|
||||
KeyIDUnlocked = True$
|
||||
end
|
||||
If KeyIDUnlocked NE True$ then
|
||||
// Key ID is still presumed to be locked.
|
||||
VolumePath = ''
|
||||
FileName = ''
|
||||
|
||||
// Resolve the volume path for this table.
|
||||
hTableFull = Database_Services('ReadDataRow', 'SYSTABLES', TableName)
|
||||
VolumeName = hTableFull<1>
|
||||
VolumeRow = Database_Services('ReadDataRow', 'SYSVOLUMES', VolumeName)
|
||||
VolumePath = VolumeRow[-1, 'B' : @FM]
|
||||
VolumePath = VolumePath[-1, 'B' : \0D\]
|
||||
VolumePath[1, 12] = '' ; // Strip off the preceding bytes.
|
||||
If SRP_Path('IsRelative', VolumePath) then
|
||||
VolumePath = SRP_Path('Combine', Drive(), VolumePath)
|
||||
// Check for only a single '\' character. Add another if necessary so this is a proper UNC path.
|
||||
// This is a workaround for this version of SRP_Path.
|
||||
If VolumePath[1, 1] EQ '\' AND VolumePath[2, 1] NE '\' then VolumePath = '\' : VolumePath
|
||||
end
|
||||
VolumePath = SRP_Path('RemoveFilename', VolumePath)
|
||||
// Make sure there is a backslash since the RTI_LH_INFO API seems to use this.
|
||||
VolumePath = SRP_Path('AddBackslash', VolumePath)
|
||||
|
||||
// Resolve the filename for this table.
|
||||
hTableFull = Database_Services('ReadDataRow', 'SYSTABLES', TableName)
|
||||
FileName = hTableFull[-1, 'B' : @FM]
|
||||
FileName = FileName[-1, 'B' : \0D\]
|
||||
FileName = FileName[1, @VM]
|
||||
If FileName _NEC 'SYSREPOS' then FileName[1, 12] = '' ; // Strip off the preceding bytes.
|
||||
FileName = FileName[-1, 'B' : '\']
|
||||
// Make sure the filename is well formed.
|
||||
Begin Case
|
||||
Case (FileName[-3, 3] _EQC '.LK') OR (FileName[-3, 3] _EQC '.OV')
|
||||
FileName[-3, 3] = ''
|
||||
Case FileName _EQC 'SYSREPOS'
|
||||
FileName = 'REVREPOS'
|
||||
End Case
|
||||
|
||||
If (VolumePath NE '') AND (FileName) NE '' then
|
||||
// Attempt to unlocked the Key ID.
|
||||
RTI_LH_Info(CMD_UNLOCK$, VolumePath, FileName, KeyID, FileName)
|
||||
// Confirm that the Key ID was unlocked.
|
||||
IsKeyIDLocked = Database_Services('IsKeyIDLocked', TableName, KeyID, False$)
|
||||
If Error_Services('NoError') AND (IsKeyIDLocked EQ False$) then
|
||||
// Key ID was not locked.
|
||||
KeyIDUnlocked = True$
|
||||
end else
|
||||
// Unable to unlock the Key ID which could be because it is locked by this station. Try using the
|
||||
// Unlock statement.
|
||||
KeyIDUnlocked = Database_Services('ReleaseKeyIDLock', TableName, KeyID)
|
||||
end
|
||||
end else
|
||||
Error_Services('Add', 'No valid VolumePath or FileName was available in the ' : Service : ' service.')
|
||||
end
|
||||
end
|
||||
end else
|
||||
Error_Services('Add', 'TableName or KeyID argument was missing in the ' : Service : ' service.')
|
||||
end
|
||||
|
||||
Response = KeyIDUnlocked
|
||||
|
||||
end service
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Internal GoSubs
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
Reference in New Issue
Block a user