Created
November 12, 2016 13:32
-
-
Save suriyasv/2ed7f2dbcfd8c79f3b9938762c17c0b5 to your computer and use it in GitHub Desktop.
Ensemble Orphaned Messages Purge Routine
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
<?xml version="1.0" encoding="UTF-8"?> | |
<Export generator="Cache" version="25" zv="Cache for Windows (x86-64) 2013.1.4 (Build 801U)" ts="2014-05-12 13:24:27"> | |
<Class name="zEnsSupport.Msgs"> | |
<IncludeCode>Ensemble,EnsHL7</IncludeCode> | |
<Super>%RegisteredObject</Super> | |
<TimeChanged>63319,48173.215985</TimeChanged> | |
<TimeCreated>62962,32987.669526</TimeCreated> | |
<UDLText name="T"> | |
<Content><![CDATA[ | |
/* | |
Changes: | |
05/12/2014 RCK - Removed 'Hidden' from the class definition. | |
*/ | |
]]></Content> | |
</UDLText> | |
<UDLText name="T"> | |
<Content><![CDATA[ | |
/* | |
tMsgBodies(MessageBodyClassName) = $List | |
1 - Min(MessageBodyId) from Ens.MessageHeader | |
2 - TimeCreated for MessageBodyClassName Min(MessageBodyId) | |
3 - Table corresponding to MessageBodyClassName (i.e. EnsLib.HL7.Message = EnsLib_HL7.Message) | |
4 - Count(ID) from SQL Table (#3) | |
5 - Min(ID) from SQL Table (#3) | |
6 - Known global storage locations for instances of MessageBodyClassName - $ListBuild(DataLocation,IndexLocation,SreamLocation,...) | |
7 - Total size of globals (#6) before running DeleteMsgBodiesUpToId() | |
8 - Number of deleted messages (populated by DeleteMsgBodiesUpToId()) | |
9 - Total size of globals (#6) after running DeleteMsgBodiesUpToId() | |
10 - Super (Extends ...) from SQL Table (#3) | |
*/ | |
]]></Content> | |
</UDLText> | |
<Method name="Menu"> | |
<Description> | |
D ##class(zEnsSupport.Msgs).Menu()</Description> | |
<ClassMethod>1</ClassMethod> | |
<Implementation><![CDATA[ | |
Do { | |
Set tSC=$$$OK | |
Kill ary,cnt | |
Write #,!,"zEnsSupport.Msgs Menu:" | |
Write !,"================================================================================",! | |
Write !,"PURGE CLEANUP/MESSAGE REPORT OPTIONS" | |
Write !," 1. Run Complete Ensemble Message Body Report" | |
Write !," 2. Run Ensemble Message Body Report w/o Global Info" | |
Write !," 3. Delete ALL MessageBodies < Min(MessageBodyId) in Ens.MessageHeader" | |
Write !," 4. Delete ONLY EnsLib.HL7.Messages < Min(MessageBodyId) in Ens.MessageHeader" | |
Write !," 5. Delete ONLY Ens.Response messages < Min(MessageBodyId) in Ens.MessageHeader" | |
Write !," 6. Show Summary Count of MessageBodies < Min(MessageBodyId)" | |
Write !," 7. Show Summary Count of EnsLib.HL7.Messages < Min(MessageBodyId)" | |
Write !," 8. Show Summary Count of Ens.Responses < Min(MessageBodyId)" | |
Write !," 9. Gather HL7 related Global information" | |
Write !,"10. Quick Check for Orphaned Message Bodies (Top 1 Not Min, No Counts)" | |
Write !,"11. Find HL7 Segment Mismatches" | |
Write !,"12. Fix HL7 Segment Mismatches" | |
//Write !!,"MISC OPTIONS" | |
//Write !,"90. CleanProduction" | |
//Write !,"91. SQL Shell" | |
Read !!,"Selection: ",x | |
Write ! | |
If x=1 { Set tSC=..MessageBodyReport(.ary,1) } | |
ElseIf x=2 { Set tSC=..MessageBodyReport(.ary,1,0) } | |
ElseIf x=3 { Set tSC=..DeleteMsgBodiesUpToId(.ary,1,0) } | |
ElseIf x=4 { Set tSC=..DeleteHL7MsgsNotRefByMsgHeader(.cnt,1) } | |
ElseIf x=5 { Set tSC=..DeleteEnsResponseNotRefByMsgHeader(.cnt,1) } | |
ElseIf x=6 { Set tSC=..DeleteMsgBodiesUpToId(.ary,1,0,1,0) } | |
ElseIf x=7 { Set tSC=..DeleteHL7MsgsNotRefByMsgHeader(.cnt,1,0) } | |
ElseIf x=8 { Set tSC=..DeleteEnsResponseNotRefByMsgHeader(.cnt,1,0) } | |
ElseIf x=9 { Set tSC=..BasicHL7GlobalInfo() } | |
ElseIf x=10 { Set tSC=..QuickMessageBodyReport(.ary,1) } | |
ElseIf x=11 { Set tSC=..FindHL7SegMismatch(1,0) } | |
ElseIf x=12 { Set tSC=..FindHL7SegMismatch(1,1)} | |
ElseIf x=90 { | |
Read "CleanProduction? <No> ",tYN | |
If ..YES(tYN) { | |
Write !,"Running CleanProduction!",! | |
Set tSC=##class(Ens.Director).CleanProduction(1) | |
} | |
} | |
ElseIf x=91 { Do $System.SQL.Shell() } | |
ElseIf '..QUIT(x) { Write !,"Invalid Option!",! } | |
//Some functions will return known errors (i.e. storage defined but not yet used = Global not found) | |
If ('tSC) Do $System.OBJ.DisplayError(tSC) Write ! | |
} While ('..QUIT(x)) | |
Quit | |
]]></Implementation> | |
</Method> | |
<Method name="MessageBodyReport"> | |
<Description><![CDATA[ | |
Complete analysis of the Ens.MessageHeader table. Finds each unique MessageBodyClassName in the Ens.MessageHeader table, | |
the number of references to each class (Hdr Count), number of unique MessageBodyIds for each MessageBodyClassName (Unq Count), and | |
minimum Id for each MessageBodyClassName in the Ens.MessageHeader table. Also looks at the SQL table for each MessageBodyClassName | |
and finds the Count() and Min(Id). <br><br> | |
It can be generally assumed that the Min Id from the Ens.MessageHeader table for each MessageBodyClassName should equal the Min Id | |
from the MessageBodyClassName table. This can depend on how classes are extended and if %Persistent data is being kept for other purposes.<br><br> | |
This method Outputs a pMsgBodies array which can be used to call DeleteMsgBodiesUpToId(). It will take considerably longer to run if | |
the option to pCheckGlobalSizes is true. <br><br> | |
pMsgBodies(MessageBodyClassName) = $List<br> | |
1 - Min(MessageBodyId) from Ens.MessageHeader<br> | |
2 - TimeCreated for MessageBodyClassName Min(MessageBodyId) from Ens.MessageHeader<br> | |
3 - Table corresponding to MessageBodyClassName (i.e. EnsLib.HL7.Message = EnsLib_HL7.Message)<br> | |
4 - Count(ID) from SQL Table (#3)<br> | |
5 - Min(ID) from SQL Table (#3)<br> | |
6 - Known global storage locations for instances of MessageBodyClassName - $ListBuild(DataLocation,IndexLocation,SreamLocation,...)<br> | |
7 - Total size of globals (#6) before running DeleteMsgBodiesUpToId()<br>]]></Description> | |
<ClassMethod>1</ClassMethod> | |
<FormalSpec>*pMsgBodies,pVerbose:%Boolean=0,pCheckGlobalSizes:%Boolean=1</FormalSpec> | |
<ReturnType>%Status</ReturnType> | |
<Implementation><![CDATA[ | |
Set tSC=$$$OK,tTotalHdrCount=0,tTotalHdrUnique=0,tTotalTblCount=0 | |
&SQL(DECLARE cur3 CURSOR FOR | |
SELECT %Exact(MessageBodyClassName), COUNT(ID), COUNT(DISTINCT MessageBodyId), MIN(MessageBodyId), TimeCreated | |
INTO :tMsgBody,:tHdrCount,:tUniqueMsgBodies,:tMinMessageBodyId,:tTimeCreated | |
FROM Ens.MessageHeader | |
GROUP BY MessageBodyClassName) | |
&SQL(OPEN cur3) | |
Write:pVerbose !,?25,"Message Header",?62,"SQL Table" | |
Write:pVerbose !,?12,"========================================",?54,"==========================" | |
Write:pVerbose !,"Class Name",?12," Hdr Count",?26," Unq Count",?40," Min Id",?54," Count",?68," Min Id" | |
Write:pVerbose !,"==========",?12,"============",?26,"============",?40,"============",?54,"============",?68,"============" | |
For { | |
&SQL(FETCH cur3) | |
Quit:(SQLCODE'=0) | |
If tMsgBody="" { | |
Set tTotalHdrCount = tTotalHdrCount + tHdrCount | |
Write:pVerbose !,"No Message Body" | |
Write:pVerbose !?12,##class(Ens.Util.FunctionSet).Pad($FN(tHdrCount,","),-12),! | |
Continue | |
} | |
Set $List(pMsgBodies(tMsgBody),1,2)=$ListBuild(tMinMessageBodyId,tTimeCreated) | |
Write:pVerbose !,tMsgBody | |
Set tSC1 = ..GetSQLTableName(tMsgBody,.tSQLTableName,.tSuperClass) | |
If 'tSC1 { | |
Set tSC = $$$ADDSC(tSC,tSC1) | |
Continue | |
} | |
Set $List(pMsgBodies(tMsgBody),3)=tSQLTableName | |
Set $List(pMsgBodies(tMsgBody),10)=tSuperClass | |
//If it Extends %Persistent first, don't bother showing all the other classes - it will have its own storage | |
Write:pVerbose !,?3,"Extends: ",$S($P(tSuperClass,",")="%Library.Persistent":"%Library.Persistent",1:tSuperClass) | |
Write:pVerbose !,?3,"SQL Table Name: ",tSQLTableName | |
Write:pVerbose !,?12,##class(Ens.Util.FunctionSet).Pad($FN(tHdrCount,","),-12) | |
Write:pVerbose ?26,##class(Ens.Util.FunctionSet).Pad($FN(tUniqueMsgBodies,","),-12) | |
Write:pVerbose ?40,##class(Ens.Util.FunctionSet).Pad(tMinMessageBodyId,-12) | |
Set tSC1 = ..GetCountMinIdMaxIdFromSQLTable(tSQLTableName,.tTblCount,.tMinTblId) | |
If 'tSC1 { | |
Set tSC = $$$ADDSC(tSC,tSC1) | |
Continue | |
} | |
Set $List(pMsgBodies(tMsgBody),4)=tTblCount | |
Set $List(pMsgBodies(tMsgBody),5)=tMinTblId | |
Set tTotalHdrCount = tTotalHdrCount + tHdrCount | |
Set tTotalHdrUnique = tTotalHdrUnique + tUniqueMsgBodies | |
Set tTotalTblCount = tTotalTblCount + tTblCount | |
Write:pVerbose ?54,##class(Ens.Util.FunctionSet).Pad($FN(tTblCount,","),-12) | |
Write:pVerbose ?68,##class(Ens.Util.FunctionSet).Pad(tMinTblId,-12),! | |
} | |
Write:pVerbose !?12,"============",?26,"============",?54,"============" | |
Write:pVerbose !,"TOTALS",?12,##class(Ens.Util.FunctionSet).Pad($FN(tTotalHdrCount,","),-12),?26,##class(Ens.Util.FunctionSet).Pad($FN(tTotalHdrUnique,","),-12),?54,##class(Ens.Util.FunctionSet).Pad($FN(tTotalTblCount,","),-12),! | |
&SQL(CLOSE cur3) | |
Set tMsgBody="" | |
For { | |
Set tMsgBody = $Order(pMsgBodies(tMsgBody)) Quit:tMsgBody="" | |
Set tSC1 = ..GetGlobalsByClassName(.tMsgBody,.tListOfGlobals) | |
If 'tSC1 Set tSC = $$$ADDSC(tSC,tSC1) | |
Set $LIST(pMsgBodies(tMsgBody),6)=tListOfGlobals | |
If pCheckGlobalSizes { | |
Set tSC1 = ..GetTotalGlobalSizes(tListOfGlobals,.tTotal,,pVerbose,tMsgBody,$ListGet(pMsgBodies(tMsgBody),4)) | |
If 'tSC1 Set tSC = $$$ADDSC(tSC,tSC1) //Some Globals may not be found resulting in an ERROR | |
Set $LIST(pMsgBodies(tMsgBody),7)=tTotal | |
} | |
} | |
Quit tSC | |
]]></Implementation> | |
</Method> | |
<Method name="DeleteMsgBodiesUpToId"> | |
<Description><![CDATA[ | |
If pMsgBodies is empty, deletes persistent objects (MessageBodyClassName) found in Ens.MessageHeader with an Id (MessageBodyId) less than the minimum MessageBodyId stored in the Ens.MessageHeader table. | |
Otherwise, this method will delete objects less than the Id specified: pMsgBodies(ClassName)=$ListBuild(StopAtId). | |
Orphaned message bodies arise mostly due to purging without including Message Bodies. | |
To be asked whether to turn journaling off, do not pass a value for pNoJrn and set pVerbose=1.<br><br> | |
If $D(pMsgBodies)<10 MessageBodyReport() is called to build array | |
<br><br>Do ##(zEnsSupport.Msgs).DeleteMsgBodiesUpToId(.tMsgBodies,1)]]></Description> | |
<ClassMethod>1</ClassMethod> | |
<FormalSpec>*pMsgBodies,pVerbose:%Boolean=0,pShowDetail:%Boolean=0,pNoJrn:%Boolean,pDelete:%Boolean=1,pCheckGlobalSizes:%Boolean=1</FormalSpec> | |
<ReturnType>%Status</ReturnType> | |
<Implementation><![CDATA[ | |
Set tSC=$$$OK | |
If ($Data(pMsgBodies)<10) { | |
Write:pVerbose !,"Gathering data..." | |
Set tSC1 = ..MessageBodyReport(.pMsgBodies,0,0) | |
//Expect errors because some Globals are defined but not yet used | |
//ERROR #308: Global EnsLib.H.MessageS not found. | |
//If 'tSC1 Set tSC = $$$ADDSC(tSC,tSC1) Quit tSC | |
} | |
If pDelete { | |
Set tJournalingWasOn = $$CURRENT^%NOJRN() | |
Set pNoJrn=$G(pNoJrn) | |
If pVerbose { | |
Write ! | |
Set tMsgBody="" | |
For { | |
Set tMsgBody = $Order(pMsgBodies(tMsgBody)) Quit:tMsgBody="" | |
Set tStopAtId = +$ListGet(pMsgBodies(tMsgBody),1) Continue:'tStopAtId | |
Write !,"Delete all ",tMsgBody," where Id < ",tStopAtId | |
} | |
Read !,"Delete message bodies? <No> ",tYN | |
Quit:'..YES(tYN) $$$ERROR(5001,"Delete then No Delete - Nothing Deleted!") | |
Read:(pNoJrn="") !,"Turn off Journaling? <No> ",tYN //Vague, must ask specifically Yes/No | |
Set:..YES(tYN) pNoJrn=1 | |
} | |
If pNoJrn { | |
Do DISABLE^%NOJRN | |
} | |
Else { | |
Do ENABLE^%NOJRN | |
} | |
} | |
Set tMsgBody="",tTotalCount=0,tGrandTotalIn=0,tGrandTotalOut=0 | |
For { | |
Set tMsgBody = $Order(pMsgBodies(tMsgBody)) Quit:tMsgBody="" | |
Set tStopAtId = +$ListGet(pMsgBodies(tMsgBody),1) Continue:'tStopAtId | |
Set tSC1 = ..GetSQLTableName(tMsgBody,.tSQLName) | |
If 'tSC1 { | |
Do:pVerbose $System.OBJ.DisplayError(tSC1) | |
Set tSC = $$$ADDSC(tSC,tSC1) | |
Continue | |
} | |
Set tSQL = "SELECT ID FROM "_tSQLName_" WHERE ID < "_tStopAtId | |
Set tStatement = ##class(%SQL.Statement).%New() | |
Set tSC1 = tStatement.%Prepare(tSQL) | |
If 'tSC1 { | |
Do:pVerbose $System.OBJ.DisplayError(tSC1) | |
Set tSC = $$$ADDSC(tSC,tSC1) | |
Continue | |
} | |
Set tRS = tStatement.%Execute() | |
Set (tCount,tUsedIn,tAlloc)=0 | |
//Set the size of the Globals before deleting | |
If pCheckGlobalSizes&&pDelete { | |
Set tTotalIn=0 | |
Set tListOfGlobals = $ListGet(pMsgBodies(tMsgBody),6) | |
If tListOfGlobals="" { | |
Set tSC1 = ..GetGlobalsByClassName(.tMsgBody,.tListOfGlobals) | |
If 'tSC1 { | |
Do:pVerbose $System.OBJ.DisplayError(tSC1) | |
Set tSC = $$$ADDSC(tSC,tSC1) | |
Continue | |
} | |
Else { | |
Set $List(pMsgBodies(tMsgBody),6)=tListOfGlobals | |
} | |
} | |
Set tSC1 = ..GetTotalGlobalSizes(tListOfGlobals,.tTotalIn) | |
If tSC1 { | |
Set $LIST(pMsgBodies(tMsgBody),7) = tTotalIn | |
Set tGrandTotalIn = tGrandTotalIn + tTotalIn | |
} | |
Else { | |
//Expect errors because some Globals are defined but not yet used | |
//ERROR #308: Global EnsLib.H.MessageS not found. | |
//Set tSC = $$$ADDSC(tSC,tSC1) Quit tSC | |
} | |
} | |
While (tRS.%Next()) { | |
Set tSC1=$$$OK | |
Set:pDelete tSC1=$CLASSMETHOD(tMsgBody,"%DeleteId",tRS.ID) | |
If tSC1 { | |
Set tCount = tCount + 1 | |
If pVerbose&&pShowDetail { | |
Write !?2 | |
Write:'pDelete "Found " | |
Write:pDelete "Deleted " | |
Write tMsgBody," with ID ",tRS.ID | |
} | |
} Else { | |
Do:pVerbose $System.OBJ.DisplayError(tSC1) | |
Set tSC = $$$ADDSC(tSC,tSC1) | |
} | |
} | |
Set $List(pMsgBodies(tMsgBody),8)=tCount | |
Set tTotalCount = tTotalCount + tCount | |
//Check the size of the Global after deleting | |
If pCheckGlobalSizes&&pDelete { | |
Set tTotalOut=0 | |
Set tSC1 = ..GetTotalGlobalSizes(tListOfGlobals,.tTotalOut) | |
If tSC1 { | |
Set $LIST(pMsgBodies(tMsgBody),9) = tTotalOut | |
Set tGrandTotalOut = tGrandTotalOut + tTotalOut | |
} | |
Else { | |
Do:pVerbose $System.OBJ.DisplayError(tSC1) | |
Set tSC = $$$ADDSC(tSC,tSC1) | |
} | |
} | |
If pVerbose { | |
Write ! | |
Write:'pDelete "Found " | |
Write:pDelete "Deleted " | |
Write tCount," msg bodies of type ",tMsgBody | |
Write:pDelete&&pCheckGlobalSizes " (",tTotalIn-tTotalOut," MB)" | |
} | |
} | |
If pVerbose { | |
Write !! | |
Write:'pDelete "Found " | |
Write:pDelete "Deleted " | |
Write tTotalCount," TOTAL Message Bodies" | |
Write:pDelete&&pCheckGlobalSizes " (",tGrandTotalIn-tGrandTotalOut," MB)" | |
Write ! | |
} | |
If pDelete Do:tJournalingWasOn ENABLE^%NOJRN | |
Quit tSC | |
]]></Implementation> | |
</Method> | |
<Method name="DeleteHL7MsgsNotRefByMsgHeader"> | |
<Description> | |
Deletes all EnsLib.HL7.Messages with an Id less than the minimum MessageBodyId stored in the Ens.MessageHeader table. | |
This situation arises mostly due to purging without including Message Bodies. </Description> | |
<ClassMethod>1</ClassMethod> | |
<FormalSpec>*pCount,pVerbose:%Boolean=0,pDelete:%Boolean=1,*pMsgBodies,pCheckGlobalSizes:%Boolean=1</FormalSpec> | |
<ReturnType>%Status</ReturnType> | |
<Implementation><![CDATA[ | |
Set tSC=$$$OK,pCount=0 | |
&SQL(SELECT MIN(MessageBodyId), TimeCreated INTO :tMsgId, :tTimeCreated | |
FROM Ens.MessageHeader | |
WHERE MessageBodyClassName ='EnsLib.HL7.Message') | |
Quit:(SQLCODE'=0) $$$ERROR(5001,"SQLCODE: "_SQLCODE) | |
Set $List(pMsgBodies("EnsLib.HL7.Message"),1,2)=$ListBuild(tMsgId,tTimeCreated) | |
Set tSC = ..DeleteMsgBodiesUpToId(.pMsgBodies,pVerbose,0,,pDelete,pCheckGlobalSizes) | |
Set pCount = +$ListGet(pMsgBodies("EnsLib.HL7.Message"),8) | |
Quit tSC | |
]]></Implementation> | |
</Method> | |
<Method name="DeleteEnsResponseNotRefByMsgHeader"> | |
<Description> | |
Deletes all Ens.Response messages with an Id less than the minimum MessageBodyId stored in the Ens.MessageHeader table. | |
Orphaned Ens.Response messages can happen for many reasons, but oftentimes happens when a BPL is configured with Ens.Response | |
as the response (default) but called Async. </Description> | |
<ClassMethod>1</ClassMethod> | |
<FormalSpec>*pCount,pVerbose:%Boolean=0,pDelete:%Boolean=1,*pMsgBodies,pCheckGlobalSizes:%Boolean=1</FormalSpec> | |
<ReturnType>%Status</ReturnType> | |
<Implementation><![CDATA[ | |
Set tSC=$$$OK, pCount=0 | |
&SQL(SELECT MIN(MessageBodyId), TimeCreated INTO :tMsgId, :tTimeCreated | |
FROM Ens.MessageHeader | |
WHERE MessageBodyClassName ='Ens.Response') | |
Quit:(SQLCODE'=0) $$$ERROR(5001,"SQLCODE: "_SQLCODE_" returned trying to SELECT from Ens.Response") | |
Set $List(tMsgBodies("Ens.Response"),1,2)=$ListBuild(tMsgId,tTimeCreated) | |
Set tSC = ..DeleteMsgBodiesUpToId(.tMsgBodies,pVerbose,0,,pDelete,pCheckGlobalSizes) | |
Set pCount = +$ListGet(tMsgBodies("Ens.Response"),8) | |
Quit tSC | |
]]></Implementation> | |
</Method> | |
<Method name="BasicHL7GlobalInfo"> | |
<Description> | |
HL7 related Globals and their size in MB</Description> | |
<ClassMethod>1</ClassMethod> | |
<ReturnType>%Status</ReturnType> | |
<Implementation><![CDATA[ | |
Set tSC=$$$OK | |
&SQL(SELECT COUNT(ID) INTO :tCount | |
FROM EnsLib_HL7.Message) | |
Quit:(SQLCODE'=0) $$$ERROR(5001,"SQLCODE: "_SQLCODE_" returned trying to find COUNT() of HL7 Messages.") | |
Set tGlobalList = $ListFromString("^Ens.MessageHeaderD,^Ens.MessageHeaderI,^Ens.Rule.LogD,^EnsHL7.Segment,^EnsLib.H.MessageD,^EnsLib.H.MessageI,^EnsLib.H.MessageS,^EnsLib.HL7.SearchTableD,^EnsLib.HL7.SearchTableI",",") | |
Set tSC=..GetTotalGlobalSizes(tGlobalList,,,1,"HL7 Related Globals",tCount) | |
Write !,$FN(tCount,",")," Unique HL7 Messages",! | |
Quit tSC | |
]]></Implementation> | |
</Method> | |
<Method name="GetSQLTableName"> | |
<ClassMethod>1</ClassMethod> | |
<FormalSpec>pClassName:%String="",*pTableName:%String,*pSuper:%String</FormalSpec> | |
<ReturnType>%Status</ReturnType> | |
<Implementation><![CDATA[ | |
Set tSC = $$$OK | |
If pClassName'="" { | |
&SQL(SELECT SqlQualifiedNameQ, Super INTO :pTableName, :pSuper | |
FROM %Dictionary.CompiledClass | |
WHERE ID = :pClassName) | |
Set:SQLCODE'=0 tSC = $$$ERROR(5001,"SQLCODE: "_SQLCODE_" returned querying %Dictionary.CompiledClass for "_tMsgBody) | |
} | |
Else { | |
Set tSC = $$$ERROR(5001,"ClassName NULL calling GetSQLTableName") | |
} | |
Quit tSC | |
]]></Implementation> | |
</Method> | |
<Method name="GetCountMinIdMaxIdFromSQLTable"> | |
<ClassMethod>1</ClassMethod> | |
<FormalSpec>pSQLTable:%String="",*pCount:%Integer="",*pMinId="",*pMaxId</FormalSpec> | |
<ReturnType>%Status</ReturnType> | |
<Implementation><![CDATA[ | |
Set tSC = $$$OK, pCount=0 | |
If pSQLTable'="" { | |
Set tSQL = "SELECT COUNT(ID) AS MsgCount, MIN(ID) AS MinId, MAX(ID) AS MaxId FROM "_pSQLTable | |
Set tStatement = ##class(%SQL.Statement).%New() | |
Set tSC = tStatement.%Prepare(tSQL) | |
Quit:'tSC tSC | |
Set tRS = tStatement.%Execute() | |
If tRS.%Next() { | |
Set pCount = tRS.MsgCount | |
Set pMinId = tRS.MinId | |
Set pMaxId = tRS.MaxId | |
} | |
} | |
Else { | |
Set tSC = $$$ERROR(5001,"pSQLTable NULL calling GetCountMinIdMaxIdFromSQLTable") | |
} | |
Quit tSC | |
]]></Implementation> | |
</Method> | |
<Method name="GetGlobalsByClassName"> | |
<ClassMethod>1</ClassMethod> | |
<FormalSpec>pClassName:%String="",*pListOfGlobals</FormalSpec> | |
<ReturnType>%Status</ReturnType> | |
<Implementation><![CDATA[ | |
Set tSC=$$$OK | |
If pClassName = "" Quit $$$ERROR(5001,"Invalid ClassName passed to GetGlobalsByClassName") | |
&SQL(SELECT DataLocation,IndexLocation,StreamLocation | |
INTO :tDataLocation,:tIndexLocation,:tStreamLocation | |
FROM %Dictionary.CompiledStorage | |
WHERE Parent = :pClassName) | |
Quit:SQLCODE'=0 $$$ERROR(5001,"SQLCODE: "_SQLCODE_" returned querying %Dictionary.CompiledStorage for "_pClassName) | |
Set pListOfGlobals="" | |
For tI = tDataLocation,tIndexLocation,tStreamLocation Set:tI'="" $List(pListOfGlobals,$ListLength(pListOfGlobals)+1)=tI | |
//Special consideration for certain well-known message bodies | |
If pClassName = "EnsLib.HL7.Message" { | |
For tI="^EnsHL7.Segment","^EnsLib.HL7.SearchTableD","^EnsLib.HL7.SearchTableI" Set:tI'="" $List(pListOfGlobals,$ListLength(pListOfGlobals)+1)=tI | |
} | |
Quit tSC | |
]]></Implementation> | |
</Method> | |
<Method name="GetTotalGlobalSizes"> | |
<ClassMethod>1</ClassMethod> | |
<FormalSpec>pListOfGlobals,*pTotalUsed,*pTotalAlloc,pVerbose:%Boolean=0,pHeader:%String="Global",pMsgCount:%Integer=""</FormalSpec> | |
<ReturnType>%Status</ReturnType> | |
<Implementation><![CDATA[ | |
Set tSC=$$$OK, (pTotalUsed,pTotalAlloc)=0 | |
Write:pVerbose !,$E(pHeader,1,50),?52," Used Storage",?67,"Alloc Storage" | |
Write:pVerbose !,"==================================================",?52,"=============",?67,"=============" | |
For tI=1:1:$ListLength(pListOfGlobals) { | |
Set (tUsed,tAlloc)=0 | |
Set tGlobal = $ListGet(pListOfGlobals,tI) | |
If tGlobal'="" { | |
Set tSC1 = ##class(%GlobalEdit).GetGlobalSize($zu(12,""),tGlobal,.tAlloc,.tUsed) | |
If tSC1 { | |
Set pTotalUsed = pTotalUsed + tUsed | |
Set pTotalAlloc = pTotalAlloc + tAlloc | |
Write:pVerbose !,tGlobal | |
Write:+pMsgCount&&pVerbose " (",$FN((tUsed/pMsgCount)*100000,",",1)," per 100K)" | |
Write:pVerbose ?52,##class(Ens.Util.FunctionSet).Pad($FN(tUsed,",",1),-13) | |
Write:pVerbose ?67,##class(Ens.Util.FunctionSet).Pad($FN(tAlloc,",",1),-13) | |
} | |
Else { | |
//Set tSC=$$$ADDSC(tSC,tSC1) | |
//Very common to have globals defined that are not yet used. | |
} | |
} | |
} | |
Write:pVerbose !," TOTAL: " | |
Write:pVerbose ?52,##class(Ens.Util.FunctionSet).Pad($FN(pTotalUsed,",",1),-13) | |
Write:pVerbose ?67,##class(Ens.Util.FunctionSet).Pad($FN(pTotalAlloc,",",1),-13),! | |
Quit tSC | |
]]></Implementation> | |
</Method> | |
<Method name="QuickCheckForMinIds"> | |
<ClassMethod>1</ClassMethod> | |
<FormalSpec>*pMsgBodies,pMsgBody:%String</FormalSpec> | |
<ReturnType>%Status</ReturnType> | |
<Implementation><![CDATA[ | |
Set tSC=$$$OK | |
&SQL(SELECT TOP 1 MessageBodyId, TimeCreated INTO :tMinMessageBodyId,:tTimeCreated FROM Ens.MessageHeader WHERE MessageBodyClassName = :pMsgBody) | |
Set tSC = ..GetSQLTableName(pMsgBody,.tSQLTableName,.tSuperClass) | |
Quit:'tSC tSC | |
Set $List(pMsgBodies(pMsgBody),1,3)=$ListBuild(tMinMessageBodyId,tTimeCreated,tSQLTableName) | |
Set $List(pMsgBodies(pMsgBody),10)=tSuperClass | |
Set tSQL = "SELECT Top 1 ID FROM "_tSQLTableName | |
Set tStatement = ##class(%SQL.Statement).%New() | |
Set tSC = tStatement.%Prepare(tSQL) | |
Quit:'tSC tSC | |
Set tRS = tStatement.%Execute() | |
If tRS.%Next() { | |
Set $LIST(pMsgBodies(pMsgBody),5)=tRS.ID //tMinTblId | |
} | |
Else { | |
Set tSC = $$$ERROR(5001,"Failed to find Top 1 ID in SQL Table "_tSQLTableName) | |
} | |
Quit tSC | |
]]></Implementation> | |
</Method> | |
<Method name="QuickMessageBodyReport"> | |
<ClassMethod>1</ClassMethod> | |
<FormalSpec>*pMsgBodies,pVerbose:%Boolean=0</FormalSpec> | |
<ReturnType>%Status</ReturnType> | |
<Implementation><![CDATA[ | |
Set tSC=$$$OK,tTotalHdrCount=0,tTotalHdrUnique=0,tTotalTblCount=0 | |
&SQL(DECLARE cur5 CURSOR FOR | |
SELECT %Exact(MessageBodyClassName) | |
INTO :tMsgBody | |
FROM Ens.MessageHeader | |
GROUP BY MessageBodyClassName) | |
&SQL(OPEN cur5) | |
Write:pVerbose !,"Class Name",?54," MinHdrBdyId",?68," MinMsgBdyId" | |
Write:pVerbose !,"====================================================",?54,"============",?68,"============" | |
For { | |
&SQL(FETCH cur5) | |
Quit:(SQLCODE'=0) | |
Continue:tMsgBody="" | |
Set tSC1 = ..QuickCheckForMinIds(.pMsgBodies,tMsgBody) | |
If 'tSC1 { | |
Set tSC = $$$ADDSC(tSC,tSC1) | |
Continue | |
} | |
Write:pVerbose !,tMsgBody | |
Write:pVerbose !,?3,"Extends: ",$S($P($ListGet(pMsgBodies(tMsgBody),10),",")="%Library.Persistent":"%Library.Persistent",1:$ListGet(pMsgBodies(tMsgBody),10)) | |
Write:pVerbose ?54,##class(Ens.Util.FunctionSet).Pad($ListGet(pMsgBodies(tMsgBody),1),-12),?68,##class(Ens.Util.FunctionSet).Pad($ListGet(pMsgBodies(tMsgBody),5),-12),! | |
} | |
&SQL(CLOSE cur5) | |
Quit tSC | |
]]></Implementation> | |
</Method> | |
<Method name="FindHL7SegMismatch"> | |
<ClassMethod>1</ClassMethod> | |
<FormalSpec>pVerbose:%Boolean=0,pFix:%Boolean=0</FormalSpec> | |
<ReturnType>%Status</ReturnType> | |
<Implementation><![CDATA[ | |
Set tSC=$$$OK | |
Set tId="" | |
If pFix { | |
Read !,"Fix HL7 Segment Mismatches? <No> ",tYN | |
Quit:'..YES(tYN) $$$ERROR(5001,"Selected option to Fix HL7 Segment Mismatches, but answered 'No' to confirm.") | |
} | |
For { Set tId=$O(^EnsLib.H.MessageD(tId)) Q:tId="" | |
Set segcount=+$G(^EnsLib.H.MessageD(tId,"segs")) | |
For tI=1:1:segcount { | |
Continue:$G(^EnsLib.H.MessageD(tId,"segs",tI))'="" | |
If 'pFix { | |
Write:pVerbose !,"Found mismatch at ^EnsLib.H.MessageD(",tId,")" | |
Quit | |
} | |
Set nextId = $O(^EnsLib.H.MessageD(tId,"segs",tI)) | |
If nextId'="" { | |
Write:pVerbose !,"Setting ^EnsLib.H.MessageD(",tId,",""segs"",",tI,")=^EnsLib.H.MessageD(",tId,",""segs"",",nextId,")" | |
Set ^EnsLib.H.MessageD(tId,"segs",tI)=^EnsLib.H.MessageD(tId,"segs",nextId) | |
Write:pVerbose !,"Killing ^EnsLib.H.MessageD(",tId,",""segs"",",nextId,")" | |
Kill ^EnsLib.H.MessageD(tId,"segs",nextId) | |
} | |
Else { | |
Write:pVerbose !,"Setting ^EnsLib.H.MessageD(",tId,",""segs"")=",tI-1 | |
Set ^EnsLib.H.MessageD(tId,"segs")=tI-1 | |
Quit | |
} | |
} | |
} | |
Quit tSC | |
]]></Implementation> | |
</Method> | |
<Method name="YES"> | |
<ClassMethod>1</ClassMethod> | |
<FormalSpec>pYN:%String=""</FormalSpec> | |
<ReturnType>%Boolean</ReturnType> | |
<Implementation><![CDATA[ Quit ("Y"=$E($TR($ZStrip(pYN,"<>W"),"y","Y"))) | |
]]></Implementation> | |
</Method> | |
<Method name="QUIT"> | |
<ClassMethod>1</ClassMethod> | |
<FormalSpec>pQuit:%String=""</FormalSpec> | |
<ReturnType>%Boolean</ReturnType> | |
<Implementation><![CDATA[ Quit ("QUIT"=$TR($ZStrip(pQuit,"<>W"),"quit","QUIT"))||("EXIT"=$TR($ZStrip(pQuit,"<>W"),"exit","EXIT"))||($ZStrip(pQuit,"<>W")="") | |
]]></Implementation> | |
</Method> | |
</Class> | |
</Export> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment